[iOS篇] iOS推送用PHP做后台


<strong>推送机制:</strong>
1.PHP后台把要发送的消息、目的iPhone的标识打包,发送给APNS(apple推送服务器)
2.APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。
3.iPhone把发来的消息传递给相应的应用程序, �程序收到通知。
<strong>流程:</strong>
1,首先创建一个对应的APPID (Registering an App ID),这个和自己项目的Bundle Identifier要相符,不然推送会连接出错。对应了之后,选择服务的时候要勾选PUSH这个,标示这个项目要用到推送。

id.jpg

2,创建开发者的开发证书,证书有开发证书和发布证书,(主要以开发为例,因为开发和发布的证书和配置文件是一样的)。创建的时候注意两点,第一点是选择开发者的推送通知服务,如图:

id2.jpg

然后上传自己从电脑里边导出的certSigningRequest文件,最后下载这个证书,双击进行安装。

然后会发现自己电脑钥匙串的证书里边多了一个证书,如图:

A7248EE5-9C47-42EA-806E-BE439F9D3A7A.jpg

导出之后输入一个密码,记住这个密码,后边用,导出之后是一个p12文件,保存起来,最好和刚刚下载的cer这个文件保存在一个文件夹下。
然后打开终端,将cer文件和p12文件分别转换成pem文件: aps_development\ (8).cer是下载的证书文件。DevelopPushP12.p12是从钥匙串导出的p12证书。
openssl x509 -in aps_development\ (8).cer -inform der -out pushDeveCerTopem.pem
openssl pkcs12 -nocerts -out pushDeveP12Topem.pem -in DevelopPushP12.p12
第二次会出现输入密码的界面,就是刚自己导入时候设置的密码,然后会让输入四个字符的新的pem的密码,记住就行了。
然后会看见有两个pem的文件,然后将两个pem文件合并成一个pem文件,也就是将刚刚生成的两个pem合并了:

cat pushDeveCerTopem.pem pushDeveP12Topem.pem > sum.pem

接下来可以测试一下苹果的ssl服务的,也就是APNS的测试服务器:

openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert pushDeveCerTopem.pem -key pushDeveP12Topem.pem

如果出现图中的字样,那么说明配置成功了:

40B0D9D8-8345-4582-9FBF-3F74FD3AC6CA.jpg

然后进入xcode,记住自己的Bundle Identifier必须和刚刚申请的appid里边的Bundle Identifier匹配,然后选择xcode中这个项目是接收通知的:

4D6F4269-BCB0-434A-BAF5-B22016971379.jpg

然后appdelegate里边:

#import "AppDelegate.h"
 
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
 
@interface AppDelegate ()
 
@end
 
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   // Override point for customization after application launch.
   
   //判断系统版本,然后进行通知配置,因为ios8以后skd换了
   if(SYSTEM_VERSION_LESS_THAN(@"8.0")){
   
       [[UIApplication sharedApplication] registerForRemoteNotificationTypes:UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];
       
   }else{
           //1.创建消息上面要添加的动作(按钮的形式显示出来)
           UIMutableUserNotificationAction *action = [[UIMutableUserNotificationAction alloc] init];
           action.identifier = @"action";//按钮的标示
           action.title=@"Accept";//按钮的标题
           action.activationMode = UIUserNotificationActivationModeForeground;//当点击的时候启动程序
           //    action.authenticationRequired = YES;
           //    action.destructive = YES;
           
           UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];
           action2.identifier = @"action2";
           action2.title=@"Reject";
           action2.activationMode = UIUserNotificationActivationModeBackground;//当点击的时候不启动程序,在后台处理
           action.authenticationRequired = YES;//需要解锁才能处理,如果action.activationMode = UIUserNotificationActivationModeForeground;则这个属性被忽略;
           action.destructive = YES;
           
           //2.创建动作(按钮)的类别集合
           UIMutableUserNotificationCategory *categorys = [[UIMutableUserNotificationCategory alloc] init];
           categorys.identifier = @"alert";//这组动作的唯一标示,推送通知的时候也是根据这个来区分
           [categorys setActions:@[action,action2] forContext:(UIUserNotificationActionContextMinimal)];
           
           //3.创建UIUserNotificationSettings,并设置消息的显示类类型
           UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:[NSSet setWithObjects:categorys, nil]];
           [application registerUserNotificationSettings:notiSettings];

   }
   
   return YES;
}
#pragma mark - ios8
 
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
 
    //注册远程通知,ios8以上的注册
    [application registerForRemoteNotifications];
}
#pragma mark - ios8 less  & < 8.0
 
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken {
    //设备号
    NSLog(@"regisger success:%@", pToken);
    
    //注册成功,将deviceToken保存到应用服务器数据库中
    
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
    
  //接收到通知
    NSDictionary *info = [userInfo objectForKey:@"aps"];
    // 处理推送消息
    UIAlertView *alert=[[UIAlertView alloc]initWithTitle:@"通知" message:info[@"alert"] delegate:selfcancelButtonTitle:@"取消" otherButtonTitles:nil, nil];
    [alert show];
    NSLog(@"%@", userInfo);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Regist fail%@",error);
    
    //通知错误时候代理
}

