概要
文章只是為了記錄 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,乾貨不多。這篇文章一來記錄下自己的實現過程,二來拋磚引玉,主要是資料互動部分,可能有更好的方式,也希望看官不吝賜教。