[TOC]
1电谣、Tips
-
擴(kuò)展App想要使用主App中的代碼秽梅,需要在如下位置引入
調(diào)試主App則運(yùn)行主App;調(diào)試擴(kuò)展則運(yùn)行擴(kuò)展 (解決擴(kuò)展不走斷點(diǎn)的問題)
擴(kuò)展App想要使用的圖片資源等剿牺,需要引入到擴(kuò)展文件夾下
2西设、純代碼需要配置info.plist的倆項(xiàng)參數(shù)
移除
NSExtensionMainStoryboard
鍵厕吉,并添加NSExtensionPrincipalClass
鍵,使用view controller的名字作為值。
3循捺、UI樣式
- 背景:盡量不要使用背景份招,默認(rèn)的毛玻璃效果很好惶我,主要文字顏色最好是白色专挪,次要文字的顏色最好是
lightTextColor
- 不要在今日面板里使用可以滾動(dòng)的 Scroll View,而是要完全展開
- 縮進(jìn):盡量保持默認(rèn)的縮進(jìn)攒读,即左邊會(huì)空幾個(gè)像素誊抛。如果想改變默認(rèn)縮進(jìn),在TodayViewController里面實(shí)現(xiàn)以下方法
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets: (UIEdgeInsets)defaultMarginInsets {
return UIEdgeInsetsZero;
}
4整陌、與主App進(jìn)行交互
- Today跳轉(zhuǎn)App(喚起App拗窃,調(diào)用App某項(xiàng)功能)
[UIApplication sharedApplication]在擴(kuò)展App中是無法訪問的,需要通過NSExtensionContext來調(diào)用主App的openURL方法
//
[self.extensionContext openURL:[NSURL URLWithString:@"跳轉(zhuǎn)鏈接"] completionHandler:^(BOOL success) {
NSLog(@"open url result:%d",success);
}];
跳轉(zhuǎn)鏈接示例:iMyApp://
為跳轉(zhuǎn)頁面做標(biāo)識(shí)
- App 處理URL Schemes
// iOS 9+
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options {
// [url.absoluteString hasPrefix:@"iMyApp://"]
if ([url.host isEqualToString:@"iMyApp"]) {
// 操作
return YES;
}
return YES;
}
// iOS 7泌辫、iOS 8
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
// [url.absoluteString hasPrefix:@"iMyApp://"]
if ([url.host isEqualToString:@"iMyApp"]) {
// 操作
return YES;
}
return YES;
}
5随夸、與主App共享數(shù)據(jù)
- 利用group,將主App和擴(kuò)展App做一個(gè)數(shù)據(jù)共享空間(
NSUserDefault
)震放,先在主App的Targets中創(chuàng)建并設(shè)置宾毒,再在擴(kuò)展App的Targets設(shè)置(如圖)
- 主App存擴(kuò)展App所需要數(shù)據(jù)
NSUserDefaults* userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.iMyApp"];
[userDefault setBool:YES forKey:@"islogin"];
- 擴(kuò)展App取所需要數(shù)據(jù)
NSUserDefaults *myDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.iMyApp"];
BOOL isLogin = [myDefaults objectForKey:@"islogin"];
6、 - (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult result))completionHandler
方法說明
對(duì)于擴(kuò)展App殿遂,即使擴(kuò)展App現(xiàn)在不可見 (即用戶沒有拉開通知中心)诈铛,系統(tǒng)也會(huì)時(shí)不時(shí)地調(diào)用實(shí)現(xiàn)了 NCWidgetProviding 的擴(kuò)展的這個(gè)方法,來要求擴(kuò)展刷新界面墨礁。
這個(gè)機(jī)制和 iOS 7 引入的后臺(tái)機(jī)制是很相似的幢竹。在這個(gè)方法中我們一般可以做一些像 API 請(qǐng)求之類的事情,在獲取到了數(shù)據(jù)并更新了界面恩静,或者是失敗后都使用提供的 completionHandler 來向系統(tǒng)進(jìn)行報(bào)告
7焕毫、定時(shí)更新機(jī)制(通過增加定時(shí)更新的NSTimer)
把NSTimer fire觸發(fā)代碼調(diào)用放到
viewWillAppear
方法中來(viewDidLoad
方法并不是每次都執(zhí)行).同理當(dāng)Widget關(guān)閉后在viewDidDisappear
方法取消NSTimer invalidate定時(shí)更新即可。
8驶乾、關(guān)閉today widget中擴(kuò)展App的顯示
有時(shí)候在沒有數(shù)據(jù)的時(shí)候需要隱藏?cái)U(kuò)展邑飒,可以使用以下方法:
NCWidgetController *widgetController = [NCWidgetController widgetController];
[widgetController setHasContent:NO forWidgetWithBundleIdentifier:@"擴(kuò)展的id"];
9、iOS10 的適配- 展開级乐、折疊按鈕
在NSExtensionContext中疙咸,新添了
widgetLargestAvailableDisplayMode
屬性,來確認(rèn)當(dāng)前widget是展開還是折疊狀態(tài)风科。所以撒轮,先在viewWillAppear中設(shè)置widget的mode為展開乞旦。
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
展開和折疊狀態(tài)變化時(shí)的處理
-(void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);
// 處理~~
} else {
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300);
// 處理~~
}
}
- 如何用XCode 7.3打出能夠適配iOS 10的widget呢?
Xcode 7沒有iOS 10腔召,可以通過KVC來解決這個(gè)問題
[self.extensionContext setValue:@"1" forKey:@"widgetLargestAvailableDisplayMode"];
if (activeDisplayMode == 0) {
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 110);
} else {
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 300);
}
}
- 切記:UI的更新要在主線程操作
//通知主線程刷新
dispatch_async(dispatch_get_main_queue(), ^{
//...........;
});