1.首先为应用程序注册通知:
不同的iOS版本注册推送通知的方式不同(目前分为: iOS 10及以上,iOS 8及以上和iOS8以下)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 // Xcode 8编译会调用
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) {
if (!error) {
NSLog(@"request authorization succeeded!");
}
}];
[[UIApplication sharedApplication] registerForRemoteNotifications];
#else // Xcode 7编译会调用
UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
#endif
} else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
UIUserNotificationType types = (UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge);
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
}
return YES;
}
2.用户同意后,会调用此程序,获取系统的deviceToken,应把deviceToken传给服务器保存,此函数会在程序每次启动时调用(前提是用户允许通知):
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"deviceToken = %@",deviceToken);
//TODO
//保存到本地并上传到服务器
}
3.收到推送消息后,进行响应的逻辑处理:
不同的iOS版本的回调函数不一样(目前分为:iOS10及以上和以下)
#pragma mark - iOS 10中收到推送消息
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
//1.前台运行 会调用的方法前台运行: 指的是程序正在运行中, 用户能看见程序的界面.iOS10会出现通知横幅, 而在以前的框架中, 前台运行时, 不会出现通知的横幅.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
NSLog(@"willPresentNotification:%@", notification.request.content.userInfo);
// 根据APP需要,判断是否要提示用户Badge、Sound、Alert
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}
//2.后台运行及程序退出 会调用的方法后台运行: 指的是程序已经打开, 用户看不见程序的界面, 如锁屏和按Home键.程序退出: 指的是程序没有运行, 或者通过双击Home键,关闭了程序.
// iOS 10: 点击通知进入App时触发,在该方法内统计有效用户点击数
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo);
completionHandler();
}
//3.静默推送通知 会调用的方法静默推送: iOS7以后出现, 不会出现提醒及声音.要求:推送的payload中不能包含alert及sound字段需要添加content-available字段, 并设置值为1例如:{"aps":{"content-available":"1"},"PageKey”":"2"}
//如果是以前的旧框架, 此方法 前台/后台/退出/静默推送都可以处理
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
completionHandler(UIBackgroundFetchResultNewData);
}
//iOS 10 以下 接受远程通知时,不管在前台.后台还是程序杀死都会调用此方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
completionHandler(UIBackgroundFetchResultNewData);
//前台运行
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
//TODO
}
//后台挂起时
else{
//TODO
}
//设置应用程序角标数为0
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
}
4.应用进入后台时,设置角标数(应用图标右上角小红点,未读消息数):具体情况另做处理,这里只是举例说明
-(void)applicationDidEnterBackground:(UIApplication *)application{
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:123;
}