iPhone 对于应用程序在后台运行有诸多限制(除非你越狱)。因此,当用户切换到其他程序后,原先的程序无法保持运行状态。对于那些需要保持持续连接状态的应用程序(比如社区网络应用),将不能收到实时的信息。
为解决这一限制,苹果推出了APNs(苹果推送通知服务)。APNs 允许设备与苹果的推送通知服务器保持常连接状态。当你想发送一个推送通知给某个用户的iPhone上的应用程序时,你可以使用 APNs 发送一个推送消息给目标设备上已安装的某个应用程序。
本文中,你将学到创建使用 APNs 的iOS 应用的详细步骤。
创建证书请求
使用APNs 的第一步是生成一个证书请求,使用该证书请求来申请一个用于开发的 SSL 证书。
1.打开“钥匙串访问”应用程序。
2.选择“KeychainAccess -> Certificate Assistant -> Request a Certificate From CertificateAuthority”(如图1 所示):
3.输入所需的信息,勾选“Saved to disk”选项,点击 Continue(如图2 所示):
4.使用默认文件名把证书请求进行保存(图3):在弹出窗口中,点击Done。
创建 App ID
每个使用 APNs 的 iOS 应用必须有一个唯一的 App ID。在本步骤中,你将学到如何创建推送通知中要用到的App ID。
1.登录iPhoneDeveloper Program:http://developer.apple.com/iphone/。点击页面右边的“
iPhone Developer Program Portal ”(图4):
2.首先看到的是欢迎页面(图5):
3.点击左边的“App ID”,然后点击右边的“New App ID”按钮(图6):
4.在 Description 栏输入“PushAppID”,在“Bundle Seed ID”栏中选择“Generate New”。在“Bundle Identifier”栏,输入“net.learn2develop.MyPushApp”,然后点击“Submit”(图7):
5.现在你应该能看到所创建的 App ID 了(图8):
配置 App
一旦创建了 App ID,你还要为推送通知对 App ID 进行一些配置。
1.点击App ID 右边的 Configure 链接,会看到如下选项(图9):
勾选“Enable for Apple Push Notificationservice”,点击“Development Push SSL Certificate”右边的“Configure”按钮。
2.接下来你会看到“Apple Push Notification service SSL Certificate Assistant”页面。点击Continue(图10):
3.点击Choose File 按钮,选择前面保存的证书请求文件存放地址。点击 Generate(图11):
4.你的SSL 证书会被生成。点击 Continue(图12):
5.点击Download Now 按钮,下载 SSL 证书。点击 Done(图13):
6.下载的 SSL 证书文件名为 aps.developer.identity.cer。双击,将证书安装到钥匙串中(图14)。这个证书会在你的程序中用到,它允许程序接收 APNs 发送来的推送通知。
创建 Provisioning Profile
接下来,需要创建 provisioning profile 以便允许应用程序安装到真实设备上。
1.回到iPhone Development Program Portal,点击 Provisioning 栏,点击 New Profile 按钮(图15):
2.Profile Name 栏输入 MyDevicesProfile,在 App ID 栏选择 PushAppID。在Devices 栏,勾选所有你想激活的设备(在 iPhone Developer Program Portal 的 Devices 页中注册的所有设备)。点击 Submit(图16)。
3.provisioning profile 会等待审核。几秒钟后,它会显示在页面上。点击Download 按钮下载该 provisioning profile(图17):
4.下载下来的provisioning profile 名为 MydevicesProfile.mobileprovision。
激活设备
创建 provision profile 后,你可以将它安装到真实设备中。
1.将iPhone 或 iPod 连接到 Mac。
2.把下载下来的 MyDevicesProfile.mobileprovision 文件拖到Dock 栏的 Xcode 图标上。
3.Xcode 的 Organizer 程序将启动,选择当前连机的设备。可以看到MyDevicesProfile 已自动安装到设备上了(图18)。
创建 iPhone 应用程序
1.打开Xcode,创建 View-Based Application 项目,命名为 ApplePushNotification。
2.把一个 WAV 文件(本例是 beep.wav)拖到Xcode 的 Resouces 文件夹(图19)。
3.展开Xcode 中的 Targets 项目,选择ApplePushNotification,按下 ⌘+i,在 info 出口,点击Properties 标签栏(图20):
在 Identifier 文本框,输入net.learn2develop.MyPushApp.
4.点击 Build 标签栏,在 search 输入框中键入Code Signing。在 Any iPhone OS Device 选项,选择正确的 profile(图21):
5.在 ApplePushNotificationAppDelegate.m 文件中,输入以下代码(加粗部分):
#import "ApplePushNotificationAppDelegate.h"
#import "ApplePushNotificationViewController.h"
@implementation ApplePushNotificationAppDelegate
@synthesize window;
@synthesize viewController;
- (void)applicationDidFinishLaunching:(UIApplication*)application {
[window addSubview:viewController.view];
[window makeKeyAndVisible];
NSLog(@"Registeringfor push notifications...");
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes:
(UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
}
- (void)application:(UIApplication*)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString*str
= [NSString
stringWithFormat:@"Device Token=%@",deviceToken];
NSLog(str);
}
- (void)application:(UIApplication*)appdidFailToRegisterForRemoteNotificationsWithError:(NSError*)err
{
NSString*str
= [NSStringstringWithFormat:
@"Error: %@", err];
NSLog(str);
}
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
for (id key in userInfo) {
NSLog(@"key: %@, value: %@", key, [userInfo objectForKey:key]);
}
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
6. 按下 ⌘+R 运行程序(在真实设备)。按下 shift+⌘+R 显示Debugger Console 窗口。查看设备输出到控制台的 device token(图22)。在下图,device token 是 38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7c e90d56e9fe145bcc 6c2c594b。记下device token(复制、粘贴到一个文本文件里)
7. 如果查看 iPhone/iPod 上的“Settings”程序,你会发现一个 Notifications 的项(图23):
创建 Push Notification Provider
Push Notification Provider 是一个应用程序,用于通过 APNs 发送推送通知给 iPhone 应用。
通过 APNs 发送推送通知有几个步骤:
1.使用前面创建的 SSL 证书与 APNs 通讯;
2.构造所要发送的消息载体;
3.发送载体到APNs;
APNs 是一个基于流的 TCP socket,你的 provider 以 SSL 协议与其通讯。推送通知(包括载体)是以二进制流的方式发送的。和APNs 建立连接后,你可以维持该连接并在连接中断之前发送多个通知。
技巧: 应避免每发送一次推送通知就建立、关闭一次连接。频繁的建立、关闭连接可能会被 APNs 认为是 DOS 攻击,从而拒绝发送 provider 的推送通知发送请求。
一个推送通知消息的格式如图24 所示:
更多细节,请参考Apple
Push Notification Service Programming Guide。
载体(payload)是 JSON 字符串(最长 256 字节),封装了你发送给 iOS 应用的信息。这是一个 payload 的例子:
{
"aps": {
"alert" : "Yougot a new message!" ,
"badge" : 5,
"sound" : "beep.wav"},
"acme1" : "bar",
"acme2" : 42
}
写provider之前,我们需要生成php Push Notification sender需要的证书文件:
1)在Keychain Access.app里选定这个新证书(Apple Development Push Services*),导出到桌面,保存为Certificates.p12.
2)然后运行如下命令:
1. openssl pkcs12 -clcerts -nokeys -out cert.pem -in Certificates.p12
2. openssl pkcs12 -nocerts -out key.pem -in Certificates.p12
3. openssl rsa -in key.pem -out key.unencrypted.pem
4. cat cert.pem key.unencrypted.pem > ck.pem
下面是一个简单的push notification proivder写法:
-
<spanstyle="font-size:16px;"><?php
-
-
$deviceToken='38c866ddbb323b39ffa734875e157ee5a85e0b7ce90d56e9fe145bcc6c2c594b';
-
-
-
-
$message=$_GET['message']or$message=$argv[1]or$message='Messagereceivedfromjavacom';
-
$badge=(int)$_GET['badge']or$badge=(int)$argv[2];
-
$sound=$_GET['sound']or$sound=$argv[3];
-
-
$body=array();
-
$body['aps']=array('alert'=>$message);
-
if($badge)
-
$body['aps']['badge']=$badge;
-
if($sound)
-
$body['aps']['sound']=$sound;
-
-
-
$ctx=stream_context_create();
-
stream_context_set_option($ctx,'ssl','local_cert','ck.pem');
-
-
-
$fp=stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195',$err,$errstr,60,STREAM_CLIENT_CONNECT,$ctx);
-
if(!$fp){
-
print"Failedtoconnect$err$errstrn";
-
return;
-
}
-
else{
-
print"ConnectionOKn";
-
}
-
$payload=json_encode($body);
-
$msg=chr(0).pack("n",32).pack('H*',str_replace('','',$deviceToken)).pack("n",strlen($payload)).$payload;
-
print"sendingmessage:".$payload."n";
-
fwrite($fp,$msg);
-
fclose($fp);
-
?></span>
运行结果:Connection OKnsending message :{"aps":{"alert":"Message received from javacom"}}n
效果图在下面。
为了省去自己编写 push notification provider 的麻烦,你也可以使用 Stefan Hafeneger 写的一个 Mac OS X 应用程序:PushMeBaby,下载地址
1.在Xcode 中打开 PushMeBaby。
2.右击 Resouces 文件夹,选择 Add Existing Files…,选择前面所下载到的aps.developer.identity.cer 文件(图25)。
3.在 ApplicationDelegate.m 文件中,修改如下代码(加粗部分):
- (id)init {
self = [super init];
if(self != nil) {
self.deviceToken = @"38c866dd bb323b39 ffa73487 5e157ee5 a85e0b7ce90d56e9 fe145bcc 6c2c594b";
self.payload = @"{\"aps\":{\"alert\":\"Yougot a new message!\",\"badge\":5,\"sound\":\"beep.wav\"},\"acme1\":\"bar\",\"acme2\":42}";
self.certificate = [[NSBundlemainBundle]
pathForResource:@"aps_developer_identity" ofType:@"cer"];
}
return self;
}
4.按下 ⌘+R,运行程序。将会问你是否允许使用证书,点击Always Allow(总是允许)(图26):
在 iPhone/iPod,确认 ApplePushNotification 程序未运行。点击 Push 按钮,会向设备发送一条推送通知。服务器实际上发送了下列消息给APN 服务器:
{
"aps": {
"alert" : "Yougot a new message!" ,
"badge" : 5,
"sound" : "beep.wav"},
"acme1" : "bar",
"acme2" : 42
}
5.如果消息推送成功,将会在 iPhone/iPod 上出现下图(图27):
6.如果现在按下 ⌘+R 调试 ApplePushNotification 程序,然后从 PushMeBaby 中发送一条消息,控制台会显示如下输出:
2009-11-24 21:11:49.182 ApplePushNotification[1461:207]key: acme1, value: bar
2009-11-24 21:11:49.187 ApplePushNotification[1461:207]key: aps, value: {
alert = "You got a new message!";
badge = 5;
sound = "beep.wav";
}
2009-11-24 21:11:49.191 ApplePushNotification[1461:207]key: acme2, value: 42
几个注意的问题:
1.如果申请ssl 证书时不是用的新的apple id,而是原来已经存在的,那么设置好之后要把对应的provisioning profile
也更新一下, 然后去下载新的profile替换掉老的,不然运行会有错。
2.如果你用的是企业版的开发者证书,别人可能没有权限去申请这个ssl 证书,当你替他申请好证书后,应该把证书和证书对
的私钥一起发给他,这样他在本地安装私钥时才会有对应的密钥。
3.当push notification到达时,程序状态不同,效果也是不一样的,一般来说程序可以分为下面三种状态:
1)程序不在运行(后台和前台都不在运行)
这时候如果push notification到了,会弹出一个alertview,当你点击action按钮时,会启动程序,并执行程序delegate.m文件里的
-
-(BOOL)application:(UIApplication*)applicationdidFinishLaunchingWithOptions:(NSDictionary*)launchOptions
方法,所以你可以在这里做一些处理:
-
-
UILocalNotification*remoteNotification=[launchOptionsobjectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
-
if(remoteNotification){
-
-
UIAlertView*al=[[UIAlertViewalloc]initWithTitle:@"receiveremotenotification!"message:@"hello"delegate:selfcancelButtonTitle:@"Ok"otherButtonTitles:nil,nil];
-
[alshow];
-
[alrelease];
-
}
2)程序在运行(不论是在前台还是后台)
当push notification到达时,如果程序在前台运行并不会弹出alertview,而是直接执行下面方法:
-
-
-
-
-(void)application:(UIApplication*)applicationdidReceiveRemoteNotification:(NSDictionary*)userInfo{
-
-
UIAlertView*al=[[UIAlertViewalloc]initWithTitle:@"receiveremotenotification!"message:@"hey"delegate:selfcancelButtonTitle:@"ok"otherButtonTitles:nil,nil];
-
[alshow];
-
[alrelease];
-
}
在这个方法里你可以获取到userInfo字典来进行相应处理。
如果程序是在后台运行,则会弹出一个alertview,当你点击action按钮,也会执行上面一样的方法。
所以如果你想要程序在push notification到达时,针对前台和后台运行做区分处理,你可以在上面方法里先做一个状态的
判断:
-
-
UIApplicationStatestate=[applicationapplicationState];
-
if(state==UIApplicationStateInactive){
-
-
-
-
}
分享到:
相关推荐
APNS(英文全称:Apple Push Notification Service),中文翻译为:苹果推送通知服务,该技术由苹果公司提供的APNS服务,下面是一个比较完善的苹果推送通知服务的php服务器端公共类.
苹果推送服务APNS通过C#实现的后台,服务器端源码。应用于IOS提供的移动端推送服务。便于开发者与用户端即时沟通讯息
iOS苹果推送apns测试工具
Java APNS推送消息 HTTP/2协议, 基于JDK 11及以上
java依赖+整合代码工具类示例
苹果推送项目源码,运行即用 语言:JAVA,开发IDE:eclipse 数据库:MYSQL 运行即用,附带API调用文档 超级硬通货,想不使用第三方苹果消息推送的千万不要错过
libcapn, 用于与Apple推送通知服务( APNs ) 交互的简单C 库 libcapn libcapn是一个与苹果推送通知服务的C 库,使用简单直观的API 。 通过该库,你可以轻松地向iOS和 OS X (> = 10.8 ) 设备发送推送通知。版本 2.0与 ...
java实现苹果推送 里面有两个方法实现推送
主要介绍了C#推送信息到APNs的方法,涉及C#推送通知到苹果APNs的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
自己用java实现苹果的apns推送,调用压缩包的text文件里面的方法即可
iphone 推送通知 服务器端java 实现 iphone 推送通知 APNS 包含所需jar包和实现代码
APNS(Apple Push Notification Service)苹果推送通知服务。该技术由苹果公司提供的APNS服务。工作原理:首先,APNS会对用户进行物理连接认证,和设备令牌认证(简言之就是苹果的服务器检查设备里的证书已确定其为...
关于IOS_APNS推送消息(iphone端+服务端)。关于IOS_APNS推送消息(iphone端+服务端)。
苹果最新技术apns推送!!C#代码!和数据库 VS2008+sql2008
苹果推送消息服务调试应用 Knuff ,Knuff 是 APNs(Apple Push Notification Service,苹果信息推...
用https实现iphone消息推送,短连接形式 有问题,请留言
基于netty4实现的苹果通知推送服务Java客户端。 特点: 支持第三版通知推送,即command = 2。目前的绝大部分Java客户端都只支持command = 1,即第二版。 支持SSL握手成功才返回,可以调用 ...
用于在iOS上实现APNS推送通知并在Android上实现Firebase的插件。 为什么制作此插件? 当前,唯一可用的推送通知插件是firebase_messaging 。 这意味着,即使在iOS上,您也需要设置Firebase并与Google通信以发送推...
PushServer 是一个 Node.js 的服务器用来发送苹果的 APNS 推送通知。 标签:PushServer