iOS 應(yīng)用擴(kuò)展 - Today Extension

需求

作出下圖效果(上半部分)

同花順

首先我們知道這是一種Today Extension巩剖,上圖是通過3DTouch觸按彈出的铝穷,我們也可以在今日通知欄里添加看到。

最終的效果如下:

效果圖

創(chuàng)建步驟

1佳魔、創(chuàng)建Today Extension

2曙聂、實(shí)現(xiàn)擴(kuò)展和宿主App之間共享數(shù)據(jù)

3、使用宿主App中的資源

4鞠鲜、擴(kuò)展中打開宿主App

5卢厂、補(bǔ)充:讀取xib文件、擴(kuò)展中支持三方框架源祈、參數(shù)傳遞猛拴、擴(kuò)展Widget高度、上架注意事項(xiàng)

創(chuàng)建Today Extension

首先霞捡,我們選中項(xiàng)目文件坐漏,選擇 xcode ->Editor ->Add Target,如下圖碧信,選中Today Extension項(xiàng)赊琳,然后點(diǎn)擊Next,命名(本文中為MyTodayWidget)砰碴,在彈出框中選擇Activate躏筏,激活這個(gè)scheme。

創(chuàng)建

激活之后呈枉,項(xiàng)目中就會(huì)多出一個(gè) TodayWidget 的擴(kuò)展趁尼,新增的文件夾中的MainInterface.storyboard 和 TodayViewController 這個(gè)類就是我們要在通知中心顯示的界面的控制器檐什。storyborad,里面已經(jīng)有一個(gè)默認(rèn)的界面弱卡,其中只包含了一個(gè)label乃正,顯示“Hello World”。

新增的文件

TodayWidget擴(kuò)展都是以宿主App前綴開始的婶博。

我們先運(yùn)行項(xiàng)目瓮具,再運(yùn)行應(yīng)用擴(kuò)展。

運(yùn)行應(yīng)用擴(kuò)展

這樣凡人,我門可以在系統(tǒng)的今日通知中心看到如下樣式

今日擴(kuò)展

上述就完成了Today Extension的創(chuàng)建名党。

當(dāng)然你可以將擴(kuò)展中的 plist 中的 displayname 更換為宿主應(yīng)用名稱,在TodayViewController完成項(xiàng)目需要的UI挠轴。

共享數(shù)據(jù)

在 Today Extension 開發(fā)中传睹,避免不了要和宿主App之間共享數(shù)據(jù),比如岸晦,筆者的項(xiàng)目中需要使用項(xiàng)目中的域名欧啤、三方平臺(tái)請(qǐng)求頭部、服務(wù)器數(shù)據(jù)地址等等启上;

擴(kuò)展與宿主App之間共享數(shù)據(jù)有兩種方式:

  • 通過NSUserDefaults
  • 通過一個(gè)擴(kuò)展與App都可以訪問的共享容器邢隧,來存放文件,數(shù)據(jù)(Core Data冈在, Sqlite等都可以存放在這個(gè)共享的容器中)

首先倒慧,我們需要?jiǎng)?chuàng)建一個(gè) app group,如下圖包券,選中項(xiàng)目的Target -> Capabilities -> App Groups纫谅,打開,如果你以前創(chuàng)建過group溅固,會(huì)自動(dòng)列出來付秕。選擇+號(hào),填入group的名稱(記下這個(gè)名稱发魄,因?yàn)檫@個(gè)是擴(kuò)展和宿主之間共享數(shù)據(jù)的標(biāo)志符)

group

創(chuàng)建完成之后盹牧,選擇擴(kuò)展的Target -> Capabilities -> App Groups俩垃,打開励幼,選擇我們剛才所創(chuàng)建的group。

??: 如果出現(xiàn)了錯(cuò)誤口柳,應(yīng)該是名稱不可用苹粟,換一個(gè)重試

也可以登錄開發(fā)中選中《App Group》創(chuàng)建

創(chuàng)建App Group

在擴(kuò)展和宿主App打開group之后,項(xiàng)目中會(huì)多出兩個(gè)文件跃闹,如下圖

新增的環(huán)境

完成上述之后嵌削,我們利用剛剛的標(biāo)志符來存取共享的數(shù)據(jù)

// 存儲(chǔ)數(shù)據(jù)
[[[NSUserDefaults alloc] initWithSuiteName:@"group.com.LOLITA.appExtension"] setValue:myNote forKey:@"myShareData"];
// 取出數(shù)據(jù)
NSArray *myData = [[[NSUserDefaults alloc] initWithSuiteName:@"group.com.LOLITA.appExtension"] valueForKey:@"myShareData"];

這樣我們可以在擴(kuò)展和宿主App之間存取共享的數(shù)據(jù)了毛好。

補(bǔ)充:

如果需要存儲(chǔ)更多的數(shù)據(jù),可以通過文件或者數(shù)據(jù)庫(Core Data苛秕, Sqlite等)肌访。這個(gè)時(shí)候共享數(shù)據(jù)的方法就是要?jiǎng)?chuàng)建一個(gè)共享的文件夾。

