远程推送通知 UIRemoteNotification

远程推送通知在App中非常常见,如短信、QQ、微博、美团等等,很多产品都将它作为提醒用户、推送广告的一种手段。在iOS8之后,远程推送又上升了一个等级,可以在通知中心中做回复等交互操作。本文主要讲解如何使用基本的远程推送,测试时请使用真机。

由于远程推送将会涉及到网络请求、真机测试、证书导出、与远程推送有关的代码编写等操作,本文主要讲解代码编写方面,其他步骤,请看下列文章:

真机测试:http://www.saitjr.com/ios/ios-debugging.html

证书导出:http://www.saitjr.com/ios/ios-export-remote-notification-p12-pem-file.html

网络请求:http://www.saitjr.com/ios/ios-http-request-post-get.html

本文Demo下载地址:

https://github.com/saitjr/UIRemoteNotificationDemo.git


环境信息
Mac OS X 10.10.3
Xcode 6.3
iOS 8.3

正文:

先描述下操作步骤:

一、下载推送证书,注意勾选推送服务

?http://www.saitjr.com/ios/ios-debugging.html

二、导出推送文件给后台,根据后台需要的文件进行选择

http://www.saitjr.com/ios/ios-export-remote-notification-p12-pem-file.html

三、关键代码

  1. 关于远程推送,所使用到的是苹果的APNS服务,之所以能够推送到某一部手机,所用到的就是token值(token与证书和设备有关,某段时间内是唯一值,超出一定时间段会自动变更)。在程序启动时,可以获得设备token值,然后,将token值传给后台,需要使用到推送服务时,后台就会根据设备token推送。
  2. 注册与处理推送都需要在AppDelegate.m中进行。
  3. 注册推送

注册推送需要在程序结束启动时进行,在iOS8之后,新增了Extension,所以注册推送的方式变了,如果要进行系统版本适配,需要先判断,写法如下:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

// 先判断当前系统环境
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {

UIUserNotificationType notificationType = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:notificationType categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
} else {
// 在iOS8的编译环境下会有警告,因为这是iOS7的方法,iOS8弃用
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}

return YES;
}
  1. 注册推送成功后,获得设备token的代理方法

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{

//register to receive notifications
[application registerForRemoteNotifications];
}

// 注册推送成功后调用该方法
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

// 将token转换成string,一般会将token中的<>与空格去掉后传给后台
NSString *dvsToken = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

//============保存dvsToken===========================
NSString *formatToekn = [dvsToken stringByReplacingOccurrencesOfString:@" " withString:@""];

// 因为这个方法有一定的延迟,所以遇到程序启动,马上就需要使用token的情况,会将token存入本地,方便下一次使用时,快速获得
[[NSUserDefaults standardUserDefaults] setObject:formatToekn forKey:@"DeviceToken"]; //将dvsToken存入本地
}

// 注册推送失败
- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(NSError*)error {

NSLog(@"%@", error);
}
  1. 接收到推送的处理方法

// 接收到远程通知以后的处理
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

// 将应用的icon上,未读推送+1
application.applicationIconBadgeNumber ++;

// 取出后台推送过来的信息(取值方法一般都一样,这里只需要改处理方法)
if ([[userInfo objectForKey:@"aps"] objectForKey:@"alert"] != NULL) {

UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"] delegate:nil cancelButtonTitle:@"确认" otherButtonTitles:nil];
[alert show];
}
}

四、关于远程推送的注意事项

  1. 如果用户禁用了推送服务,那么App无法获得token;
  2. 设计程序时,不要将token作为设备的唯一标示,可使用UUID代替;
  3. 不要使用开发证书打包测试,开发证书打包出来拿到token不正确,无法进行推送。