iOS 8 之 Widgets

尽管iOS 8还未正式发布,但其新增许多特性已经让广大开发人员兴奋不已。Extension是iOS 8开放出来的最重要的新功能之一,意味着苹果这个封闭的系统向开放性迈出了一大步。这篇文章主要介绍Extension中的Widget,考虑到准确性,很多地方直接采用了苹果官方描述,并未将其翻译成中文,请见谅。

说明:本文基于当前XCode最新版本:XCode 6 Beta3

1. Extension

Extensions(扩展/插件):Lets you extend custom functionality and content beyond your app and make it available to users while they’re using other apps. You create an extension to enable a specific task; after users get your extension, they can use it to perform that task in a variety of contexts.

Extension point(扩展点): iOS and OS X define several general types of extensions, each of which is tied to an area of the system, such as sharing, Notification Center, and the iOS keyboard. A system area that supports extensions is called an extension point.

Widgets:通知中心的今日栏目的Extension被称为Widgets

2. Extension类型

image
image
image

3. Extension提交和激活

Extension提交

Extension只能被捆绑在应用内,Extension只能随着其Containing app一起被安装。所以用户不可以单独下载 Extension,开发者也不能向App Store提交单独的Extension

Extension激活

不同类型的Extension,激活方式也不同

  • Today:在通知中心里进行激活或关闭;
  • Custom Keyboard:在设置的相应区域里进行设置;
  • Photo Editing和Storage Provider:只会在特定的情形下才会出现(比如你在使用照片应用时,或者你在选取文件时);
  • Share和Action:能够在任何应用里被唤起,但开发者必须为扩展添加激活原则(Activation Rules),使得Extension只有在用户执行特定操作(比如分享链接或文档)时才会出现。

4. Widgets

设计实现Widget时需要注意的一些事情,总结如下:

  • Ensure that content always looks up to date.
  • Respond appropriately to user interactions.
  • Perform well (widgets must use memory wisely or the system may terminate them)
  • A widget may also appear on the lock screen of an iOS device.
  • It’s a good idea to limit the number of interactive items in a widget.
  • iOS widgets don’t support keyboard entry.
  • Avoid putting a scroll view inside a widget.
  • If you want to create an extension that enables a multistep task or helps users perform a lengthy task, such as uploading or downloading content, the Today extension point is not the right choice.
  • Users need to be able to use the containing app to configure a widget’s content and behaviour.

5. Widget开发实现

5.1 使用Today Extension模版

首先,在XCode中选择Today Extension模版
image

一直点下一步直到结束,Today模版将自动生成下列默认文件

  • OC类:TodayViewController.h/.m
  • Plist文件:Info.plist
  • UI文件:一个storyboard或者xib文件

image

Info.plist文件内容:
image

开发人员也可以不使用storyboard,直接使用TodayViewController来生成UI,只需要将Plist文件中的NSExtensionMainStoryboard删除,添加NSExtensionPrincipalClass及属性值:

image

5.2 Widget UI相关方法

推荐使用 Auto Layout
调整边距: 使用 NCWidgetProviding 的widgetMarginInsetsForProposedMarginInsets:方法.
调整 widget 高度:

  • 使用 Auto Layout
  • 修改 UIViewController 的属性 preferredContentSize.-

动画函数:

  • viewWillTransitionToSize:withTransitionCoordinator:
  • animateAlongsideTransition:completion:
  • notificationCenterVibrancyEffect.

5.3 Widget内容更新

Today extension point 提供了 Notification Center Framework 用于管理widget的状态和更新其内容。

更新widget内容使用 NCWidgetProviding protocol的widgetPerformUpdateWithCompletionHandler:方法

- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
    // Perform any setup necessary in order to update the view.
    NSLog(@"widgetPerformUpdateWithCompletionHandler");
    // If an error is encoutered, use NCUpdateResultFailed
    // If there's no update required, use NCUpdateResultNoData
    // If there's an update, use NCUpdateResultNewData

    self.value.text = [NSString stringWithFormat:@"$%d", arc4random() % 100];
    completionHandler(NCUpdateResultNewData);
}

5.4 从Widget返回Containing app

    [self.extensionContext openURL:[NSURL URLWithString:[NSString stringWithFormat:@"widgetExample://%@", value]]
                 completionHandler:nil];

extensionContext是iOS 8为UIViewController新增的属性:

@interface UIViewController(NSExtensionAdditions) <NSExtensionRequestHandling>

// Returns the extension context. Also acts as a convenience method for a view controller to check if it participating in an extension request.
@property (nonatomic,readonly,retain) NSExtensionContext *extensionContext NS_AVAILABLE_IOS(8_0);

@end

5.5 指定Widget什么时候显示

使用 NCWidgetController API 指定Widget是否应该显示。Widget 和 containing app 均可调用setHasContent:forWidgetWithBundleIdentifier: 方法,以通知widget是否有内容需要显示

    NCWidgetController *controller = [NCWidgetController widgetController];
    [controller setHasContent:YES forWidgetWithBundleIdentifier:@"org.muhan.WidgetDemo.myWidget"];

6. Containing app 与 Host app

  • Containing app: 尽管苹果开放了extension,但是在iOS中extension并不能单独存在,要想提交到AppStore,必须将extension包含在一个app中提交,这个包含extension的app就叫containing app。一个containing app可以包含多个extension。

  • Host app:能够调起extension的app被称为host app,host app发出一个request,触发extension生命周期的开始,并且host app将定义extension后续操作的上下文,当extension完成host app的请求时,其生命周期结束。

  • Extension的生命周期
    image

7. Extension和Host App之间通信

Extension和host app之间可以通过extensionContext属性直接通信,该属性是新增加的UIViewController类别,见上面5.4。由于Widget的Host app是通知中心,一般情况下不需要关心这两者之间的数据传输。

8. Extension和Containing App之间数据共享

  • 尽管extension的bundle是放在containing app的bundle中,但是他们是两个完全独立的进程,两者不能直接通信

Screen_Shot_2014_07_08_at_2_59_28_PM

Screen_Shot_2014_07_08_at_2_59_34_PM

  • iOS 8新增App Groups实现containing app和extension之间的数据共享。此外,App Group还支持同一个开发团队开发的不同app之间的数据共享,见另一篇文档:iOS 8 之 App Group。 image

8. 参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值