iOS Widget小組件開發(fā)(Today Extension)

自iOS8之后煤蹭,蘋果支持了擴(kuò)展(Extension)的開發(fā)码泛,開發(fā)者可以通過系統(tǒng)提供給我們的擴(kuò)展接入點(diǎn) (Extension point) 來為系統(tǒng)特定的服務(wù)提供某些附加的功能逝变。

所謂Widget憎夷,就是我們熟知的小組件佛舱,這是獨(dú)立于應(yīng)用之外的又一個(gè)新小應(yīng)用,但是和主應(yīng)用之間又有著一定的關(guān)系掏膏。

本文介紹的是iOS14系統(tǒng)以下的widget組件,也就是Todat Extension
iOS14系統(tǒng)以上widget請見:
iOS14 Widget(Widget Extension)小組件開發(fā)

widget實(shí)現(xiàn)

1.創(chuàng)建添加Todat Extension

File -> New -> Target -> Todat Extension

創(chuàng)建路徑.jpg

2.添加widget的URL Schemes

由于extension 和主app 是兩個(gè)完全獨(dú)立的進(jìn)程腰池,所以它們之間不能直接相互跳轉(zhuǎn)尾组。為了實(shí)現(xiàn) Widget 調(diào)起 APP忙芒,這里通過 openURL 的方式來啟動(dòng) 主app示弓。

主APP中 Target -> Info-> URL Types -> +

urlscheme.png

調(diào)用方式
widget中點(diǎn)擊跳轉(zhuǎn)事件添加如下代碼

[self.extensionContext openURL:[NSURL URLWithString:@"NowWidget://"] completionHandler:nil];

主APP的AppDelegate中接收

-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options{
    if ([url.scheme isEqualToString:@"NowWidget"]){
        //執(zhí)行跳轉(zhuǎn)后的操作
    }
    return YES;
}
3.數(shù)據(jù)共享

由于widget跟APP間相互獨(dú)立,如果想用相同的數(shù)據(jù)則需要兩者間數(shù)據(jù)共享呵萨,創(chuàng)建App Group
主APP中 Target -> Signing & Capability -> +Capability -> 添加 App Group

APPGroups創(chuàng)建.png

ps:網(wǎng)上說的還需創(chuàng)建申請 APPID 但在開啟自動(dòng)管理 Automatically manage signing的情況下xcode會(huì)自動(dòng)給你創(chuàng)建相關(guān)聯(lián)的APPID

兩者間的數(shù)據(jù)共享主要通過NSFileManagerNSUserDefaults兩種形式奏属。

  • 通過NSUserDefaults共享數(shù)據(jù)
//存數(shù)據(jù)
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.imoblife.now"];
[userDefaults setObject:@"content" forKey:@"widget"];
[userDefaults synchronize];

//取數(shù)據(jù)
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.imoblife.now"];
NSString *content = [userDefaults objectForKey:@"widget"];
  • 通過NSFileManager共享數(shù)據(jù)
-(BOOL)saveDataByNSFileManager:(NSData *)data
{
    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.imoblife.now"];
    containerURL = [containerURL URLByAppendingPathComponent:@"widget"];
    BOOL result = [data writeToURL:containerURL atomically:YES];
    return result;
}

-(NSData *)readDataByNSFileManager
{
    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.imoblife.now"];
    containerURL = [containerURL URLByAppendingPathComponent:@"widget"];
    NSData *value = [NSData dataWithContentsOfURL:containerURL];
    return value;
}
4.開啟折疊及尺寸規(guī)定

不需要折疊功能忽略此步驟

- (void)viewDidLoad {
    [super viewDidLoad];
    //添加折疊效果
    self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
}
//折疊及非折疊樣式更改
-(void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
    /**
     iOS10以后,重新規(guī)定了Today Extension的size潮峦。寬度是固定(例如在iPhone6上是359)囱皿,所以無法改變勇婴;但是高度方面,提供了兩種模式:
     
     NCWidgetDisplayModeCompact:固定高度嘱腥,則為110
     
     NCWidgetDisplayModeExpanded:可以變化的高度耕渴,區(qū)間為110~616
     */
    if (activeDisplayMode == NCWidgetDisplayModeCompact) {
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width-16, 110);
    } else {
        self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width-16, 250);
    }
}

