iOS Notification – 远程通知
本文讲解iOS
的远程通知的基本使用,主要包括远程通知的类型,处理远程通知的场景,以及远程通知相关证书的配置等等。
APNs
是苹果公司提供的远程通知的服务器,当App
处于后台或者没有运行时,如果后台需要发送通知,那么就需要借助APNs
服务器。在App
接收通知的过程中,通知的发送路径是:
Provider
-> APNs
服务器 -> iPhone
-> App
其中,Provider
和APNs
之间有一个TLS
连接,Provider
通过该连接将远程通知发送到APNs
服务器;iPhone
与APNs
之间也有一个TLS
连接,APNs
将远程通知通过该连接发送给iPhone
,进而通知用户某App
有新通知。
iPhone
与APNs
连接图如下:注意:
APNs
服务器只需维持一条连接。Provider
与APNs
连接图如下:注意:
App
的 bundle ID
唯一确定Provider certificate
需要通过开发者账号申请生成,其中包含 App
的 bundle ID
APNs
工作流程注意:
APNs
服务器注册当前 App
,APNs
会返回一个 Token
(注意这个过程要求App
有合法的证书,需要包含推送功能的证书);注意不同应用在同一设备上获取的 Token
不同,同一应用在不同设备上获取的 Token
也不同,所以 Token
是跟设备与 App
唯一绑定的App
拿到 Token
后需要将其发送给 Provider
Provider
发送推送通知时,指定 Token
和通知内容,并发送给 APNs
服务器APNs
服务器会将通知发送给 Token
对应的设备上APNs
发过来的通知中带有的 bundle ID
信息区分是哪个App
的远程通知(这里应该是根据 Token
来获取 bundle ID
)Feedback
是 APNs
服务器提供的用于减少服务器压力以及优化网络的服务,工作流程图如下:
注意:
Provider
发送一个远程通知给 APNs
服务器,APNs
服务器会检测目的设备是否在线,如果不在线,那么 APNs
服务器会暂存该消息APNs
会发送暂存的消息给目的设备(按照苹果官方说法暂存消息只会暂存最后一条消息,之前的消息会被丢弃);APNs
消息会把该设备加入 feedback
名单。Provider
可以定期去 APNs
拉新 feedback
名单;Provider
再次给之前的设备发送远程通知时,需要检查一下 feedback
名单,如果设备在这个名单,则不再发送给 APNs
了;Provider
可以再将此设备移除feedback
名单,当 Provider
更新 feedback list
后,就可以重新给该设备发送远程通知了。当然,feedback list
的更新可能会有周期,如果需要及时有效的更新 feedback list
,那么需要 App
打开后,及时通知 Provider
;APNs
服务器的压力,另一方面也可以减少网络流量假定已经有开发证书的情况,下面只介绍配置推送证书的步骤
App ID
Provisioning Profiles
远程通知具体可分为普通远程通知和静默远程通知
收到通知后,有文字和声音,点击通知会进入App
,然后执行如下方法
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
收到通知后,没有文字和声音,不用点开通知,也不用打开App
,就能执行如下方法
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
静默通知注意点:
aps
数据中一定要加"content-available" : 1
alert
,如果加入了alert
就不是静默推送了sound
和 badge
也不能加 if (DEF_IOS10) {
// iOS 10
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
NSLog(@"greet");
} else {
NSLog(@"reject");
}
}];
} else if (DEF_IOS8) {
// iOS 8 和 iOS 9
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
// iOS 7
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound];
}
iOS9以后,每次重新安装应用后得到的 Token
是不一样的,而且每次重装系统也会改变,所以 每次应用启动时都需要按上面的步骤注册一次
application:didRegisterForRemoteNotificationsWithDeviceToken:
在这个方法里把deviceToken
发送给服务器Provider
应用在前台
-(void) application: didReceiveRemoteNotification:
-(void) application: didReceiveRemoteNotification: fetchCompletionHandler:
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler
应用在后台,但是还活着
iOS6 ~ iOS9 调用方法和应用在前台相同
iOS10
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler
应用被杀死状态
这种情况和应用重新启动类似,应用会调用下面的方法重新启动
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
其中,通知的信息在launchOptions
里,
id userInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
参考资料
http://www.jianshu.com/p/ad43bc1a970a
http://www.tuicool.com/articles/AFRvemV
http://blog.csdn.net/hherima/article/details/47133171