APP Extension 是iOS 8以后推出的一個(gè)新功能,我們可以通過App Extension快捷的實(shí)現(xiàn)一些操作,而不需要再打開APP。在iOS10以后,又新增了iMessage和Siri的擴(kuò)展。iOS12以后,我們還可以通過Intent來實(shí)現(xiàn)一些捷徑的快捷操作。

這里主要記錄一下APP Extentsion和 主APP之間的數(shù)據(jù)共享。
雖然APP Extentsion和APP是在同一個(gè)項(xiàng)目當(dāng)中,但是他們分屬不同的Targets, 各自擁有屬于自己的沙盒環(huán)境。但是在實(shí)際操作當(dāng)中,我們需要在APP Extentsion里面拿到APP的一些數(shù)據(jù)和資源,這時(shí)候就涉及到Extentsion和APP之間建立起橋接關(guān)系了。
下面說下可能會(huì)用到的幾種情況:
1. 本地?cái)?shù)據(jù)的共享
由于沙盒限制,通過
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
是無法在Extension中獲取到APP的數(shù)據(jù)的。但是Apple提供了一個(gè)GroupID,每一個(gè)APP可以由于一個(gè)唯一的GroupID,通過這個(gè)GroupID可以去獲取數(shù)據(jù)。

NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.xxxxx.IMessageExtension"];
[userDefault setObject:userToken forKey:@"IMessage_User_Token"];
這里需要注意的一點(diǎn)是,這里必須是有效的GroupID,如果是你自己隨便定義的key,是無法正常獲取到數(shù)據(jù)的。
2.通過keyChain
我們知道NSUserDefault是把數(shù)據(jù)存儲(chǔ)在Libarary/Preferences目錄下,本質(zhì)上就是一個(gè)plist文件。所以有些敏感的數(shù)據(jù)我們最好不要用這種方式來共享。
Apple還提供了一個(gè)安全的數(shù)據(jù)保存方式,那就是KeyChain。通過KeyChain,我們可以共享一些敏感的數(shù)據(jù)比如說userid,token等。
@interface LHKeyChainTool : NSObject
#pragma mark - 存儲(chǔ)用戶偏好設(shè)置到NSUserDefults
+(void)saveUserData:(id)data forKey:(NSString*)key;
#pragma mark讀取用戶偏好設(shè)置
+(id)readUserDataForKey:(NSString*)key;
#pragma mark刪除用戶偏好設(shè)置
+(void)removeUserDataForkey:(NSString*)key;
@end
使用KeyChain的時(shí)候需要注意要打開KeychainSharing,并且添加相應(yīng)的Bundle Id

3. Pod文件
如果在APP里面使用CocoaPods來管理第三方庫,那么在Extension里面是無法直接使用這些文件的,哪怕你可以正常的#import,然后編譯器代碼提示正常,但是在編譯的時(shí)候會(huì)報(bào)找不到頭文件的錯(cuò)誤。
你可以在項(xiàng)目的podfile文件里面加入這句話:
link_with '宿主App的名字', '拓展App的名字'
然后執(zhí)行 pod update --no-repo-update 。如果你是使用了bundle,執(zhí)行 bundle exec update --no-repo-update
這樣就在宿主App和拓展App之間的建立了pod文件的連接。
但是當(dāng)你只想在Extension當(dāng)中引用APP的一個(gè)或其中幾個(gè)庫時(shí),這樣子的全部鏈接有些不合適,你可以這樣做:
target '宿主App的名字' do
pod ...
pod ...
pod ...
end
target '拓展App的名字' do
pod ...
end
這樣子就能在APP和Extension之間連接想要的庫
4.Assets.xcassets
如果在Extension當(dāng)中需要用到APP的某些資源圖片時(shí),我們不需要再次引用這些資源文件,在xcassets里面直接勾選想要共享的target就可以了

5.類文件
但是我們并不能通過共享資源的方式來實(shí)現(xiàn)類文件的共用。
如果你需要共享的文件不是太多,或者你就是想簡(jiǎn)單粗暴一點(diǎn),那就直接把相關(guān)的類文件拷貝一份到Extension當(dāng)中就可以了。
Apple推薦我們通過提取一個(gè)公共的framework的方式來優(yōu)雅的實(shí)現(xiàn)數(shù)據(jù)共享。

這樣子也可以讓你的代碼更有調(diào)理,不會(huì)糟糕的互相嵌套import
制作framework的過程這里就不詳細(xì)展開了。