//此方法主要執(zhí)行刷新操作
- (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler {
    // Perform any setup necessary in order to update the view.
    
    // If an error is encountered, use NCUpdateResultFailed
    // If there's no update required, use NCUpdateResultNoData
    // If there's an update, use NCUpdateResultNewData
    
    completionHandler(NCUpdateResultNewData);
}

5.文件共享及pods共享
  • 文件共享

    文件共享.png

    勾選共享widget選項(xiàng)即可

  • pods共享
    正常使用下widget中無法使用pods導(dǎo)入的第三方SDK如Masonry等,會(huì)造成布局等極其不便齿兔,因此需要共享pods橱脸,在Podfile中需要另設(shè)置并重新install

source 'https://github.com/CocoaPods/Specs.git'

platform :ios, '9.0'
inhibit_all_warnings!

#共享Masonry
def share_pods
    pod 'HandyJSON'
end

target "targetName" do
    pod 'AFNetworking'
    share_pods
end

target "widgetTargetName" do
    share_pods
end

完成后即可使用pods中的第三方SDK了
#import <Masonry.h>
#import <SDWebImage/UIImageView+WebCache.h>
#import <SDWebImageDownloader.h>
#import <SDImageCache.h>
#import <AFNetworking.h>...

Pods第三方SDK使用錯(cuò)誤提示
如果在pods導(dǎo)入共享第三方庫,或者使用[UIApplication sharedApplication]方法報(bào)錯(cuò)如下時(shí)

not available on iOS (App Extension) - Use view controller based solutions where appropriate instead.

則需要在pods Target里面分苇,選中出錯(cuò)的SDK并點(diǎn)擊buildSettings 搜索Require
然后把Require Only App-Extension-Safe API 然后把YES改為NO即可

修正路徑說明.png

ps:工程項(xiàng)目里也可按照這個(gè)方法去排查原因


在調(diào)試widget功能時(shí)不要忘記將Device變更為widget項(xiàng)目 ??♀???♀???♀?

調(diào)整device.png

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末添诉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子医寿,更是在濱河造成了極大的恐慌栏赴,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件靖秩,死亡現(xiàn)場離奇詭異须眷,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)沟突,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門柒爸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人事扭,你說我怎么就攤上這事捎稚。” “怎么了求橄?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵今野,是天一觀的道長。 經(jīng)常有香客問我罐农,道長条霜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任涵亏,我火速辦了婚禮宰睡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘气筋。我一直安慰自己拆内,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布宠默。 她就那樣靜靜地躺著麸恍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抹沪,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天刻肄,我揣著相機(jī)與錄音,去河邊找鬼融欧。 笑死敏弃,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的噪馏。 我是一名探鬼主播权她,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逝薪!你這毒婦竟也來了隅要?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤董济,失蹤者是張志新(化名)和其女友劉穎步清,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虏肾,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡廓啊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了封豪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谴轮。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖吹埠,靈堂內(nèi)的尸體忽然破棺而出第步,到底是詐尸還是另有隱情,我是刑警寧澤缘琅,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布粘都,位于F島的核電站,受9級特大地震影響刷袍,放射性物質(zhì)發(fā)生泄漏翩隧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一呻纹、第九天 我趴在偏房一處隱蔽的房頂上張望堆生。 院中可真熱鬧,春花似錦雷酪、人聲如沸淑仆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糯景。三九已至,卻和暖如春省骂,著一層夾襖步出監(jiān)牢的瞬間蟀淮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工钞澳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怠惶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓轧粟,卻偏偏與公主長得像策治,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子兰吟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348