NSURL *groupURL = [[NSFileManager defaultManager]  containerURLForSecurityApplicationGroupIdentifier: @"group.com.LOLITA.appExtension"];

通過上面的方法艇劫,擴(kuò)展和App就都可以訪問這個(gè)共享的文件夾了吼驶,將數(shù)據(jù)庫,文件等存儲(chǔ)在這個(gè)文件夾中店煞,也同樣的達(dá)到數(shù)據(jù)共享的目的蟹演。

使用宿主App中的文件

在擴(kuò)展中,總是避免不了想要使用宿主項(xiàng)目中的文件顷蟀,例如cell樣式酒请,數(shù)據(jù)處理工具等等,重寫一份當(dāng)然是可以的鸣个,但不是我們想要的結(jié)果羞反。

我們可以將需要用的文件也供用給擴(kuò)展,步驟如下

打開.m文件囤萤,選中下圖按鈕

共享文件

這樣我們就可以在擴(kuò)展中使用該文件了

??:在選擇的文件中苟弛,如果包含了其他文件,一樣是需要添加到擴(kuò)展中的

擴(kuò)展中打開宿主App

既然擴(kuò)展作為了宿主App消息的展示欄阁将,肯定應(yīng)用的入口了膏秫,那么我們?cè)趺醋寯U(kuò)展和App之間進(jìn)行消息傳遞呢?例如做盅,我們需要打開某條消息的詳情缤削,或者是某個(gè)功能模塊。

我們知道吹榴,我們打開別的應(yīng)用是需要設(shè)置URL Types亭敢,然后通過URL Schemes來打開應(yīng)用的,同樣的图筹,擴(kuò)展也可以看成是其他應(yīng)用帅刀,這樣,我們勢(shì)必也要為自己的App設(shè)置一個(gè)URL Types远剩。

首頁我們?cè)O(shè)置一個(gè)URL Types

設(shè)置URL Types

當(dāng)我們想通過openURL來打開應(yīng)用時(shí)扣溺,卻發(fā)現(xiàn)報(bào)錯(cuò)了

openURL

這是因?yàn)閿U(kuò)展不是一個(gè)完整的程序,所以它并沒沒有 sharedApplication 這個(gè)對(duì)象瓜晤。

所以Apple給每個(gè)UIViewController加了一個(gè) extensionContext 屬性锥余,在我們的宿主App中,這個(gè)屬性是nil痢掠,而在擴(kuò)展中驱犹,我們就可以通過extensionContext來執(zhí)行跳轉(zhuǎn)嘲恍。

我們?cè)邳c(diǎn)擊事件中添加如下代碼。

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

既然有跳轉(zhuǎn)雄驹,肯定涉及到傳處理了佃牛,我們?cè)贏ppDelegate里處理消息。

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    // 可以先回到應(yīng)用首頁医舆,在跳轉(zhuǎn)
    if ([url.absoluteString hasPrefix:@"AppExtension"]) {
        if ([url.absoluteString hasSuffix:@"add"]) {
            // do something
        }
        else if ([url.absoluteString containsString:@"detail"]){
            // do something
        }
    }
    return YES;
}

補(bǔ)充

讀取xib文件吁脱、擴(kuò)展中支持三方框架、參數(shù)傳遞彬向、擴(kuò)展Widget高度兼贡、上架注意事項(xiàng)等**

  • 讀取xib文件

如果cell樣式是xib,并出現(xiàn)讀取錯(cuò)誤問題娃胆,可以使用下面代碼嘗試遍希。

NSBundle *bundle = [NSBundle bundleForClass:[TodayItemView class]];
NSArray *cells = [bundle loadNibNamed:@"TodayItemView" owner:nil options:nil];
TodayItemView *itemView = cells.firstObject;
  • 擴(kuò)展中支持三方框架

如果擴(kuò)展中使用到三方框架,則在Podfile中添加下面代碼里烦,并且update

target :'MyTodayWidget' do
    platform :ios, '8.0'
    pod 'AFNetworking', '~> 3.1.0'
end
  • 參數(shù)傳遞

如果需要傳遞多個(gè)參數(shù)凿蒜,可以參考下面代碼嘗試

