App Extension

Extension概述

眾所周知,基于iOS系統(tǒng)的安全性考慮,其應(yīng)用的數(shù)據(jù)存儲(chǔ)是通過沙盒模式進(jìn)行的,要實(shí)現(xiàn)應(yīng)用之間的數(shù)據(jù)共享十分困難,功能共享就更加棘手。在iOS8系統(tǒng)中,apple為我們提供了一個(gè)革命性的功能:擴(kuò)展。我們可以通過擴(kuò)展來使app間數(shù)據(jù)甚至功能進(jìn)行共享。
  App Extension出現(xiàn)后,突破了兩個(gè)重要的iOS限制,那就是:由Open In系統(tǒng)創(chuàng)建的應(yīng)用程序之間不必要的數(shù)據(jù)復(fù)制無法替換蘋果鍵盤。
  然而,其中有一個(gè)最可能的誤解需要澄清一下,就是iOS 8 App Extensions不同于Android Indents,Ars Technica網(wǎng)站撰稿人Andrew Cunningham這樣寫道。根據(jù)Google的描述:

Intent提供了一種機(jī)制,用于不同應(yīng)用程序代碼之間的后期運(yùn)行時(shí)綁定。它主要用來啟動(dòng)Activities,因此可以將它看作是Activities之間的粘合劑。從本質(zhì)上講,它是一個(gè)無源數(shù)據(jù)結(jié)構(gòu),存放要執(zhí)行動(dòng)作的抽象描述。

雖然Extension在很多情況下與Intent沒有什么不同,但在iOS 8中,App Extension系統(tǒng)的整體設(shè)計(jì)使得它與Intent有很大的不同。

Extension的生命周期

正如蘋果文檔中的描述,Extension是通過“包含應(yīng)用程序(containing app)”提供的專門的二進(jìn)制文件。包含應(yīng)用程序只負(fù)責(zé)提供Extension,后者是獨(dú)立運(yùn)行的。盡管如此,一個(gè)iOS包含應(yīng)用程序?qū)嶋H上還需要提供Extension之外的某些功能。OS X沒有這樣的要求,其上的包含應(yīng)用程序不需要提供任何額外的功能。
雖然說必須有一個(gè)「容器軟件」來包含各種擴(kuò)展應(yīng)用,擴(kuò)展應(yīng)用和容器軟件仍舊分開運(yùn)行。每個(gè)擴(kuò)展都是一個(gè)以「.appex」作為擴(kuò)展名的二進(jìn)制文件。該種類型的文件可以被打開、完成給定任務(wù)、而后在容器軟件未被關(guān)閉的情況下關(guān)閉擴(kuò)展。同時(shí)我們也可以預(yù)想到,許多的應(yīng)用軟件內(nèi)有著同樣的擴(kuò)展。比如說,Instagram 的擴(kuò)展是可以給圖像添加濾鏡。很多其他的圖像處理軟件也需要給圖像添加濾鏡。此時(shí)蘋果公司鼓勵(lì)開發(fā)者使用「嵌入框架」(embedded framework)共享他們完成此任務(wù)的代碼。創(chuàng)建嵌入框架的步驟很簡(jiǎn)單,僅需創(chuàng)建一個(gè)框架、把代碼放進(jìn)框架內(nèi)、而后將框架嵌入容器軟件和應(yīng)用擴(kuò)展即可。唯一需要注意的地方是這種特性必須在 iOS 8.0 或者后續(xù)的系統(tǒng)中才能存在。之前版本的操作系統(tǒng)不支持此種類型的操作。

蘋果公司嚴(yán)格的強(qiáng)制回收內(nèi)存機(jī)制是導(dǎo)致需要擴(kuò)展和容器應(yīng)用分開運(yùn)行的重要原因之一。由于用戶經(jīng)常同時(shí)開啟多個(gè)小插件,因此小插件的內(nèi)存管理受到的限制尤其嚴(yán)格。這從 iPhone 4s 或者 iPad 2 這樣的設(shè)備上這些內(nèi)存受限的小插件的運(yùn)行機(jī)制就能看出。
文檔提到,Extension的生命周期與它的包含應(yīng)用程序完全沒有關(guān)系,它由4個(gè)階段組成:

  • 用戶選擇一個(gè)App Extension
  • 系統(tǒng)啟動(dòng)它
  • App Extension運(yùn)行
  • 系統(tǒng)終止App Extension


    app_extensions_lifecycle_2x.png

    如果兩個(gè)應(yīng)用程序需要同樣的Extension做相同的工作,那么這會(huì)發(fā)生在兩個(gè)獨(dú)立的Extension進(jìn)程中。
    這一方法的主要?jiǎng)訖C(jī)是,通過生命周期短暫的Extension減少內(nèi)存使用和能量消耗,并防止一個(gè)Extension的錯(cuò)誤影響到使用了相同Extension的應(yīng)用程序。

