流程大致如下, 详情参考:http://hi.baidu.com/iphone8/item/cbc7ae7348ed1c3d6cc37ca7
1. 创建AppId, 不能使用通配符.
2. 创建绑定了AppId的推送证书, 测试证书和实际证书都需要创建.
3. 清理原有的开发证书后, 重新创建开发证书(未证实有什么影响)
4. iOS客户端代码, 在工程配置中, 选择第3步生成的证书. 不需要去管推送证书.
5. 利用推送证书(cer文件), 生成服务器证书(pem文件)
6. 服务器端代码
客户端代码(objc)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController* controller = [[UIViewController alloc] init];
self.label = [[UILabel alloc] initWithFrame:controller.view.bounds];
self.label.backgroundColor = [UIColor whiteColor];
self.label.numberOfLines = 0;
[controller.view addSubview:self.label];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.rootViewController = controller;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
// 注册推送通知功能
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];
// 程序是由推送服务启动的
if (launchOptions)
{
NSLog(@"APNS -> 通过推送窗口启动的程序");
NSDictionary* pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (pushNotificationKey)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"推送通知"
message:@"这是通过推送窗口启动的程序, 你可以在这里处理推送内容"
delegate:nil
cancelButtonTitle:@"知道了"
otherButtonTitles:nil, nil];
[alert show];
}
}
return YES;
}
// 接收从苹果服务器返回的唯一的设备deviceToken, 该deviceToken是推送服务器发送推送消息的依据, 所以需要发送回推送服务器保存
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
NSLog(@"APNS -> 生成的deviceToken:%@", deviceToken);
// TODO: 把deviceToken发送到我们的推送服务器, 是一个8x8的字符串
}
// 接收注册推送通知功能时出现的错误, 并做相关处理:
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"APNS -> 注册推送功能时发生错误, 错误信息:%@", error);
}
// 接收到推送消息, 解析处理, 这个方法只有在程序启动时才触发
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSLog(@"APNS -> 接收到推送消息, 接收的数据是:%@", userInfo);
application.applicationIconBadgeNumber = 0; // 把icon上的标记数字设置为0,
NSDictionary* dicAps = [userInfo objectForKey:@"aps"];
if ([dicAps objectForKey:@"alert"])
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"推送消息"
message:[dicAps objectForKey:@"alert"]
delegate:self
cancelButtonTitle:@"关闭"
otherButtonTitles:@"处理", nil];
[alert show];
}
self.label.text = userInfo.description;
}
服务器代码(php)
<?php
// collect parameters from url
// example: http://www.xxxxx.com/apns.php?types=0&alert=helloworld&badge=9&sound=received5.caf&token=660d76cfdb3d1e3b8d3cdf3b8302eeeeee32cd582ab20e3d3e8b82a944f1c826&other=aaaaaa
$types = $_GET['types']; // the test type (0 Development, 1 Distribution)
$token = $_GET['token']; // the deviceToken from iOS devices
$alert = $_GET['alert']; // the message will be shown
$badge = $_GET['badge']; // the num will be shown
$sound = $_GET['sound'];
$other = $_GET['other']; // the others will be received
if (!$types)
{
$types = '0';
}
if (!$token)
{
$token = '660d76cfdb3d1e3b8d3cdf3b8302eeeeee32cd582ab20e3d3e8b82a944f1c826'; // my iPhone
}
if (!$alert)
{
$alert = 'This is a simple notification';
}
if ($types === '0')
{
$certificate = 'issmobile2_push_development.pem'; // the development certificate from iOS App Developer
$serverurl = 'ssl://gateway.sandbox.push.apple.com:2195'; // notification(Development)
}
else
{
$certificate = 'issmobile2_push_production.pem'; // the distribution certificate from iOS App Developer
$serverurl = 'ssl://gateway.push.apple.com:2195'; // notification(Distribution)
}
$passphase = 'push'; // the passphrase of certificate
// construct the payload (payload size must be less than 256 bytes)
$body = array();
$body['aps'] = array();
if ($alert) $body['aps']['alert'] = $alert;
if ($badge) $body['aps']['badge'] = (int)$badge;
if ($sound) $body['aps']['sound'] = $sound;
if ($other) $body['aps']['other'] = $other;
$payload = json_encode($body);
$message = chr(0) . pack("n", 32) . pack('H*', str_replace(' ', '', $token)) . pack("n", strlen($payload)) . $payload;
print "token: " . $token . "<br/>";
print "serverurl: " . $serverurl . "<br/>";
print "certificate: " . $certificate . "<br/>";
print "send message: " . $payload . "<br/>";
// send message to server
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $certificate);
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphase);
$fp = stream_socket_client($serverurl, $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
if (!$fp)
{
print "failed to connect $err $errstr<br/>";
return;
}
else
{
print "connection OK<br/>";
}
fwrite($fp, $message);
fclose($fp);
?>