IOS開(kāi)發(fā)系列——Widget專題【整理】

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。

image

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是如何工作的,如下圖:

image
image

作為一個(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,如下圖:

image

然后創(chuàng)建完,如下圖:

image

默認(rèn)創(chuàng)建的storyboard里是helloworld,所以我們先run項(xiàng)目,看看效果:

image

是不是很簡(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),如下圖:

image

點(diǎn)下面的加號(hào)按鈕,新建一個(gè)group,例如:group.com.company.app,如下圖:

image

創(chuàng)建完后如下圖:

image

同理,選擇targets為extension,同樣創(chuàng)建一個(gè)appgroups,選擇跟containing app一樣的名字,就是containing app里的appgroups跟extension里的app groups名字相同,如下圖:

image

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,然后我們看下效果:

image

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,如下圖:

image

在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里,

image
image

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

http://www.imooc.com/wenda/detail/253341

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容