iOS之widget開發(Today Extension)

前言

extension是iOS8新開放的一種對幾個固定系統區域的擴展機制,它能夠在必定程度上彌補iOS的沙盒機制對應用間通訊的限制。javascript

extension的出現,爲用戶提供了在其它應用中使用咱們應用提供的服務的便捷方式,好比用戶能夠在Today Extension中查看應用展現的簡略信息,而不用再進到咱們的應用中,一樣能夠快捷操做app的功能,這將是一種全新的用戶體驗。java

今天咱們介紹一下給工程添加Today Extension的步驟。git

添加Today Extension工程

在原有的工程基礎上,想要使用Today Extension,咱們須要建立一個新的target,點擊File-->New-->Target-->Today Extention,以下圖所示:github

添加Target

選擇Today Extension

添加成功後項目的目錄會以下圖所示:app

工程目錄

運行項目會看到以下圖所示的效果:ide

運行效果

定製UI

因爲我習慣使用純代碼寫UI,因此我會選擇刪除默認建立的MainInterface.storyboard,並在info.plist中刪除NSExtensionMainStoryboard,添加NSExtensionPrincipalClass爲TodayViewController,以下圖所示:
學習

配置controller

咱們能夠使用如下方法配置視圖的大小

//配置Today Extension展現視圖的大小
self.preferredContentSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, 100);複製代碼

實現下面的協議,配置邊距,不然會發現一個問題:繪製的內容與左側邊界有必定距離。ui

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {

    //配置邊距爲0
    return UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0);

}複製代碼

咱們建立一個lable來充滿視圖,而且點擊可打開咱們的appatom

//Today Extension的頁面加一個可點擊打開containingAPP的label
UILabel *openAppLabel = [[UILabel alloc] init];
openAppLabel.textColor = [UIColor colorWithRed:(97.0/255.0) green:(97.0/255.0) blue:(97.0/255.0) alpha:1];
openAppLabel.backgroundColor = [UIColor clearColor];
openAppLabel.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 100);
openAppLabel.textAlignment = NSTextAlignmentCenter;
openAppLabel.text = @"點擊打開app";
openAppLabel.font = [UIFont systemFontOfSize:15];
[self.view addSubview:openAppLabel];

openAppLabel.userInteractionEnabled = YES;
UITapGestureRecognizer *openURLContainingAPP = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(openURLContainingAPP)];
[openAppLabel addGestureRecognizer:openURLContainingAPP];複製代碼

打開app

Today Extension只能經過openURL的方式來調起app,而且須要在info.plist文件中配置參數URL types,
app工程中配置以下url

app schemes

Today Extension以下圖

跳轉URL types設置

URL identifier爲app的bundle ID,URL Schemes配置爲app的scheme
而且調用如下代碼來打開app

//經過openURL的方式啓動Containing APP
- (void)openURLContainingAPP
{
    //scheme爲app的scheme
    [self.extensionContext openURL:[NSURL URLWithString:@"scheme://xxxx"]
                 completionHandler:^(BOOL success) {
                     NSLog(@"open url result:%d",success);
                 }];
}複製代碼

demo代碼,因爲後面的步驟是須要蘋果開發者帳號才能操做,因此demo的代碼到這裏爲止。

數據共享

首先須要去蘋果開發者中心的APP Groups中建立一個APP Group,命名方式"group.com.companyName.xxx",以下圖

建立App Group

完成以後你還要作如下修改

  1. 編輯你的contain app的APP ID,Service中選中App Groups,而且點擊右邊的Edit按鈕選中剛剛建立的group,返回後,點擊Done完成APP ID的編輯
  2. 此時contain app的Provisioning Profiles文件會顯示爲沒法使用,須要更新下文件,而且下載下來覆蓋安裝

Today Extension工程與app工程的配置都以下圖所示

App Groups設置

經過App Groups提供的同一group內app共同讀寫區域,能夠用NSUserDefaults和NSFileManager兩種方式實現Today Extension和containing app之間的數據共享。

經過NSUserDefaults共享數據

- (void)saveDataByNSUserDefaults
{
    NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.xxx.xxx"];
    [shared setObject:@"test" forKey:@"widget"];
    [shared synchronize];
}

- (NSString *)readDataFromNSUserDefaults
{
    NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.xxx.xxx"];
    NSString *value = [shared valueForKey:@"widget"];

    return value;
}複製代碼

經過NSFileManager共享數據

- (BOOL)saveDataByNSFileManager
{
    NSError *error = nil;
    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.xxx.xxx"];
    containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/test"];

    NSString *value = @"test";
    BOOL result = [value writeToURL:containerURL atomically:YES encoding:NSUTF8StringEncoding error:&error];
    if (!result) {
        NSLog(@"%@",error);
    } else {
        NSLog(@"save value:%@ success.",value);
    }

    return result;
}

- (NSString *)readDataByNSFileManager
{
    NSError *error = nil;
    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.com.xxx.xxx"];
    containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/test"];
    NSString *value = [NSString stringWithContentsOfURL:containerURL encoding:NSUTF8StringEncoding error:&error];

    return value;
}複製代碼

這樣就實現了Today Extension與app的數據共享

真機調試與打包

咱們把Today Extension看成一個單獨的app,各自有本身的App ID和Provisioning profile. 在Xcode裏是兩個Target給不一樣的target設置本身的bundleID和Provisioning profile。因此你須要按如下步驟操做,才能真機調試以及打包

蘋果開發者中心操做如下步驟

  1. 須要爲Today Extension建立一個APP ID,通常命名方式爲你的contain app的bundle id加上你建立的Today Extension工程名"com.companyName.xxx.xxx",App Services中勾選上App Groups,完成建立。以下圖
    Today Extension APP ID設置
  2. 去Provisioning Profiles中建立Today Extension對應的profile文件,下載下來,安裝,真機調試和打包須要用到,以下圖
    Today Extension profile文件
  3. 將Today Extension的bundleID修改成剛剛爲Today Extension建立的APP ID
  4. Today Extension版本號與contain app配置一致,不然審覈上傳的時候會有警告
  5. 打包或者真機調試的時候contain app與Today Extension選擇各自的profile文件。

完成以上的準備工做以後,咱們就能夠開始真機調試以及打包了。

總結

本篇暫時只是Today Extension簡單的功能實現,我會在後面更新iOS10的適配,以及其餘功能使用。若是有錯誤的地方歡迎指出~謝謝~

擴展閱讀

  1. WWDC2014之App Extensions學習筆記

但願對您有幫助,若是文章中有問題,歡迎評論留言~,謝謝支持~歡迎關注,我會在空餘時間更新技術文章~

相關文章
相關標籤/搜索