iOS基础 - 实现APP的推送通知 |已弃用|
前言
1 - 推送通知,也被叫做远程通知,是在 iOS 3.0 以后被引入的功能。是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径。推送的新消息可能是一条信息、一项即将到期的日程或是一份远程服务器上的新数据
2 - 要实现推送通知这一目的,开发者必须通过 iOS Developer Program Portal 获得 SSL 证书。每个证书限用于一个程序,使用程序的 bundle ID 作为标识。证书有两种用途的:一种是针对用于开发和测试,另外一种针对发布产品
3 -(苹果推送通知服务 Apple Push Notification Service)APNS 提供了两项基本的服务:消息推送和反馈服务
产品接口:gateway.push.apple.com:2195
sandbox: gateway.sandbox.push.apple.com:219
② 反馈服务:可以得到针对某个程序的发送失败记录。开发者应该使用反馈服务周期性检查哪些设备收不到通知,不需要重复发送通知到这些设备
sandbox:feedback.push.apple.com:2196
产品接口:feedback.sandbox.push.apple.com:2196
Apple Push Notification 的工作机制
1 - 推送流程
① 首先是应用程序注册消息推送
② iOS 跟 APNS 要 deviceToken,应用程序接受 deviceToken
③ 应用程序将 deviceToken 发送给推送服务器(称作 Provider,就是我们的后台)
④ Provider 向 APNS 服务发送消息
⑤ APNS 服务将消息发送给 iPhone 应用程序
2 - 无论是 iPhone 客户端跟 APNS,还是 Provider 跟 APNS 都需要通过证书进行连接,整体推送流程大致分为三个阶段
第一阶段:推送服务器把要发送的消息、iPhone 的标识打包发给 APNS
第二阶段:APNS 在自身的已注册 Push 服务的 iPhone 列表中,查找有相应标识的 iPhone,并把消息发到 iPhone
第三阶段:iPhone 把发来的消息传递给相应的应用程序,并且按照设定弹出 Push 通知
开发正书 | 推送证书
1 - 制作推送证书
第一步:登录开发者帐号:IOS Provisioning 中选择或新建一个App Id,这里以 info.luoyl.iostest 为例
第二步:创建完后进入 App Id 列表可以看到新建的 App Id 默认是没有激活推送功能的。点击 Configure 链接进入推送功能激活页面
第三步:在 Enable for Apple Push Notification service 选项上打勾,然后在行点 configure 按钮
第四步:此时会弹出一窗口,点击 continue
第五步:在弹出证书上传页面,证书选择事先做好的 CertificateSigningRequest.certSigningRequest 然后点击 Generate 按钮
第六步:接下来会有 Your APNs SSL Certificate has been generated 提示,点击 continue
第七步:下载刚生成的证书 aps_development.cer
第八步:至此 App Id 的 Development Push SSL Certificate 已经变成 Enabled 状态
2 - 制作开发证书
第一步:App Id 指定为 info.luoyl.iostest , 下载后双击安装到电脑上
第二步:双击下载好的推送文件 aps_development.cer 安装到 keychain Access 上
第三步:选中 Push Services 证书,右键导出证书为 个人信息交换(.p12)格式文件,这里命名为 aps_development.p12。点存储时会弹出一个密码设置窗口,可留空不填
第四步:在终端执行下面的命令,把刚才导出的 个人信息交换(.p12)格式文件 加密转换成推送服务器的推送证书
openssl pkcs12 -clcerts -nokeys -out cert.pem -in aps_development.p12 openssl pkcs12 -nocerts -out key.pem -in aps_development.p12 openssl rsa -in key.pem -out key.unencrypted.pem cat cert.pem key.unencrypted.pem > iostest_push_dev.pem
上面的命令在执行时有 4 处是需要输入密码的:其中 1 和 2 直接回车;3 是必须设定一个 key ,比如 push ,那么在 4 处输入 3 设定的 key 值 push
第五步:命令执行完后生成的 iostest_push_dev.pem 就是我们推送服务器要使用的推送证书(经过以上步骤的配置,就完成了开发推送功能所需要的条件)
第六步:代码实现。接下来将会新建一个 iOS 应用来体验完成推送功能
在代码方面,推送的注册、监听和处理都集中在 AppDelegate 中
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{ self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; self.viewController = [[[ViewController alloc] init] autorelease]; self.window.rootViewController = self.viewController; [self.window setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"background.png"]]]; [self.window makeKeyAndVisible]; /** 注册推送通知功能*/ [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; // 判断程序是不是由推送服务完成的 if (launchOptions) { NSDictionary* pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; if (pushNotificationKey) { UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"推送通知" message:@"这是通过推送窗口启动的程序,你可以在这里处理推送内容" delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil]; [alert show]; [alert release]; } } return YES; }
接收从苹果服务器返回的唯一的设备 token
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString* token = [NSString stringWithFormat:@"%@",deviceToken]; NSLog(@"apns -> 生成的devToken:%@", token); // 把 deviceToken 发送到我们的推送服务器 // DeviceSender 是自己的文件 DeviceSender *sender = [[[DeviceSender alloc]initWithDelegate:self ] autorelease]; [sender sendDeviceToPushServer:token ]; }
接收注册推送通知功能时出现的错误,并做相关处理
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSLog(@"apns -> 注册推送功能时发生错误, 错误信息:\n %@", err); }
接收到推送消息,解析处理
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"\napns -> didReceiveRemoteNotification,Receive Data:\n%@", userInfo); // 把 icon 上的标记数字设置为 0 application.applicationIconBadgeNumber = 0; if ([[userInfo objectForKey:@"aps"] objectForKey:@"alert"]!=NULL) { UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"**推送消息**" message:[[userInfo objectForKey:@"aps"] objectForKey:@"alert"] delegate:self cancelButtonTitle:@"关闭" otherButtonTitles:@"处理推送内容",nil]; alert.tag = alert_tag_push; [alert show]; } }
通过上面的代码,基本推送功能就已经完成