Extension的類型

Extension有多種類型,每一種類型都綁定到一個(gè)稱為“擴(kuò)展點(diǎn)(Extension point)”的系統(tǒng)區(qū)域:

Extension point Typical app extension functionality
Today (iOS and OS X) Get a quick update or perform a quick task in the Today view of Notification Center(A Today extension is called a widget)
Share (iOS and OS X) Post to a sharing website or share content with others
Action (iOS and OS X; UI and non-UI variants) Manipulate or view content originating in a host app
Photo Editing (iOS) Edit a photo or video within the Photos app
Finder Sync (OS X) Present information about file sync state directly in Finder.
Document Provider (iOS; UI and non-UI variants) Provide access to and manage a repository of files.
Custom Keyboard (iOS) Replace the iOS system keyboard with a custom keyboard for use in all apps
Watch App (iOS) Provide an app, a glance, or a notification UI for Apple Watch, as described in App Programming Guide for watchOS.
  • “今日(Today,又稱為Widget)”:可以快速獲取更新或者在通知中心的今日視圖中執(zhí)行一項(xiàng)快速任務(wù)。
  • 共享:發(fā)布到一個(gè)共享網(wǎng)站或者與其它應(yīng)用程序共享內(nèi)容。
  • 動(dòng)作:在另一個(gè)應(yīng)用程序的上下文中操作或查看內(nèi)容。
  • 照片編輯(僅限于iOS):在照片應(yīng)用程序中編輯照片或視頻。
  • 查找器(僅限于OS X):在查找器中直接顯示文件同步的狀態(tài)信息。
  • 文檔提供程序(僅限于iOS):提供對(duì)文件庫的訪問和管理。
  • 自定義鍵盤(僅限于iOS):用自定義鍵盤替代iOS系統(tǒng)鍵盤,并用于所有的應(yīng)用程序中。
  • Watch App(僅限于iOS):為Apple Watch提供一個(gè)app,一個(gè)glance頁面或者一個(gè)通知UI,詳見: App Programming Guide for watchOS

由于每個(gè)擴(kuò)展點(diǎn)都有與之相關(guān)的使用策略和專門的API,開發(fā)人員必須為他們想要提供的那種功能選擇恰當(dāng)?shù)臄U(kuò)展點(diǎn)。例如,在默認(rèn)情況下,鍵盤Extension“不能訪問網(wǎng)絡(luò),而且不能與其包含應(yīng)用程序共享同一容器”。通過對(duì)Extension進(jìn)行恰當(dāng)?shù)呐渲?,這樣的限制可以移除,但開發(fā)人員仍然需要遵守蘋果應(yīng)用商店審查指南和iOS開發(fā)者計(jì)劃許可協(xié)議中的具體的網(wǎng)絡(luò)鍵盤指南。

Extension運(yùn)行機(jī)制

即使是iOS 8 允許運(yùn)行擴(kuò)展,卻仍舊在應(yīng)用、應(yīng)用擴(kuò)展以及應(yīng)用數(shù)據(jù)之間設(shè)置了許多的障礙。而這一切正是出于保護(hù)用戶以及用戶隱私的目的。實(shí)際上應(yīng)用之間仍舊不能直接交流。像之前提到的一樣,應(yīng)用擴(kuò)展是小的二進(jìn)制文件,并且和容器應(yīng)用程序分開來運(yùn)行。調(diào)用這些擴(kuò)展的應(yīng)用程序(蘋果稱之為「主應(yīng)用」,host app)在調(diào)用并啟動(dòng)擴(kuò)展之后會(huì)與擴(kuò)展進(jìn)行直接的交流,然而主應(yīng)用與容器應(yīng)用之間永遠(yuǎn)不會(huì)建立連接。即使主應(yīng)用想要調(diào)用一個(gè)擴(kuò)展,也是通過向蘋果的系統(tǒng)框架發(fā)送請(qǐng)求。此時(shí)僅僅啟動(dòng)應(yīng)用擴(kuò)展,而不直接啟動(dòng)容器應(yīng)用。


simple_communication_2x.png