<strong>服务器:</strong>
将刚刚合成的pem文件和自己要运行的php文件放在同一个文件夹下,服务器代码:

<?php
//手机注册时候返回的设备号,在xcode中输出的,复制过来去掉空格
$deviceToken = ‘70653cf189aeed1fbf207437446b6c9f6dbc406b57de38e52d1667edf1cd8a05‘;
//刚刚合并pem文件时候自己设置的四个字符的密码
$pass = ‘1234‘;    
//消息内容
$message = ‘this is my push content!‘.time();
//badge,也就是app中得小红点数
//$badge = 1;
//sound,是提示音, default是代表系统默认的提示音,也就是apple那个来通知的特别俗的提示音
$sound = ‘default‘;
//通知的内容,必须是json
$body = array();
$body[‘aps‘] = array(‘alert‘ => $message);
static $badge=1;
$body[‘aps‘][‘badge‘] = $badge += 1;
if ($sound)
  $body[‘aps‘][‘sound‘] = $sound;
//把数组数据转换为json数据
$payload = json_encode($body);  
//这个注释的是上线的地址,下边是测试地址,对应的是发布和开发:ssl://gateway.sandbox.push.apple.com:2195这个是沙盒测试地址,ssl://gateway.push.apple.com:2195正式发布地址
//创建推送流,然后配置推送流。
$ctx = stream_context_create();
stream_context_set_option($ctx, ‘ssl‘, ‘local_cert‘, ‘sum.pem‘);   //刚刚合成的pem文件
stream_context_set_option($ctx, ‘ssl‘, ‘passphrase‘, $pass);
$fp = stream_socket_client(‘ssl://gateway.sandbox.push.apple.com:2195‘, $err, $errstr, 60,STREAM_CLIENT_CONNECT, $ctx);
if (!$fp) {
    print "Failed to connect $err $errstr\n";
    return;
}
else {
   print "Connection OK\n<br/>";
}
// send message
$msg = chr(0) . pack("n",32) . pack(‘H*‘, str_replace(‘ ‘, ‘‘, $deviceToken)) . pack("n",strlen($payload)) .$payload;
//推送和关闭当前流
fwrite($fp, $msg);
fclose($fp);
?>

然后真机选择在code sign里边选择自己的配置文件,证书不用选择,xcode会自动匹配:

846E6EE0-425E-401A-9E43-B951CD38CAA5.jpg

运行自己的app,然后打开终端,进入自己后台服务器的文件夹,运行php文件:
php push.php
如果运行上边服务器的代码,出现Connection OK的字样,说明后台没问题,然后再看看前台时候收到通知。
我这边是接收到了:

IMG_0304.jpg


<strong>最后看看要注意的几点:</strong>

1,每次的设备号获取之后不能自己在后台手动输入,而是获取之后通过http请求,将设备号发送给服务器,然后让服务器来推,所以项目中获取设备号之后:

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken {
    
    NSLog(@"regisger success:%@", pToken);
    
    //注册成功,将deviceToken上传保存到服务器中
    AFHTTPRequestOperationManager *Manager = [AFHTTPRequestOperationManager manager];
    //这里将pToken进行处理,去掉空格,不写了。
    [Manager POST:@"服务器的接受的URL" parameters:@{@"token":pToken}success:^(AFHTTPRequestOperation *operation, id responseObject) {
        
        NSLog(@"succeed");
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        
        NSLog(@"fail");
        
    }];
    
}

2,小红点问题和跳转问题。当用户进入界面之后,用户离开后台之后小红点的处理。 跳转到指定页面的处理,服务器传来数据,通过客户端判断进行操作,不一一列举。

3,ios 的推送消息有256个字符长度限制;超出范围不能发送 ,且失败。

4,PHP运行的服务器如果没有开通sll模块,不管是apache,还是iis,都要开启这三个模块:

mod_include
mod_cgi
mod_expires

5,php文件在终端中打开,别再浏览器中打开,因为ssl模块不属于服务器的http模块,不开启服务也能推送,这是我试验过的。

6,服务器可以通过不同的身份推送不同的消息给客户端,取决于服务器要什么参数和客户端传什么参数。

7,ios8的注册方法可以这么判断:

#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
    [application registerForRemoteNotifications];
}
#endif

8,didFinishLaunchingWithOptions里边的配置应该有点多,不是这么写的应该是,改天改改。ios8步骤就是注册设置,然后注册,这么个流程。
9,推送就是实时通讯。


连接地址:http://www.mamicode.com/info-detail-1118979.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容