iOS 10推出了很多新功能丈攒,其中有幾個高調(diào)的變化:通知欄更加實用哩罪,電話可以防騷擾授霸,iMessage變得更加有趣和強大,還有就是新一輪的Siri調(diào)戲际插。這些重大功能讓我們更加期待iOS10正式上線碘耳!作為開發(fā)者,我們也需要不斷為自己充電框弛,想把握先機辛辨?讓我們先來看看它們的基本-App Extension
介紹
應用擴展(App Extension)從iOS 8正式登錄iOS平臺,開發(fā)者可以通過應用擴展為用戶提供系統(tǒng)特定的擴展功能。開發(fā)者通過擴展點(Extension Point)來指定特定的系統(tǒng)功能瑟枫,如Today擴展斗搞,通知欄擴展,Messages擴展慷妙,電話簿擴展等等僻焚。
創(chuàng)建應用擴展
應用擴展必須依附于一個宿主App(iOS10有更新,見下文)景殷,在現(xiàn)有工程中溅呢,選擇File->New->Target->Application Extension來創(chuàng)建一個應用擴展
開發(fā)者可以根據(jù)自己的業(yè)務(wù)需求創(chuàng)建不同的應用擴展,也可以在一個App中創(chuàng)建多個應用擴展猿挚。
iOS10開始咐旧,Messages擴展可獨立于宿主App創(chuàng)建:
創(chuàng)建Messages Application.png
Messages Application將自動創(chuàng)建一個Sticker Pack和Messages Extension。
參考iMessage Apps and Stickers, Part 1 WWDC 2016 第7分鐘的介紹绩蜻。
Xcode會為我們自動生成一些文件,有兩種類型:
-
含用戶交互界面的
如:Today Extension
Today Extension.png
包含一個ViewController铣墨,一個ui和一個plist。
同類型的還有Message Extension(需要Xcode8), Share Extension, Action Extension等办绝。
2.不含用戶交互界面的
如:Share Link Extension
包含一個Handler和plist伊约。
同類型的還有Call Directory Extension(需要Xcode8)等。
這兩種類型的plist大致相同孕蝉,除了NSExtension這個屬性屡律。
含用戶交互界面的應用擴展會定義NSExtensionMainStoryboard
,通常會是MainInterface降淮;而不含用戶交互界面的應用擴展則會定義NSExtensionPrincipalClass
超埋,通常會是XXXHandler(在Share Link Extension的例子中是RequestHandler)。
生命周期
了解應用擴展的生命周期佳鳖,首先要了解兩個概念:
1.容器App (container app)
2.宿主App (host app)
容器App是包含應用擴展的App霍殴,就是應用擴展所依賴的App;
宿主App是提供應用擴展界面顯示或者功能的App。
其次:
雖然容器App包含應用擴展系吩,但它與應用擴展有著完全不同的生命周期来庭,應用擴展與容器App擁有不同的進程。
![應用擴展life cycle](https://developer.apple.com/library/prerelease/content/documentation/General/Conceptual/ExtensibilityPG/Art/app_extensions_lifecycle_2x.png)
1.用戶在宿主App中選擇應用擴展(查看其UI或者點擊啟動其功能)穿挨。下面會說明
2.系統(tǒng)啟動應用擴展月弛。在此期間肴盏,宿主App會調(diào)用相關(guān)方法啟動應用擴展,應用擴展可以通過ExtensionContext的到交互信息帽衙。
3.應用擴展執(zhí)行業(yè)務(wù)邏輯叁鉴。有些應用擴展在這個階段不需要和宿主App進行交互,如Share Link Extension佛寿;有些應用擴展則需要和宿主App保持聯(lián)系以監(jiān)聽用戶操作或接受命令幌墓,如iMessage Extension。
4.應用擴展執(zhí)行完畢冀泻,系統(tǒng)將其終止常侣。
在應用擴展的生命周期中,甚至不需要與容器App有任何交互弹渔。實際上胳施,應用擴展運行時,容器App也不需要處于運行狀態(tài)(除非主動調(diào)用)肢专。
應用擴展響應宿主App請求
我們在上文提到了應用擴展的兩種類型舞肆,應用擴展的類型不同,響應請求的方式也不同博杖。
有用戶交互界面的應用擴展在宿主App中展示的時候啟動椿胯,并且加載UI。我們可以在ViewController的loadView
等方法中通過self.extensionContext
(NSExtensionContext 類型)來獲取宿主App傳給應用擴展的信息剃根。
無用戶交互界面的應用擴展在Handler(NSExtensionPrincipalClass
指定的Handler)中直接接受來自宿主App的請求,調(diào)用方法:
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context;
當應用擴展響應宿主App哩盲,并請求完業(yè)務(wù)邏輯之后,需要主動告知宿主App狈醉。通過調(diào)用NSExtensionContext
的這兩個方法:
- (void)completeRequestReturningItems:(nullable NSArray *)items completionHandler:(void(^ __nullable)(BOOL expired))completionHandler;
- (void)cancelRequestWithError:(NSError *)error;
應用擴展執(zhí)行
completeRequestReturningItems:
之后廉油,系統(tǒng)可以隨時將其終止,如果是有用戶交互界面的應用擴展苗傅,執(zhí)行該方法之后抒线,viewController會立刻dismiss(有用戶交互界面的應用擴展通常都是通過presentViewController
的方式顯示的)。
參考
App Extension Programming Guide
NSExtensionContext Class Reference