Widget專題
1 機(jī)制原理
1.1 概念
1、appextension
app extension:extension是iOS8新開(kāi)放的一種對(duì)幾個(gè)固定系統(tǒng)區(qū)域的擴(kuò)展機(jī)制,extension并不是一個(gè)獨(dú)立的app,它有一個(gè)包含在app bundle中的獨(dú)立bundle,extension的bundle后綴名是.appex。當(dāng)然它有好多類型,如下圖官方文檔上介紹的那天,今天我們主要講解的就是Today中的,又叫做widget。
2、containing app
包含extension的app就是containningapp,因?yàn)閑xtension不能單獨(dú)存在,所以必須得依附在一個(gè)正常的app里,這樣才能提交商店。
3、host app
能夠調(diào)起extension的app被稱為hostapp,比如widget的host app就是Today。
我們看下它們?nèi)咧g是如何工作的,如下圖:
作為一個(gè)ios開(kāi)發(fā)者,遇到問(wèn)題的時(shí)候,有一個(gè)學(xué)習(xí)的氛圍跟一個(gè)交流圈子特別重要,對(duì)自身有極大幫助,眾人拾柴火焰高 這是一個(gè)我的iOS交流群:711315161,進(jìn)群密碼iOS 分享BAT,阿里面試題、面試經(jīng)驗(yàn),討論技術(shù), 大家一起交流學(xué)習(xí)成長(zhǎng)!希望幫助開(kāi)發(fā)者少走彎路。
2 實(shí)現(xiàn)
2.1 新建Target
接下來(lái)我們具體看如何完成一個(gè)簡(jiǎn)單的DEMO,這樣你就更加了解了。
首先我們先新建一個(gè)工程,這一步就省略了,接下來(lái)我們?cè)黾右粋€(gè)target,選擇TodayExtension,如下圖:
然后創(chuàng)建完,如下圖:
默認(rèn)創(chuàng)建的storyboard里是helloworld,所以我們先run項(xiàng)目,看看效果:
是不是很簡(jiǎn)單,_。。。
2.2 數(shù)據(jù)共享
那么接下來(lái)我們看下containing app跟extension如何共享數(shù)據(jù),例如我containing app里的數(shù)據(jù),我要在extension顯示。
2.2.1 添加appgroups
在這之前,我們要先講下app groups,它主要用于同一group下的app共享同一份讀寫(xiě)空間,以實(shí)現(xiàn)數(shù)據(jù)共享。我們看下工程中如何開(kāi)啟app groups,首先們選擇targets,然后選擇containing app,->Capabilities,打開(kāi)appgroups的開(kāi)關(guān),如下圖:
點(diǎn)下面的加號(hào)按鈕,新建一個(gè)group,例如:group.com.company.app,如下圖:
創(chuàng)建完后如下圖:
同理,選擇targets為extension,同樣創(chuàng)建一個(gè)appgroups,選擇跟containing app一樣的名字,就是containing app里的appgroups跟extension里的app groups名字相同,如下圖:
OK。。。app groups創(chuàng)建好后,我們就可以實(shí)現(xiàn)數(shù)據(jù)共享了,
2.2.2 共享數(shù)據(jù)讀寫(xiě)
2.2.2.1 通過(guò)NSUserDefaults
第一種方法是通過(guò)NSUserDefaults,存數(shù)據(jù)代碼如下:
1 **NSUserDefaults** *shared = [[NSUserDefaults alloc] initWithSuiteName:groupID];
2 [shared setObject:[NSNumber numberWithInt:10] forKey:@"number"];
3 [shared synchronize];
取數(shù)據(jù)如下:
1 **NSUserDefaults** *shared = [[NSUserDefaults alloc] initWithSuiteName:groupID];
2
3 **NSString** *string=[NSString stringWithFormat:@"%@",[shared objectForKey:@"number"]];
4
5 _numberLabel.text=string;
我們?cè)赾ontaining app中存一個(gè)數(shù)據(jù),然后在extension里取一個(gè)數(shù)據(jù),demo中我存了一個(gè)數(shù)字10,然后我們看下效果:
2.2.2.2 通過(guò)NSFileManager
還有一種方法是通過(guò)NSFileManager來(lái)實(shí)現(xiàn),存數(shù)據(jù)代碼如下:
1 **NSError** *err =** nil**;
2 **NSURL** *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupID];
3 containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/test"];
4
5 **NSString** *value =@"123";
6
7 **BOOL** result = [value writeToURL:containerURL atomically:**YES** encoding:NSUTF8StringEncoding error:&err];
取數(shù)據(jù)代碼如下:
1 **NSError** *err =** nil**;
2 **NSURL** *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupID];
3 containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/test"];
4 **NSString** *value = [NSString stringWithContentsOfURL:containerURL encoding:NSUTF8StringEncoding error:&err];
2.2.2.3 共享代碼
對(duì)于更復(fù)雜工程里加入extension,可能需要共享代碼,你可能需要把一些公用的數(shù)據(jù)寫(xiě)入自己的framework中,然后containing app跟extension中各存一個(gè),以此來(lái)達(dá)到共用代碼,至于具體的實(shí)現(xiàn),各位可以自己去嘗試嘗試_。。
2.3 點(diǎn)擊extension內(nèi)容回到containing app
我們?cè)倏聪峦ㄟ^(guò)點(diǎn)擊extension里的內(nèi)容來(lái)回到containing app中,其實(shí)就是通過(guò)openurl,首先需要在containing app中創(chuàng)建urltype,如下圖:
在extension中,寫(xiě)如下代碼:
[**self**.extensionContext openURL:[NSURL URLWithString:@"TestWight://"] completionHandler:^(**BOOL** success) {
NSLog(@"open url result:%d",success);
}];
需要注意的地方是,extension中view的位置不是最左邊開(kāi)始的,而是默認(rèn)從icon后開(kāi)始的,所以如需修改,代碼入下:
// 一般默認(rèn)的View是從圖標(biāo)的右邊開(kāi)始的...如果你想變換,就要實(shí)現(xiàn)這個(gè)方法
- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
//UIEdgeInsets newMarginInsets = UIEdgeInsetsMake(defaultMarginInsets.top, defaultMarginInsets.left - 16, defaultMarginInsets.bottom, defaultMarginInsets.right);
//return newMarginInsets;
//return UIEdgeInsetsZero; // 完全靠到了左邊....
**return** UIEdgeInsetsMake(0.0, 16.0, 0, 0);
}
還有就是有時(shí)view里的控件看不見(jiàn),所以需要添加這句話:
**self**.preferredContentSize = CGSizeMake(**self**.view.bounds.size.width, 100);
需要手動(dòng)自己添加,在下拉通知里的edit里,
2.4 常見(jiàn)使用問(wèn)題
2.4.1 運(yùn)行后Today中沒(méi)有widget
可能是新建的工程的Deployment Target版本太高了,比測(cè)試機(jī)版本高,導(dǎo)致存在版本兼容性問(wèn)題,將版本值設(shè)為6.0或者7.0即可。
3 參考鏈接
ios8新特性widget開(kāi)發(fā)
http://blog.csdn.net/kuloveyouwei/article/details/44019815
iOS開(kāi)發(fā)之構(gòu)建Widget