iOS8.0之后锹锰,蘋果支持了擴展(Extension)的開發(fā),開發(fā)者可以通過系統(tǒng)提供給我們的擴展接入點 (Extension point) 來為系統(tǒng)特定的服務提供某些附加的功能癣漆。當時Widget擴展應用不溫不火长赞,iOS10之后官方對Widget進行了大幅度的優(yōu)化,配合3Dtouch Widget逐漸火了起來态贤。本文簡單的介紹了Widget的使用。
本地大致按照以下四個步驟介紹widget
1.在宿主工程添加widget target
2.構建UI界面
3.喚醒宿主App
4.與宿主App共享數(shù)據(jù)
1.在宿主工程添加widget target
打開宿主工程醋火,F(xiàn)lie->New->Target->Today Extension->Next悠汽,如下圖箱吕。
這樣創(chuàng)建一個widget target
這個時候需要注意兩點
1.在當前的widget target基本配置里面將Deployment Target設置為你要兼容的iOS最低版本。
因為創(chuàng)建出來的時候柿冲,這里是默認是iOS最高版本茬高,如果不更改,你自己的手機iOS版本比Deployment Target低的話就會導致運行而不出現(xiàn)widget情況假抄。
2將你需要的圖片資源拖入當前的target內(nèi)
因為widget 與 宿主App是兩個不容的進程怎栽,資源是不能共享的,如果不推入widget會導致不能加載資源宿饱。當然你也可以創(chuàng)建一個xcassets再把圖片資源拖入熏瞄。
2.構建UI界面
系統(tǒng)默認是用storyboard的形式,如果你使用純代碼需要在當前target的info.plist首先將原有NSExtensionMainStoryboard字段刪除谬以,添加字段NSExtensionPrincipalClass强饮,value是你所寫的controller的名稱,一般默認的都是TodayViewController为黎,如下圖
如果使用SB那就忽略上面的操作邮丰。
iOS10以上支持widget的折疊與展開。
在初始化UI的時候加入下面的代碼铭乾,告訴系統(tǒng)你的widget是可折疊的樣式柠座。
if (@available(iOS 10.0, *)) {
self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
}
重寫切換展開及折疊布局時的方法,處理用戶點擊折疊與展開的操作片橡。
- (void) widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
NSLog(@"maxWidth %f maxHeight %f",maxSize.width,maxSize.height);
if (@available(iOS 10.0, *)) {
if (activeDisplayMode == NCWidgetDisplayModeCompact) {
//折疊
self.preferredContentSize = CGSizeMake(maxSize.width, 100);
//處理一些操作
} else {
//展開
self.preferredContentSize = CGSizeMake(maxSize.width, 200);
//處理一些操作
}
} else {
// Fallback on earlier versions
}
}
這里注意加載數(shù)據(jù)完畢后妈经,渲染UI時一定要在主線程操作。
3.喚醒宿主App
widget 與 宿主App屬于兩個獨立的進程捧书〈蹬荩可以理解為兩個不同的App,如果喚醒宿主经瓷,可以通過schemes的方式喚醒爆哑。
1.在宿主App內(nèi)設置url schemes
在宿主項目的target->info->URLTypes點擊加號增加內(nèi)容,然后在URL Schemes定義一個Schemes舆吮,例如為widgetDemo揭朝,如下圖
2.處理widget的點擊事件
在需要跳轉的時候加入以下代碼
//點擊了內(nèi)容,要跳轉到宿主app
NSURL *URL = [NSURL URLWithString:@"widgetDemo://data=123456"];
[self.extensionContext openURL:URL completionHandler:^(BOOL success) {
if (success) {
NSLog(@"打開成功");
}
}];
4.與宿主App共享數(shù)據(jù)
1.通過schemes傳遞參數(shù)
如果數(shù)據(jù)量不大色冀,僅僅是參數(shù)的一些傳遞的話潭袱,利用schemes即可,如上面的代碼所示widgetDemo://后面的data=123456即是參數(shù)锋恬,可以攜帶少量的信息屯换。
2.通過App Groups來共享數(shù)據(jù)
(1.)去開發(fā)者賬號Identifiers->App Groups 點擊+號增加一個App Groups total.如下圖:
(2.)然后去宿主App的appId點擊Edit->點擊App Groups的Edit,選中剛才創(chuàng)建的App Groups total->Continue.點擊如下圖
(3.)分別去Xcode中的宿主Targrt 與 widget Target,打開App Groups對剛才創(chuàng)建的App Groups total打鉤彤悔,無任何錯誤嘉抓,證明添加成功,如下圖晕窑。
當然你也可以忽略前兩步直接進行第三步抑片,點擊+號分別在宿主Targrt 與 widget Target中增加一個App Groups total,可能會因為格式不對杨赤,而無法添加成功敞斋。
分別在widget 內(nèi)添加寫入代碼,在宿主app內(nèi)添加讀取代碼望拖。即可完成App Groups內(nèi)數(shù)據(jù)共享
//widget內(nèi)存入數(shù)據(jù)
- (void)wirteData:(NSData *)data {
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.widgetdemo.message"];
[userDefaults setObject:data forKey:@"widgetImage"];
BOOL isok = [userDefaults synchronize];
NSLog(@"寫入成功?%d",isok);
}
//宿主app內(nèi)讀取數(shù)據(jù)
- (void)readMessage {
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.widgetdemo.message"];
NSData * date = [userDefaults objectForKey:@"widgetImage"];
_imageView.image = [UIImage imageWithData:date];
}
至此widget的簡單使用完成挫鸽,Demo戳這里说敏,下面有一些注意點:
1.widget與宿主細胞分別是兩個不同的進程,相當于是兩個不同的app丢郊,上架的時候需要創(chuàng)建證書盔沫,配置文件等。
2.widget與宿主細胞分別是兩個不同的進程枫匾,圖片等資源不能直接使用宿主app的資源架诞。
3.widget target基本配置里面將Deployment Target設置為你要兼容的iOS最低版本。一定比你真機的iOS系統(tǒng)版本低干茉,否者不能顯示出來谴忧。