背景:最近連續幾周被項目中的APNS實現所折騰,服務器和客戶端都存在坑,服務器升級導致一堆bug,修復完后客戶端這邊收到消息通知但是不符合業務邏輯,在項目經理再三溝通和協調的下,在服務器和客戶端同事們的全力排查代碼邏輯終于完成此功能點。
一、實現原理:
蘋果推送的實現原理就是有一個觸發者(服務器)觸發用戶關聯信息,通過APNs精確傳遞到用戶的設備上,具體以消息推送的形式呈現出來。
二、項目實踐
1、客戶端項目配置
在項目對應target欄目中capabilities的Push Notifications打開。
在項目對應target欄目中General Signing(release)選擇你要發布的證書
2、 客戶端代碼
在AppDelegate.m文件中需要做如下配置
2.1注冊遠程推送
這里需要兼容iOS10、iOS8、iOS8以下系統注冊遠程推送
-(void)registerForRemoteNotification
{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
#ifdef __IPHONE_10_0
//進行用戶權限的申請
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionBadge|UNAuthorizationOptionSound|UNAuthorizationOptionAlert|UNAuthorizationOptionCarPlay completionHandler:^(BOOL granted, NSError * _Nullable error) {
//在block中會傳入布爾值granted,表示用戶是否同意
if (granted) {
//如果用戶權限申請成功,設置通知中心的代理
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
}
}];
#endif
}
UIApplication *application = [UIApplication sharedApplication];
if([application respondsToSelector:@selector(registerUserNotificationSettings:)]){
UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
}
#if !TARGET_IPHONE_SIMULATOR
//ios8 注冊APNS
if ([application respondsToSelector:@selector(registerForRemoteNotifications)]){
[application registerForRemoteNotifications];
}else{//ios8以下
UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
}
#endif
}
2.2注冊遠程推送返回代理
注冊遠程推送成功
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
將注冊成功的deviceToken 注冊到推送服務器中,可以獲取到一個唯一的標志碼
注冊遠程推送失敗
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
將error 傳給相關模塊執行再次申請注冊遠程推送
2.3獲取到遠程推送的幾個場景
需要兼容IOS 7以及IOS7以上系統
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
#ifdef __IPHONE_7_0
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler
?其中userInfo是由推送服務器發的內容
aps =? ? {
alert = "sdhsflsflsaksakaskgkasglkasdjglkadsglknasdgdksal";//推送內容
badge = 3;//應用右上角數字
sound = "msg.mp3";//推送的聲音
};
//一下是服務器自定義的json數據格式
}
/*__IOS_AVAILABLE(10.0)? 必須使用xcode8
App在前臺的時候收到推送執行的回調方法*/
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
/*__IOS_AVAILABLE(10.0)? 必須使用xcode8
App在后臺的時候,點擊推送信息,進入App后執行的 回調方法*/
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
業務邏輯就是將收到的遠程推送的內容(自定義字段表示內容)展現在該app中。
三、總結
所謂總結就是分享我自己從這個坑里爬出來的感受
我所負責的app有兩個推送模式,遠程推送和本地IM推送,我負責遠程推送,他負責本地IM消息管理,其實推送devicetoken已經在IM那邊已經注冊了,但是我還重復注冊了一次,因為我之前的項目沒有集成IM,所以就順理成章按照之前的做法做了,得到的結果就是我可以收到遠程推送,就是我同事負責的消息管理模塊沒有任何關于我遠程推送的消息記錄,后來經過調試發現遠程推送和本地推送的標識碼不一樣,解決方法是以IM注冊為主,遠程推送和本地消息管理共用一個標識碼進行業務上操作。
其實這個問題本身不是一個很大的問題,關鍵在于開發人員雙方溝通不夠順暢,當時項目經理開了一個電話會議后將所涉及的開發人員召集在一起全力解決。
代碼實現結果其實是團隊溝通成效的體現。
參考文獻
1.《APNs Overview》https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//apple_ref/doc/uid/TP40008194-CH8-SW1
2.《Maintaining Your Signing Identities and Certificates》https://developer.apple.com/library/content/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html
3.《Payload Key Reference》https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html#//apple_ref/doc/uid/TP40008194-CH17-SW1
4.《手把手教你配置蘋果APNS推送服務》https://my.oschina.net/hejunbinlan/blog/494721