應(yīng)用擴(kuò)展和「主應(yīng)用」之間可以交流,然而此時(shí)擴(kuò)展和其容器應(yīng)用之間并不會(huì)直接建立聯(lián)系。
在 FortyTwo 公司的 iOS 開發(fā)者 Eduardo Fonseca 向我們解釋了 iOS 是如何實(shí)現(xiàn)讓應(yīng)用和擴(kuò)展之間不建立聯(lián)系的效果的。
「每一個(gè)擴(kuò)展是在主應(yīng)用程序之內(nèi)的獨(dú)立的程序。這些擴(kuò)展擁有獨(dú)立的可執(zhí)行代碼。」Fonseca 說,「然而有趣的是實(shí)際上擴(kuò)展并不是應(yīng)用程序。蘋果的系統(tǒng)框架會(huì)通過已經(jīng)事先定義好的接口調(diào)用這些擴(kuò)展。擴(kuò)展的代碼會(huì)被分開來單獨(dú)執(zhí)行,也就是說第三方應(yīng)用的『應(yīng)用空間』內(nèi)什么都不會(huì)執(zhí)行。這樣的話支持使用擴(kuò)展的應(yīng)用(比如 Safari)就不會(huì)有任何危險(xiǎn)。同樣,在其他應(yīng)用內(nèi)執(zhí)行你的擴(kuò)展也不會(huì)遇到任何問題。它們就像油和水一樣,是完全不會(huì)融合的分開的兩個(gè)部分?!?br> 即使應(yīng)用程序擴(kuò)展與其容器應(yīng)用之間必須有所交流,他們也必須通過系統(tǒng)接口非直接地進(jìn)行交流。默認(rèn)下容器應(yīng)用與其應(yīng)用程序擴(kuò)展之間是不可以互相接觸到對(duì)方的數(shù)據(jù)的。


detailed_communication_2x.png

擴(kuò)展和其容器應(yīng)用必須通過接口和其他用來分享數(shù)據(jù)的特殊容器進(jìn)行非直接的交流
為了在容器應(yīng)用和其應(yīng)用擴(kuò)展之間分享數(shù)據(jù),你也許需要把容器應(yīng)用和擴(kuò)展都設(shè)置成一個(gè)「應(yīng)用群」(App Group) 的一部分。這樣就可以通過包含應(yīng)用沙箱和擴(kuò)展沙箱的一個(gè)第三方容器傳輸二者之間的數(shù)據(jù)。你可能想過為什么在 iOS 上登錄 Chrome 瀏覽器會(huì)讓你同時(shí)登錄谷歌地圖或者谷歌云端硬盤。這就是因?yàn)?Chrome、谷歌地圖和谷歌云端硬盤都是谷歌的應(yīng)用群的一部分。然而即使在應(yīng)用群里,數(shù)據(jù)的分享也有一些限制。它們之間能夠分享數(shù)據(jù)庫、緩存信息、登錄信息等等,但是本地存儲(chǔ)的媒體文件或者其他文件卻絕對(duì)不能分享。
app_extensions_container_restrictions_2x.png

把容器應(yīng)用和應(yīng)用擴(kuò)展放到一個(gè)應(yīng)用群里能夠使它們?cè)诜窒韰^(qū)域分享一些數(shù)據(jù)。否則容器應(yīng)用和應(yīng)用擴(kuò)展的數(shù)據(jù)會(huì)被存儲(chǔ)在不同的地方。
簡(jiǎn)單地來總結(jié)一下上述內(nèi)容:蘋果公司不想讓一個(gè)應(yīng)用能夠進(jìn)入另一個(gè)應(yīng)用的沙箱內(nèi)。而應(yīng)用擴(kuò)展就像是在沙箱里的小沙箱,因此在主應(yīng)用調(diào)用擴(kuò)展時(shí),擴(kuò)展不會(huì)將容器應(yīng)用內(nèi)的數(shù)據(jù)泄露給主應(yīng)用。
應(yīng)用程序擴(kuò)展的執(zhí)行方式和應(yīng)用程序的執(zhí)行方式也不一樣。如果你在不同的應(yīng)用內(nèi)同時(shí)開起了多個(gè)同樣的應(yīng)用程序擴(kuò)展,系統(tǒng)實(shí)際上會(huì)打開多個(gè)應(yīng)用程序擴(kuò)展進(jìn)程、每個(gè)都作為一個(gè)獨(dú)立的進(jìn)程單獨(dú)運(yùn)行。比如說你在 Safari 里打開了一個(gè)擴(kuò)展、而后在郵件里也打開了一個(gè)同樣的擴(kuò)展,那么即使擴(kuò)展都一樣,系統(tǒng)實(shí)際上會(huì)運(yùn)行兩個(gè)不同擴(kuò)展程序進(jìn)程。這些進(jìn)程之間不會(huì)利用你相同的存儲(chǔ)地址區(qū)域,因此這能讓兩個(gè)主應(yīng)用使用獨(dú)立的數(shù)據(jù),并且如果一個(gè)應(yīng)用擴(kuò)展進(jìn)程崩潰了也不會(huì)影響另一個(gè)進(jìn)程。像 Chrome 和 Safari 這樣的瀏覽器也出于同樣的目的,每個(gè)網(wǎng)頁標(biāo)簽實(shí)際上也是分別運(yùn)行的。

