IOS 个推推送总结

1.创建个推开发者帐号
创建个推开发者帐号,请访问个推开发者平台(dev.getui.com),点击注册进行开发者账号注册。
2.登记新应用
创建好账号进入个推开发者平台,首页展示的是如下界面,点击左上角“登记应用”。
这里写图片描述
注意:应用平台选择IOS,应用标识与工程的Bundle ID相同,应用证书是推送证书的P12文件(分为开发环境和产品环境),证书密码是导出P12文件的时候设置的,个推平台上密码不能为空,所以必须设置密码。

3.推送证书的制作
(1).登录苹果开发者官网进入certificate中心创建App IDs(标记应用的唯一性,区别于其他应用),创建App IDs 之前必须先有Development或者Production的根证书(一个开发者账号只能各自创建两个根证书,如果需要新的根证书则需要删除之前已创建的)
这里写图片描述
为App开启Push Notification功能。如果是已经创建的App ID也可以通过设置开启Push Notification功能。
这里写图片描述
根据实际情况完善App ID信息并提交,注意此处需要指定具体的Bundle ID,不要使用通配符如星号(*)和问号(?)等。(因为推送是具体某个应用的功能,不能将某个应用的消息推送到其他应用上)
这里写图片描述

如果你之前没有创建过Push证书或者是要重新创建一个新的,请在证书列表下面新建。

新建证书需要注意选择证书种类(开发证书用于开发和调试使用,生产证书用于App Store发布)
这里写图片描述

点击Continue后选择证书对应的应用ID,然后继续会出现“About Creating a Certificate Signing Request (CSR)”。
这里写图片描述

根据它的说明创建Certificate Signing Request。
这里写图片描述

然后点击Continue ,上传刚刚生成的 .certSigningRequest文件 点”generate”生成APNs Push Certificate
这里写图片描述

继续返回Apple developer 网站点击 Continue ,上传刚刚生成的 .certSigningRequest 文件生成 APNs Push Certificate。
下载并双击打开证书,证书打开时会启动“钥匙串访问”工具。

在“钥匙串访问”中你的证书会显示在“我的证书”中,注意选择“My Certificates” 和”login”
3、导出 .p12证书文件
在“钥匙串访问”中,选择刚刚加进来的证书,选择右键菜单中的“导出“…””。
这里写图片描述

将文件保存为Personal Information Exchange (.p12)格式。保存p12文件时,需为其设置密码,因平台上传证书时需要密码。

注意:务必选择证书然后再导出。
这里写图片描述

4.导入个推SDK(具体进入个推官网了解)
5.集成个推
(1)App运行时启动个推SDK并注册APNS
在AppDelegate didFinishLaunchingWithOptions 方法中:通过平台分配的AppId、AppKey、AppSecret启动个推SDK,并完成注册APNS通知和处理启动时拿到的APNS透传数据。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 通过个推平台分配的appId、 appKey 、appSecret 启动SDK,注:该方法需要在主线程中调用
    [GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self];

    // 注册APNS
    [self registerRemoteNotification];

    // 处理远程通知启动APP,实现相应逻辑跳转
    [self receiveNotificationByLaunchingOptions:launchOptions];

    return YES;
}

//注册苹果通知
- (void)registerRemoteNotification {
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {

        UIUserNotificationSettings *uns = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound) categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:uns];
        [[UIApplication sharedApplication] registerForRemoteNotifications];

    }
    else {
        UIRemoteNotificationType apn_type = (UIRemoteNotificationType)(UIRemoteNotificationTypeAlert|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge);
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:apn_type];
    }
}

(2)向个推服务器注册DeviceToken

/** 远程通知注册成功委托 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    //处理苹果返回的deviceToken,去除空格和括号
    NSString *myToken = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    myToken = [myToken stringByReplacingOccurrencesOfString:@" " withString:@""];
    /// 向个推服务器注册deviceToken
    [GeTuiSdk registerDeviceToken:myToken];    
    NSLog(@"\n>>>[DeviceToken Success]:%@\n\n",myToken);
}

如果获取DeviceToken获取失败,也需要通知个推服务器

/** 远程通知注册失败委托 */
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    [GeTuiSdk registerDeviceToken:@""];     /// 如果APNS注册失败,通知个推服务器
    NSLog(@"\n>>>[DeviceToken Error]:%@\n\n",error.description);
}