NSString *urlString = [NSString stringWithFormat:@"AppExtension://markCode=%@&code=%@&yesclose=%@&stockName=%@",market_stockCode,stockCode,preclose_px,[stockName stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];
[self.extensionContext openURL:[NSURL URLWithString:urlString] completionHandler:nil];

??:url中不能出現(xiàn)中文,需要進(jìn)行UTF-8轉(zhuǎn)換胁黑,上面例子中废封,我將中文名稱進(jìn)行了轉(zhuǎn)換,你也可以將urlString整體進(jìn)行轉(zhuǎn)換丧蘸。

  • url解析(接上面c)

如果url解析有問題漂洋,可以參考下面代碼嘗試

// 將url轉(zhuǎn)為http形式
NSString *tmpUrlString = [url.absoluteString stringByReplacingOccurrencesOfString:@"AppExtension://" withString:@"http://xxx?"];
NSURLComponents *components = [NSURLComponents componentsWithString:tmpUrlString];
NSArray* queryItems = components.queryItems;
NSMutableDictionary* queryItemDict = [NSMutableDictionary dictionary];
// 將value和name轉(zhuǎn)換為字典
for (NSURLQueryItem* item in queryItems) {
    [queryItemDict setObject:item.value forKey:item.name];
}
  • 擴(kuò)展Widget高度

系統(tǒng)默認(rèn)的高度為110,如果想要在通知中心擴(kuò)展高度力喷,可以使用下面代碼嘗試刽漂。

- (void)viewDidLoad {
    [super viewDidLoad];
    // 將小部件展現(xiàn)模型設(shè)置為可展開
    self.extensionContext.widgetLargestAvailableDisplayMode = NCWidgetDisplayModeExpanded;
}

在代理方法中設(shè)置高度。

- (void)widgetActiveDisplayModeDidChange:(NCWidgetDisplayMode)activeDisplayMode withMaximumSize:(CGSize)maxSize {
    if (activeDisplayMode == NCWidgetDisplayModeExpanded) {
        // 設(shè)置展開的新高度
        self.preferredContentSize = CGSizeMake(0, NewHeight);
    }else{
        self.preferredContentSize = maxSize;
    }
}

??:使用3DTouch喚出的彈窗依舊是110弟孟,上面代碼只是改變了通知中心的高度

  • 上架注意事項(xiàng)

如果出現(xiàn)打包贝咙,或上架失敗,可以嘗試下面步驟拂募。

  1. 擴(kuò)展和target中的應(yīng)用包都選自動(dòng)管理簽名和證書
簽名
證書
  1. 項(xiàng)目中配置正確的證書
項(xiàng)目配置證書
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庭猩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子陈症,更是在濱河造成了極大的恐慌蔼水,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爬凑,死亡現(xiàn)場(chǎng)離奇詭異徙缴,居然都是意外死亡试伙,警方通過查閱死者的電腦和手機(jī)嘁信,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門于样,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人潘靖,你說我怎么就攤上這事穿剖。” “怎么了卦溢?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵糊余,是天一觀的道長。 經(jīng)常有香客問我单寂,道長贬芥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任宣决,我火速辦了婚禮蘸劈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘尊沸。我一直安慰自己威沫,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布洼专。 她就那樣靜靜地躺著棒掠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屁商。 梳的紋絲不亂的頭發(fā)上烟很,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音蜡镶,去河邊找鬼溯职。 笑死,一個(gè)胖子當(dāng)著我的面吹牛帽哑,可吹牛的內(nèi)容都是我干的谜酒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼妻枕,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼僻族!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起屡谐,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤述么,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后愕掏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體度秘,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了剑梳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唆貌。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖垢乙,靈堂內(nèi)的尸體忽然破棺而出锨咙,到底是詐尸還是另有隱情,我是刑警寧澤追逮,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布酪刀,位于F島的核電站,受9級(jí)特大地震影響钮孵,放射性物質(zhì)發(fā)生泄漏骂倘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一巴席、第九天 我趴在偏房一處隱蔽的房頂上張望稠茂。 院中可真熱鬧,春花似錦情妖、人聲如沸睬关。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽电爹。三九已至,卻和暖如春料睛,著一層夾襖步出監(jiān)牢的瞬間丐箩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來泰國打工恤煞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屎勘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓居扒,卻偏偏與公主長得像概漱,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瓤摧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 最近在做一個(gè)記事類的App,其中有一個(gè)想實(shí)現(xiàn)的功能就是希望能夠在通知中心查看自己的一些記事內(nèi)容玉吁。正好也是之前寫了一...
    水哥閱讀 8,251評(píng)論 8 56
  • iOS8.0加入了擴(kuò)展进副,iOS10蘋果又增加了很多擴(kuò)展这揣。在今后,程序中會(huì)集成越來越多的擴(kuò)展功能。 今天主要來模仿1...
    fou7閱讀 12,788評(píng)論 7 47
  • 在生活中给赞,我曾經(jīng)嘗試堅(jiān)持鍛煉身體机打,明明知道這樣對(duì)自己是有益的,但往往堅(jiān)持不下去塞俱。當(dāng)看到身邊有的人姐帚,明明有好的選擇吏垮,...
    可可兒媽閱讀 249評(píng)論 0 0
  • 也許 用完后 你就不會(huì)在想我 可是 這并不能 阻止我 去裝飾你的美 請(qǐng)?jiān)徫?太容易變形 水向我沖來 我就現(xiàn)出原形...
    螢火蟲最美閱讀 255評(píng)論 1 4
  • 我一直認(rèn)為障涯,具有遠(yuǎn)見是一件太困難的事情。遠(yuǎn)見膳汪,是一種盡可能接近未來的推理能力唯蝶,它的基礎(chǔ)是:洞察力、判斷力遗嗽、學(xué)習(xí)力粘我。...
    王炳煒閱讀 178評(píng)論 0 0