Extension限制

上線限制

像所有未越獄的 iPhone 里的軟件一樣,所有的 iOS 擴(kuò)展將需要從蘋果應(yīng)用商城中下載。不過此處最大的限制是蘋果公司不會(huì)允許開發(fā)者提供僅僅作為擴(kuò)展出現(xiàn)的應(yīng)用。開發(fā)者必須提供一個(gè)基本的「容器應(yīng)用程序」,擴(kuò)展則作為錦上添花的內(nèi)容存在于這個(gè)基本的應(yīng)用程序內(nèi)。蘋果公司強(qiáng)調(diào),這個(gè)基本的「容器應(yīng)用」必須提供給用戶一些基本的功能,否則他們不會(huì)授權(quán)該軟件登陸應(yīng)用商店。這一點(diǎn)有別于安卓。

通信限制

對(duì)于Extension與其它應(yīng)用程序之間的通信,蘋果有幾項(xiàng)強(qiáng)制規(guī)定:

1. 調(diào)用Extension的應(yīng)用程序即主應(yīng)用程序不能啟動(dòng)Extension;只有系統(tǒng)可以啟動(dòng)Extension。
2. 當(dāng)Extension啟動(dòng)后,主應(yīng)用程序就和它直接通信。
3. 主應(yīng)用程序永遠(yuǎn)不和包含應(yīng)用程序直接通信。
4. Extension不是一個(gè)應(yīng)用程序,但它由系統(tǒng)生成,并有它自己?jiǎn)为?dú)的進(jìn)程。
5. 為了在包含應(yīng)用程序和它的Extension之間共享數(shù)據(jù),包含應(yīng)用程序及其Extension都必須是應(yīng)用程序組的一部分。對(duì)于應(yīng)用程序組的其中兩個(gè)成員,部分?jǐn)?shù)據(jù)可以在兩者沙箱之外的第三個(gè)容器中共享。

正如Ars Technica的Andrew Cunningham總結(jié)的那樣,這些
規(guī)則的最終結(jié)果主要是一個(gè)應(yīng)用程序不能進(jìn)入另一個(gè)應(yīng)用程序的沙箱。這與Android相反,在Android上,內(nèi)容提供程序解析程序仍然可以一起工作來為應(yīng)用程序提供對(duì)其它應(yīng)用程序中數(shù)據(jù)的訪問。

參考鏈接:

App Extension Programming Guide
App Extension編程指南(iOS8/OS X v10.10):創(chuàng)建應(yīng)用擴(kuò)展
WWDC2014 IOS8 APP Extensions
App Extension編程指南(iOS8/OS X v10.10):擴(kuò)展類型--自定義鍵盤
如何在Swift中創(chuàng)建Action擴(kuò)展

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從 iOS 8 開始,蘋果引入了全新的 App Extension,涉及到方方面面,例如今日面板、鍵盤、內(nèi)容攔截器...
    Cyandev閱讀 15,569評(píng)論 29 85
  • 最近在做一個(gè)記事類的App,其中有一個(gè)想實(shí)現(xiàn)的功能就是希望能夠在通知中心查看自己的一些記事內(nèi)容。正好也是之前寫了一...
    水哥閱讀 8,446評(píng)論 8 56
  • 蝦的個(gè)頭很大,泡在濃稠的酸甜醬汁里面,配著檸檬片和香蔥。 吃蝦基本靠手,筷子都不用。 抓住蝦頭和蝦尾,輕輕擰一下,...
    記憶半島閱讀 426評(píng)論 0 1
  • 北方的夜里, 掛著一輪南方的月, 若不是城市早已睡去, 我或許還不信夜空無星, 可恨的冬日, 清洗如我一般活在夢(mèng)里...
    光洋閱讀 237評(píng)論 2 3
  • 小時(shí)候的我們很擅長(zhǎng)掌握自己的人生。 想當(dāng)班長(zhǎng),課上多回答兩個(gè)問題,與老師頻繁互動(dòng),下課安安靜靜,本本分分差不多就行...
    晗Hevin閱讀 164評(píng)論 0 0

友情鏈接更多精彩內(nèi)容