/** SDK启动成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
    // [4-EXT-1]: 个推SDK已注册,返回clientId,通常需要将clientId发送给App服务器
    NSLog(@"\n>>>[GeTuiSdk RegisterClient]:%@\n\n", clientId);
}

/** SDK遇到错误回调 */
- (void)GeTuiSdkDidOccurError:(NSError *)error {
    // [EXT]:个推错误报告,集成步骤发生的任何错误都在这里通知,如果集成后,无法正常收到消息,查看这里的通知。
    NSLog(@"\n>>>[GexinSdk error]:%@\n\n", [error localizedDescription]);
}

(3)Background Fetch 接口回调,iOS7.0 以后支持APP后台刷新数据,会回调performFetchWithCompletionHandler接口,此处为保证个推数据刷新需调用 [GeTuiSdk resume] 接口恢复个推SDK 运行刷新数据


- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    /// Background Fetch 恢复SDK 运行
    [GeTuiSdk resume];
    completionHandler(UIBackgroundFetchResultNewData);
}

(4)使用个推SDK透传消息, 由个推通道下发 (非APNS)
SDK 在线状态时(App在前台运行),个推服务器会直接给您的App发送透传消息,不发送苹果APNS消息,可以更快的把消息发送到手机端;SDK离线状态时 (停止SDK 或 App后台运行 或 App停止),个推服务器会给App发送苹果APNS消息,同时保存个推的离线消息,当SDK在线后,SDK会获取所有的个推透传消息,offLine字 段就是表明该条消息是否为离线消息。

/** SDK收到透传消息回调 */
- (void)GeTuiSdkDidReceivePayload:(NSString *)payloadId andTaskId:(NSString *)taskId andMessageId:(NSString *)aMsgId andOffLine:(BOOL)offLine fromApplication:(NSString *)appId {

    // [4]: 收到个推消息
    NSData *payload = [GeTuiSdk retrivePayloadById:payloadId];
    NSString *payloadMsg = nil;
    if (payload) {
        payloadMsg = [[NSString alloc] initWithBytes:payload.bytes length:payload.length encoding:NSUTF8StringEncoding];
    }

    NSString *msg = [NSString stringWithFormat:@" payloadId=%@,taskId=%@,messageId:%@,payloadMsg:%@%@",payloadId,taskId,aMsgId,payloadMsg,offLine ? @"<离线消息>" : @""];
NSLog(@"\n>>>[GexinSdk ReceivePayload]:%@\n\n", msg); 

/**
*汇报个推自定义事件
*actionId:用户自定义的actionid,int类型,取值90001-90999。
*taskId:下发任务的任务ID。
*msgId: 下发任务的消息ID。
*返回值:BOOL,YES表示该命令已经提交,NO表示该命令未提交成功。注:该结果不代表服务器收到该条命令
**/
[GeTuiSdk sendFeedbackMessage:90001 taskId:taskId msgId:aMsgId];
}

(5)苹果官方静默推送

/**IOS7之后 APP已经接收到“远程”通知(推送) - 透传推送消息  */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
    // 处理APNs代码,通过userInfo可以取到推送的信息(包括内容,角标,自定义参数等)。如果需要弹窗等其他操作,则需要自行编码。app在前台时该方法不会执行,优先走个推透传。
    NSLog(@"\n>>>[Receive RemoteNotification - Background Fetch]:%@\n\n",userInfo);

    completionHandler(UIBackgroundFetchResultNewData);
}

/**IOS7之前 APP已经接收到“远程”通知(推送) - 透传推送消息  */
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    // 处理APNs代码,通过userInfo可以取到推送的信息(包括内容,角标,自定义参数等)。如果需要弹窗等其他操作,则需要自行编码。app在前台时该方法不会执行,优先走个推透传。
    NSLog(@"\n>>>[Receive RemoteNotification - Background Fetch]:%@\n\n",userInfo);

    completionHandler(UIBackgroundFetchResultNewData);

}

