App Extensions篇之Share Extension,appextensionshare
轉載請註明出處:http://www.cnblogs.com/zhanggui/p/7119572.html
1.前言
這裡主要是對App Extension的一些介紹以及詳細給大家介紹一下Share Extension,後期會添加其他的Extension介紹。
2.開始
主要對App Extension和Share Extension進行介紹。請繼續往下看:
2.1: App Extension的介紹
官方給的說法是:App Extension可以讓你擴充你的APP的自訂功能和內容,使使用者可以在與其他應用或者系統進行互動的時候去使用它。翻譯的不一定準確,這樣說可能會好理解:我們平時看到的Widget、和QQ的share等等,都是App Extension,是一些例子:
其實就是我們經常看到的Widget,但是Widget只是Today Extension,除了Today Extension,還有很多。
一個支援擴充的系統地區叫做一個extension point(擴充點)。每個擴充點的擴充都有自己專屬的使用方法和API。你可以根據你的需求來選擇不同的擴充。官方API裡面提出了一個名詞叫:Host app,我們可以把它理解為宿主的App也就是提供應用擴充介面顯示或者功能的App。還有一個container app,我們可以把它理解為容器App,就像的share extension,容器app就是。
擴充和app不同,擴充無法單獨上架AppStore。儘管你必須使用個app來包含並且分發你的extension,extension也是一個單獨的二進位檔案,獨立於用於傳遞和分發的container app。
你可以通過File--->New --->Target來建立Extension,它和其他的target一樣,它和你的app project組合成為一個產品。一個app可以有一個擴充,也可以有多個擴充。最好的建立擴充的方式就是通過Xcode提供的Extension種類選擇自己需要的來建立,裡麵包含了必要的API以及方法實現。
如果你想讓使用者去使用你的擴充,那麼就需要吧你的containing app發布到AppStore,當使用者安裝了你的Containing app,擴充也就安裝了。不同的擴充啟動的方式也不一樣,例如Today Extension,你需要Widget來展示到你的通知中樞。擴充也不要亂用,擴充的最佳使用者體驗從來都是希望使用者操作更精簡、更快速,並且專註於單個任務。
2.1.1: Extension的種類
我們可以在Xcode的File--->New--->Target裡面看到不同平台的Extension,包括iOS、watchOS、tvOS、macOS等等。這裡主要介紹iOS,主要包括以下幾種Extensions:
1.Action Extension:動作擴充,在另一個應用程式的上下文中操作或者查看內容
2.Audio Unit Extension:音頻單元擴充
3.Broadcast UI Extension:廣播UI 擴充
4.Broadcast Upload Extension:廣播上傳擴充
5.Call Directory Extension:呼叫目錄擴充
6.Content Blocker Extension:內容攔截器擴充
7.Custom Keyboard Extension:鍵盤擴充,例如第三方的鍵盤,搜狗IME,百度IME等。
8.iMessage Extension:訊息的擴充
9.Intents Extension:Intents擴充
10.Intents UI Extension:Intents UI擴充
11.Notification Content Extension:通知內容擴充
12.Notification Service Extension:通知服務擴充
13.Photo Editing Extension:圖片編輯擴充,在照片app中編輯照片或者視頻
14.Share Extension:分享擴充,發布一個共用網站或者與其他應用共用內容。
15.Shared Links Extension:分享連結擴充功能
16.Spotlight Index Extension:Spotlight 索引擴充
17.Sticker Pack Extension:貼紙包擴充
18.Today Extension:Today擴充,可以快速擷取更新或者在通知中樞的近日視圖中執行一項快速任務。
等等。也可直接在這裡參見更多extension。
2.1.2: App Extensions的生命週期
先,估計你已經看到了好多次這張圖,恭喜你這次又看到了,因為這個是蘋果官方提供的圖片。
1.使用者選擇要使用的App extension
2.系統啟動App Extension
3.App Extension 代碼運行
4.運行完之後系統kill掉App Extension
這就是App Extension的生命週期,舉個例子:
一個Share Extension,在圖庫裡面你選擇了一張圖片,然後點擊分享,選擇你的Share Extension(第一步),此時系統會啟動你的Share Extension(第二步)。然後你將選擇的圖片分享到指定的程式(例如的發送給朋友)(第三步)。接下來分享頁面關閉,系統kill掉了Share Extension。
2.1.3: App Extension的通訊方式
App Extension主要的通訊是和他的host app(例如的Share Extension和),來自host app的請求和extension的response。你應該也很熟悉(app 擴充直接和host app溝通):
這個展示的就是正在啟動並執行App Extension、host app和containing app之間的關係。可以看出:Containing App和app Extension並沒有直接的溝通。甚至有的時候Containing app可以不運行,而App Extension直接運行。Containing app和Host app沒有任何的溝通。
在一個典型的request/response中,系統開啟代表host app(圖庫)的extension(分享的share extension),把host app提供的資料(圖片和選擇的好友)輸送到extension的context,然後extension展示介面,提供一些功能任務(例如的分享到朋友)。
還有一種是app extension可以直接和他的containing app溝通:
例如Today Widget,可以直接告訴系統開啟他的Containing app,只需要調用NSExtensionContext的openURL:CompletionHandler:方法即可。
2.1.4: 在App Extension中不可以做的事情
一個app extension不能有以下情況:
1.訪問sharedApplication對象。因此不能使用任何該對象的防範
2.使用任何標記NS_EXTENSION_UNAVAILABLE宏的API,或者類似的宏,或者不可用framework裡面的API,例如HealthKit framework不能用於app extensions
3.iOS裝置訪問相機或者麥克風(iMessage app可以訪問這些資源,只要在Info.plist裡面進行配置使用描述即可)
4.運行一個長時間的背景工作(根據不同平台而異)
5.使用AirDrop接收資料
2.2: Share Extension的簡單使用
這裡我們以Share Extension為例進行介紹。
2.2.1: 選擇正確的Extension Point開始開發
當你建立app extension的時候,可以直接使用Xcode內建的模板建立你需要的Extension。點擊File--->New--->Target:
從這裡選擇符合你需求的Extension,當你建立完畢後,你的項目工程目錄就會多一個檔案夾:
可以發現多了一個.swift、.storyboard和一個Info.plist。接下來你也會在Scheme裡發現一個Extension,而且多了一個以.appex為尾碼的Bundle
這裡需要注意:
一個app extension必須在architectures build settings 裡麵包含arm64(ios)或者x86_64(OS X),否則containing app上架的時候將會被拒絕。Xcode預設的Standard architecture包含了64-bit的architecture。
An app extension target must include the arm64 (iOS) or x86_64 architecture (OS X) in its Architectures build settings or it will be rejected by the App Store. Xcode includes the appropriate 64-bit architecture with its “Standard architectures” setting when you create a new app extension target.If your containing app target links to an embedded framework, the app must also include 64-bit architecture or it will be rejected by the App Store.
2.2.2: 來看看預設的App Extension模板
從上面的項目工程目錄看,每個extension都包含了一個plist檔案、一個視圖控制器類和一個預設的user interface,這些都是被extension point定義的。我們先來看一下Info.plist裡面的東西:
再看看項目工程的Info.plist:
兩者可以進行一個對比,可以看出:
1、CFBundlePackageType不一樣,項目是APPL,而Extension的是XPC!
2、比較明顯的就是App Extension裡面多了一個NSExtension的字典。
在Info.plist中,該檔案必須包含NSExtension鍵和擴充點指定的鍵和值的字典。這裡的ExtensionPointIdentifier是com.apple.share-services,因為我建立的是Share Extension。
這裡注意,如果你的app extension的Info.plist裡麵包含了UIBackgroundModes key那麼將無法通過AppStore的審核。
2.2.3:調試App Extension
調試App Extension很簡單,你要做的就是選擇(scheme)擴充,然後點擊Run, 就會彈出一個彈框讓你選擇Host app,選擇Host app之後便可以運行調試。比如你調試Share Extension,你可以選擇照片,然後讓照片當Host app,然後運行之後就會開啟照片,選擇分享就會看到你的app擴充,然後進行debug斷點處理等。
2.3:Share Extension Demo
先看一下我自己做的分享Demo效果:
然後在containing app裡面查看分享的圖片:如的第三張圖。先看一下這裡預設建立的Share Extension的視圖控制器:
class ShareViewController: SLComposeServiceViewController { override func isContentValid() -> Bool { // Do validation of contentText and/or NSExtensionContext attachments here return true } override func didSelectPost() { // This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments. // Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context. self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) } override func configurationItems() -> [Any]! { // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here. return [] }}
裡面主要有三個方法:
isContentValid是用來判斷內容是否可用的,這裡可以做一些校正,比如我們分享的內容是否符合要分享的要求,如果返回false,那麼在的Post按鈕就無法點擊了。因為一旦返回false,則說明分享內容不符合要求,也就無法Post了。
configuration是一個配置數組,它可以配置多個列表,例如分享的[發送給朋友,分享到朋友圈,收藏]:
didSelectPost是你點擊發送之後處理的事件,比如的點擊收藏,可以調用的api,然後進行收藏。預設的注釋也說明了本方法的作用:
當使用者選中post之後調用。是對內容或者NSExtensionContext附件的上傳。我這裡使用App Group的方式進行app Extension和containing app進行互動。先將內容儲存到UserDefaults,然後再在containing app裡面取出圖片展示到containing app裡面。
這裡我把圖片儲存到了UserDefaults,然後在Containing app裡面擷取:
suite的name是app group的名稱。具體可參見Github源碼裡的ShareExtension。
總結
App Extension的出現使App的使用更加方便,比如系統的天氣widget,還有類似(QQ)的分享,完全可以實現不開啟containing app而直接使用share extension分享。
在後續的時間裡,將會不定期進行更新,給讀者介紹其他的Extension,如有任何疑問,隨時留言溝通。
參考資料
1、App Extension Programming Guide
2、深入App Extensions for iOS8
3、Information property List Key Reference
4、App Extension Programming Guide---Share