概要
文章只是为了记录 iOS todayWidget 的实现流程。
实现
添加 TodayWidget
1, 添加一个 target,如下图(图中的 TodayWidget 是我已添加的组件)
2,选择 Today Extension
3,点击 Next,结果如下图。(刚生成时应该只有 ViewController 文件,其他的类都是我后期加上去的)
UI 效果实现
1,这里没什么细讲的,和 iOS 原生开发没什么区别,唯一注意的一点是,可以通过如下枚举控制 Widget 是否可以展开
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
2,实现两个代理,注释很明确,没什么可说的。
// If implemented, the system will call at opportune times for the widget to update its state, both when the Notification Center is visible as well as in the background.
// An implementation is required to enable background updates.
// It's expected that the widget will perform the work to update asynchronously and off the main thread as much as possible.
// Widgets should call the argument block when the work is complete, passing the appropriate 'NCUpdateResult'.
// Widgets should NOT block returning from 'viewWillAppear:' on the results of this operation.
// Instead, widgets should load cached state in 'viewWillAppear:' in order to match the state of the view from the last 'viewWillDisappear:', then transition smoothly to the new data when it arrives.
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult result))completionHandler;
// If implemented, called when the active display mode changes.
// The widget may wish to change its preferredContentSize to better accommodate the new display mode.
- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize __API_AVAILABLE(ios(10.0));
数据交互
-
数据交互的前提是设置 App Groups,具体设置步骤如下
- 点击如下红框按钮,弹出后选择 App Groups,然后点击App Groups 下面的“+”,输入名称。两个需要通讯的 targte 分别设置,例子中选中“Premium”和“TodayWidget”分别设置。记得勾选刚才设置的名称。
-
数据传递和事件传递
- 设置了App Groups 的两个 target 之间有两种通讯方式,各有利弊
-
通知的方式,
CFNotificationCenterPostNotification
,// 发送通知 - (void)postNotificaiton { CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyCenter(); CFNotificationCenterPostNotification(notification, CFSTR("com.your.name.to_app"), NULL,NULL, YES); } // 注册接收通知 - (void)receiveNotification { CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyCenter (); CFNotificationCenterAddObserver(notification, (__bridge const void *)(self), observerMethod,CFSTR("com.your.name.to_weiget"), NULL, CFNotificationSuspensionBehaviorDeliverImmediately); } void observerMethod (CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { NSNotification *notification = [[NSNotification alloc] initWithName:@"callBack" object:nil userInfo:nil]; [[NSNotificationCenter defaultCenter] postNotification:notification]; }
-
通过 NSUserDefaults 共享数据,存取类似,需要注意的是 NSUserDefaults 的实例化方法和确保 suiteName 两端保持一致
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.ingeek.widget"]; NSArray *array = [userDefaults objectForKey:@"group.com.ingeek.your.suiteName"];
-
- 通过通知的方式只能传递事件响应,无法传递和接收数据,NSUserDefaults 的方式只能共享数据,无法做到数据的及时响应,所以最好两种方式都一起使用。
- 设置了App Groups 的两个 target 之间有两种通讯方式,各有利弊
结束
都是调用官方的 Api,干货不多。这篇文章一来记录下自己的实现过程,二来抛砖引玉,主要是数据交互部分,可能有更好的方式,也希望看官不吝赐教。