這兩天借著排查“添加的Local Notification到點(diǎn)沒有提醒”的機(jī)會(huì)衡怀,對Local Notification, Remote Notification以及相關(guān)API做了一個(gè)梳理,發(fā)現(xiàn)“別有洞天”。
在iOS 8以前裁眯,蘋果只提供了一個(gè)API來獲取關(guān)于通知相關(guān)的東東,[[UIApplication sharedApplication] enabledRemoteNotificationTypes]冰悠,
The values in the returned bit mask indicate the types of notifications currently enabled for the app. These types are first set when the app calls the registerForRemoteNotificationTypes: method to register itself with Apple Push Notification service. Thereafter, the user may modify these accepted notification types in the Notifications preference of the Settings app. This method returns those initial or modified values.
官方文檔中說姓惑,它的值取決于之前用registerForRemoteNotificationTypes注冊Remote Notification時(shí)所設(shè)定的types,同時(shí)也會(huì)根據(jù)用戶通知中心中的設(shè)定而變更按脚,也就是說于毙,enabledRemoteNotificationTypes同時(shí)會(huì)反映這兩種情況。但在實(shí)際測試中辅搬,發(fā)現(xiàn)只要registerForRemoteNotificationTypes注冊成功并生成用于發(fā)送PUSH的token唯沮,不論通知中心中app的設(shè)置如何變化(開啟通知、關(guān)閉通知堪遂、單獨(dú)開啟聲音介蛉、單獨(dú)關(guān)閉提醒等),enabledRemoteNotificationTypes的值都不會(huì)改變溶褪,嚴(yán)格等同于之前調(diào)用registerForRemoteNotificationTypes時(shí)設(shè)定的入?yún)⒈揖伞_@就意味著,只要注冊成功過Remote Notification一次猿妈,后續(xù)無論用戶如何調(diào)整app的通知設(shè)定吹菱,enabledRemoteNotificationTypes的返回值都是一樣的。
這個(gè)“特性”彭则,對于Remote Notification可能還好鳍刷,因?yàn)楫吘褂|發(fā)PUSH是在服務(wù)端,在發(fā)送的時(shí)候俯抖,也無法得知本地客戶端的用戶設(shè)置输瓜,但對于Local Notification來說,這就是“致命”的芬萍,因?yàn)楦鶕?jù)它開發(fā)者無法判斷用戶是否允許Local Notification尤揣,這也就是文章開頭“添加的Local Notification到點(diǎn)沒有提醒”的原因,因?yàn)楝F(xiàn)有的判斷是根據(jù)enabledRemoteNotificationTypes柬祠,而它又返回了全部3個(gè)type芹缔,但其實(shí)這時(shí)用戶已經(jīng)關(guān)閉了app的通知。
幸好蘋果在iOS 8上解決了這個(gè)問題瓶盛,引入了新的機(jī)制最欠,把用戶授權(quán)App使用本地/遠(yuǎn)程通知與Remote Notification成功注冊并生成token分離開來示罗,前者用[[UIApplication sharedApplication] registerUserNotificationSettings:]來實(shí)現(xiàn),后者通過[[UIApplication sharedApplication] registerForRemoteNotifications]與AppDelegate的[application:didRegisterUserNotificationSettings:]回調(diào)來達(dá)到芝硬,并引入了[[UIApplication sharedApplication] currentUserNotificationSettings]蚜点,來同步返回用戶在通知中心中的設(shè)定狀態(tài)。
最后拌阴,很有意思的是绍绘,在兩個(gè)版本中,當(dāng)App在后臺時(shí)迟赃,通知中心中此App的設(shè)定值都會(huì)影響到Local Notification是否以及如何被顯示陪拘,而當(dāng)在App在前臺時(shí),無論通知中心中的設(shè)置如何纤壁,Local Notification總是同樣地進(jìn)行顯示左刽。