首先,需要一个pem的证书,该证书需要与开发时签名用的一致。 具体生成pem证书方法如下:
1. 登录到 iPhone Developer Connection Portal(http://developer.apple.com/iphone/manage/overview/index.action ) 并点击 App IDs
2. 选择对应App ID。(开发与发布不一样的。需注意)
3. 点击App ID旁的“Configure”,然后按下按钮生产 推送通知许可证。根据“向导” 的步骤生成一个签名并上传,最后下载生成的许可证。
4. 通过双击.cer文件将你的 aps_developer_identity.cer 引入Keychain中。
6. 单机“Apple Development Push Services”,导出p12文件,保存为 apns-dev-cert.p12 文件。
7. 扩展“Apple Development Push Services” 对“Private Key”做同样操作,保存为 apns-dev-key.p12 文件。
8. 需要通过终端命令将这些文件转换为PEM格式:
openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns-dev-cert.p12
openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns-dev-key.p12
9. 如果你想要移除密码,要么在导出/转换时不要设定或者执行:
openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem
10. 最后,你需要将键和许可文件合成为apns-dev.pem文件,此文件在连接到APNS时需要使用:
cat apns-dev-cert.pem apns-dev-key-noenc.pem > apns-dev.pem
PHP后台写法:
<?
php
//
这里是我们上面得到的deviceToken,直接复制过来(记得去掉空格)//deviceToken 在测试版本和上线版本上不一样。 //lei ipod touch
$deviceToken = '06fe0a85056f6b9f07fb11a4eed962aaab824b9522660a8bb165b369717159ab'
;
//
Put your private key's passphrase here:
$passphrase = 'abc123456'
;
//
Put your alert message here:
$message = 'My first push test!'
;
//
//////////////////////////////////////////////////////////////////////////////
$message =
array('msg'=>'小小说阅读器','title'=>'小小说','url'=>' http://www.apple.com.cn'
);
//
$message = array('msg'=>'去商品详细页面','itemtype'=>'2','id'=>'192172'); //$message = array('msg'=>'去菜单页面','itemtype'=>'1','zktype'=>'1','order'=>'1','zksubtype'=>'1','zktitle'=>'9.9包邮'); //$message = array('msg'=>'软件升级');
$ctx =
stream_context_create
();
stream_context_set_option(
$ctx, 'ssl', 'local_cert', 'ck_dev.pem'
);
stream_context_set_option(
$ctx, 'ssl', 'passphrase',
$passphrase
);
//
Open a connection to the APNS server //这个为正是的发布地址 //$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); //这个是沙盒测试地址,发布到appstore后记得修改哦
$fp =
stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195',
$err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT,
$ctx
);
if (!
$fp
)
exit("Failed to connect:
$err
$errstr" .
PHP_EOL
);
echo 'Connected to APNS' .
PHP_EOL
;
//
Create the payload body
$body['aps'] =
array
( 'alert' => '逗你玩!哈哈。', 'sound' => 'beep.wav', 'badge' => 1
);
$body['type']=2
;
$body['data']=
$message
;
//
Encode the payload as JSON
$payload = json_encode(
$body
);
//
Build the binary notification
$msg =
chr(0) .
pack('n', 32) .
pack('H*',
$deviceToken) .
pack('n',
strlen(
$payload)) .
$payload
;
//
Send it to the server
$result =
fwrite(
$fp,
$msg,
strlen(
$msg
));
if (!
$result
)
echo 'Message not delivered' .
PHP_EOL
;
else
echo 'Message successfully delivered' .
PHP_EOL
;
//
Close the connection to the server
fclose(
$fp
); ?>
客户端代码:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *
)launchOptions{
self.window =
[[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
//
Override point for customization after application launch.
main =
[[MainViewController alloc] init];
navMain =
[[UINavigationController alloc] initWithRootViewController:main];
self.window.rootViewController =
navMain;
notifiDic =
[[NSMutableDictionary alloc] init];
[self initNotification];
[UIApplication sharedApplication].applicationIconBadgeNumber =
0
;
NSLog(
@"
launchOption==%@
"
,[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]);
if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey] !=
nil)
{
if (notifiDic.count !=
0
) {
[notifiDic removeAllObjects];
}
[notifiDic setDictionary:(NSDictionary *
)[launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
@"
didFinishLaunching
" message:[NSString stringWithFormat:
@"
didFinishLaunching:\n%@
",launchOptions]
delegate:self cancelButtonTitle:
@"
Cancek
"otherButtonTitles:
@"
OK
"
, nil];
[alert show];
alert.tag =
101
;
[alert release];
}
self.window.backgroundColor =
[UIColor whiteColor];
[self.window makeKeyAndVisible];
return
YES;、
}
- (
void
)initNotification{
[[UIApplication sharedApplication]registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert
|UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
}
#pragma mark
--(
void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *
)deviceToken{
NSLog(
@"
deviceToken: %@
"
, deviceToken);
NSLog(
@"
deviceToken===%@
"
,[deviceToken description]);
NSRange _range = NSMakeRange(
1,[[deviceToken description] length]-
2
);
NSString *deviceTokenStr =
[[deviceToken description] substringWithRange:_range]; NSLog(
@"
deviceTokenStr==%@
"
,deviceTokenStr);
deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:
@"
" withString:
@""
]; NSLog(
@"
deviceTokenStr==%@
"
,deviceTokenStr);
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:
@"
product deviceToken
" message:deviceTokenStr
delegate:nil cancelButtonTitle:
@"
OK
"
otherButtonTitles:nil, nil];
[ alertView show]; [alertView release]; }
- (
void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *
)userInfo{ NSLog(
@"
%s,,,,%@
"
,__func__,userInfo);
if (notifiDic.count !=
0
) { [notifiDic removeAllObjects];
}
[notifiDic setDictionary:userInfo];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:
@"" message:[NSString stringWithFormat:
@"
受到的通知如下:\n%@
",userInfo]
delegate:self cancelButtonTitle:
@"
Cancel
" otherButtonTitles:
@"
OK
"
, nil]; [alert show]; alert.tag =
100
; [alert release];
}
- (
void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *
)err {
NSLog(
@"
%s
"
,__func__);
}
注意点:
1.推送证书都弄好后,项目的开发证书要重新下载一下。
1.反馈服务
Apple 还提供了一个 反 馈服务 ,你应该定期查询。它提供了一个以前使用过但不再有效的(例如用户卸载了你的iPhone程序)设备令牌列表。你可以从你的数据库中删除这些设备令牌。
本教程不涉及反馈服务的使用。
2.创建载荷
使用 PHP 很容易根据数组并 转 换成 JSON而创建载荷:
$payload['aps'] = array('alert' => 'This is the alert text', 'badge' => 1, 'sound' => 'default');
$payload = json_encode($payload);
显示 $payload 的内容可以看到传送到APNS 的 JSON字符串:
{
"aps" : { "alert" : "This is the alert text", "badge" : 1, "sound" : "default" }
}
这将使消息显示于设备上,触发提升声音并将“1”置于程序图标上。默认按钮“Close”和“View”同时会显示于弹出窗口上。
对于 Server Density iPhone程序而言,让用户按下“View”直接进入产生此提示的服务器是很重要的,所以我们增加了额外的自定义值:
$payload['aps'] = array('alert' => 'This is the alert text', 'badge' => 1, 'sound' => 'default');
$payload['server'] = array('serverId' => $serverId, 'name' => $name);
$output = json_encode($payload);
当用户按下“View”后,自定义server值将被传递到设备中的程序。JSON 值如下:
{
"aps" : { "alert" : "This is the alert text", "badge" : 1, "sound" : "default" },
"server" : { "serverId" : 1, "name" : "Server name")
}
256字节的限制适用于整个载荷,包括自定义字典集。
原生接口
在Server Density中,一旦产生了一条提示,将建立一个载荷并插入队列中。因此有必要时我们可以同时发送多个载荷。
Apple推荐使用这种方法,因为如果你在发送各载荷时频繁连接和断开,APNS有可能会封锁你的IP。
3.Push Notification Provider 是一个应用程序,用于通过 APNs 发送推送通知给 iPhone 应用。
通过 APNs 发送推送通知有几个步骤:
1. 使用前面创建的 SSL 证书与 APNs 通讯;
2. 构造所要发送的消息载体;
3. 发送载体到APNs;
APNs 是一个基于流的 TCP socket,你的 provider 以 SSL 协议与其通讯。推送通知(包括载体)是以二进制流的方式发送的。和APNs 建立连接后,你可以维持该连接并在连接中断之前发送多个通知。
技巧:应避免每发送一次推送通知就建立、关闭一次连接。频繁的建立、关闭连接可能会被 APNs 认为是 DOS 攻击,从而拒绝发送provider 的推送通知发送请求。