前言:網(wǎng)上一搜這個關鍵詞【UNNotificationServiceExtension】敞恋,一片片的教程胃珍。但是每一個都特么轉(zhuǎn)載自【徐不同】耐薯,窩草,毫無更改徐许。只想淡淡吐槽一句MMPJ┟邸!
本文說的一種app和extension的通信問題雌隅。
需求:需要統(tǒng)計推送到達率翻默。再extension中進行數(shù)據(jù)上報處理操作缸沃。廢話不多提開始操作。
1修械、新建target(網(wǎng)上一坨趾牧,這里不贅述了)
2、斷點調(diào)試?衔邸G痰ァ!
這個問題MMP困擾了我好長時間蹦渣。
1運行app
2【Xcode】——【Debug】——【Attach to Process PID or Name】添加新建的target名字 如圖1.0,添加之后會出現(xiàn)NotificationService Waiting to Attach
如圖2.0
3 點擊工程哄芜,選擇target運行 如圖3.0
4 選擇自己的宿主app 如圖4.0
3、證書問題
NotificationService自動簽名柬唯,但代碼簽名身份iPhone開發(fā)人員:xxxxx已手動指定认臊。在build settings編輯器中為“iPhone開發(fā)人員”設置代碼簽名標識值,或者在項目編輯器中切換到手動簽名锄奢。
方法1 點擊Automatically manage siging 系統(tǒng)會幫你生成一個證書
方法2 app總會上架失晴,還是自己新建證書為好。手把手教你推送證書
4斟薇、用工具進行推送測試
工具1:SmartPush
工具2:Easy APNS Provider
推送格式:
{
"aps": {
"alert": "This is some fancy message.",
"badge": 1,
"sound": "default",
"mutable-content": "1",
"imageAbsoluteString": "http://upload.univs.cn/2012/0104/1325645511371.jpg"
}
}
這里我們要注意一定要有"mutable-content": "1",以及一定要有Alert的字段师坎,否則可能會攔截通知失敗。(蘋果文檔說的)堪滨。
打個斷點胯陋,可以調(diào)試了!8は洹遏乔!
怎么通信呢?
在app Podfile里加入target 與app同級
target 'NotificationService' do
pod 'xxx'
end
但是我引用的庫中使用了 [UIApplication sharedApplication]
extexsion中是不允許這樣使用的发笔、
怎么辦盟萨?只能換方式
在默認情況下,iOS的應用是存在一個沙盒里面的了讨,不允許應用與應用直接進行數(shù)據(jù)的交互捻激。為此,蘋果提供了一項叫App Groups的服務前计,該服務允許開發(fā)者可以在自己的應用之間通過NSUserDefaults胞谭、NSFileManager或者CoreData來進行相互的數(shù)據(jù)傳輸。
下面介紹如何激活App Groups服務:
-
首先要有一個獨立的AppID(帶通配符*號的AppID是不允許激活App Groups的)
然后打開容器應用的項目配置的Capabilities頁簽男杈,激活App Groups特性丈屹,如圖:
- 點擊+號添加一個App Groups,點擊OK按鈕
- 創(chuàng)建完成后伶棒,XCode會自動把應用添加到新建的分組中旺垒。如圖:
- 上述步驟完成后彩库,容器程序的App Groups已經(jīng)算是設置完成。然后輪到Share Extension插件需要激活App Groups服務先蒋,設置步驟跟容器程序相同骇钦,唯一不同的是,插件不需要創(chuàng)建新的App Group竞漾,只要加入到容器程序剛才創(chuàng)建的Group即可(這里可以理解為司忱,哪些應用要實現(xiàn)共享數(shù)據(jù),那么他們必須在同一個Group里面)畴蹭。如圖:
至此,應用和擴展的App Groups服務都已經(jīng)啟動鳍烁,現(xiàn)在就要進行分享內(nèi)容的傳輸操作叨襟。下面分別介紹一下NSUserDefaults、NSFileManager以及CoreData三種方式是如何實現(xiàn)App Groups下的數(shù)據(jù)操作:
-
NSUserDefaults
:要想設置或訪問Group的數(shù)據(jù)幔荒,不能在使用standardUserDefaults方法來獲取一個NSUserDefaults對象了糊闽。應該使用initWithSuiteName:方法來初始化一個NSUserDefaults對象,其中的SuiteName就是創(chuàng)建的Group的名字爹梁,然后利用這個對象來實現(xiàn)右犹,跨應用的數(shù)據(jù)讀寫,代碼如下:
//初始化一個供App Groups使用的NSUserDefaults對象
NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.cn.vimfung.ShareExtensionDemo"];
//寫入數(shù)據(jù)
[userDefaults setValue:@"value" forKey:@"key"];
//讀取數(shù)據(jù)
NSLog(@"%@", [userDefaults valueForKey:@"key"]);
-
NSFileManager
:通過調(diào)用 containerURLForSecurityApplicationGroupIdentifier:方法可以獲得AppGroup的共享目錄姚垃,然后在此目錄的基礎上實現(xiàn)任意的文件操作念链。代碼如下:
//獲取分組的共享目錄
NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.cn.vimfung.ShareExtensionDemo"];
NSURL *fileURL = [groupURL URLByAppendingPathComponent:@"demo.txt"];
//寫入文件
[@"abc" writeToURL:fileURL atomically:YES encoding:NSUTF8StringEncoding error:nil];
//讀取文件
NSString *str = [NSString stringWithContentsOfURL:fileURL encoding:NSUTF8StringEncoding error:nil];
NSLog(@"str = %@", str);
- CoreData:其實CoreData是基于NSFileManager取得共享目錄后來實現(xiàn)數(shù)據(jù)共享的。即在初始化CoreData時积糯,先使用NSFileManager取得共享目錄掂墓,然后再指定共享目錄為存儲數(shù)據(jù)文件的目錄(如存儲的sqlite文件)。代碼如下:
//獲取分組的共享項目
NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.cn.vimfung.ShareExtensionDemo"];
NSURL *storeURL = [containerURL URLByAppendingPathComponent:@"DataModel.sqlite"];
//初始化持久化存儲調(diào)度器
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
[coordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeURL
options:nil
error:nil];
//創(chuàng)建受控對象上下文
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[context performBlockAndWait:^{
[context setPersistentStoreCoordinator:coordinator];
}];
我使用的是NSUserDefault
然后在app中- (void)applicationDidBecomeActive:(UIApplication *)application
中進行數(shù)據(jù)的讀取看成。