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


推送机制:
1.PHP后台把要发送的消息、目的iPhone的标识打包,发送给APNS(apple推送服务器)
2.APNS在自身的已注册Push服务的iPhone列表中,查找有相应标识的iPhone,并把消息发到iPhone。
3.iPhone把发来的消息传递给相应的应用程序, �程序收到通知。
流程:
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);
    
    //通知错误时候代理
}

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

 $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
"; } // 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


最后看看要注意的几点:

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

你可能感兴趣的:([iOS篇] iOS推送用PHP做后台)