(6)自定义方法处理从通知栏点进来处理信息

- (void)handlePushMessage:(NSDictionary *)dict notification:(UILocalNotification *)localNotification {
   //开始处理从通知栏点击进来的推送消息

    if ([UIApplication sharedApplication].applicationIconBadgeNumber != 0) {
        if (localNotification) {
        //删除相应信息栏
            [[UIApplication sharedApplication] cancelLocalNotification:localNotification];
        }
        //应用的数字角标减1
        [UIApplication sharedApplication].applicationIconBadgeNumber -= 1;
    }
    else {
        [[UIApplication sharedApplication] cancelAllLocalNotifications];
        [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
    }
}

总结:
a. app在前台运行时:收到推送信息,优先走个推透传,触发方法:
- (void)GeTuiSdkDidReceivePayload:(NSString )payloadId andTaskId:(NSString )taskId andMessageId:(NSString )aMsgId andOffLine:(BOOL)offLine fromApplication:(NSString )appId ;
只有在个推失效情况下,才会触发以下方法(可能性低)
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo;

b. app在后台运行,收到推送信息则走苹果APNS推送,在消息栏里有新消息提醒。此时有两种进入app方法:点击消息栏和app图标。此时两种方法app delegate方法都一样。
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
和- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo;
如果个推有设置离线消息,并且此时还在离线消息的有效期内,也会触发
- (void)GeTuiSdkDidReceivePayload:(NSString )payloadId andTaskId:(NSString )taskId andMessageId:(NSString )aMsgId andOffLine:(BOOL)offLine fromApplication:(NSString )appId ;
所以如果要在上面几个方法里面做逻辑跳转的时候,要注意判断优先级,防止多次操作同一消息。

c.App进程已被杀死,此时收到推送消息,走的是苹果APNS推送。这个时候从消息栏进入app和点击图标进入app的触发方法是:
- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions;

//打印lanchOptions自动如下:
{
  "UIApplicationLaunchOptionsRemoteNotificationKey":{
  "aps":{
        "badge":1,
        "sound":"default",
        "alert":{
                "body":"消息内容"
                }
          }
  "payload":"自定义内容"
  }
}

和- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo;
如果个推有设置离线消息,并且此时还在离线消息的有效期内,也会触发
- (void)GeTuiSdkDidReceivePayload:(NSString )payloadId andTaskId:(NSString )taskId andMessageId:(NSString )aMsgId andOffLine:(BOOL)offLine fromApplication:(NSString )appId ;
所以如果要在上面几个方法里面做逻辑跳转的时候,要注意判断优先级,防止多次操作同一消息。

d.最后总结逻辑跳转位置:
如果是外部点击进入app则逻辑在下面方法处理
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;
- (void)application:(UIApplication )application didReceiveRemoteNotification:(NSDictionary )userInfo;

如果是在app内部则在个推透传方法中处理
- (void)GeTuiSdkDidReceivePayload:(NSString )payloadId andTaskId:(NSString )taskId andMessageId:(NSString )aMsgId andOffLine:(BOOL)offLine fromApplication:(NSString )appId ;

注意点:
1.处理逻辑的时候一定要防止重复操作,目前个人解决方法建立一个配置表,处理过的数据在表中标注,在处理前查询是否处理过。

2.开发的时候需要上传开发证书,开发测试OK后,发布到appstore之前,需要把证书更换成生产证书,证书更换后10分钟左右生效

3.自定义字段时,payload中的值有大小限制,最大为256字节,实际没有那么准确

4.个推平台上做apns推送测试

这里写图片描述

如果数据格式要payload = {"target_page":"{\"customer_id\":1}","notify_type":10};

则在payload中输入{"notify_type":1,"target_page":"\"customer_id\":10"}

5.做个推透传推送输入格式如下

这里写图片描述

{"aps":{"sound":"","alert":"contentBody","badge":1,"text":"contentBody"},"notify_type":0,"target_page":"{\"end_date\":\"1447047559745\",\"start_date\":\"1447047259745\",\"customer_id\":\"11111\"}"}
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值