iOS 如何为项目添加消息推送及使用友盟推送记录

现在为我们的项目添加推送功能有两种方式

1:使用Token Authentication (p8)方式,也是现在推荐的方式

Token Authentication (p8)是 APNs 新推出的推送鉴权方式,这种新的方式有很多优势

  • 同一个账户下所有 App 无论是测试 App 还是正式版 App,都能使用同一个 key 来发推送消息和 voice-over-Internet Protocol (VoIP) 消息,不再需要为每个 App 生成一个证书
  • 生成的 Auth Key 不再有过期时间,无需像证书那样每年需要重新生成一次
  • 生成过程简单,不需要繁琐、易错的证书导出操作

创建Token Authentication (p8)

image.png

点击keys旁边的添加,然后我们勾选图中的选择,点击continue
image.png

下载后会有一个.p8文件,AuthKey_keyxxxxx.p8
image.png

如果我们使用第三方推送,比如友盟,个推等,我们还需要Team ID
image.png

这里以友盟推送示列,我们去友盟上配置一下,最后点击确认添加,如果不出意外,添加成功
image.png

2:使用证书的方式来添加消息推送

1:从CA请求证书

image.png

WechatIMG7.png

2:苹果开发者网站创建推送证书,点击+号
image.png

我们创建开发和发布环境都支持的证书
image.png

选择我们要创建推送证书的App ID,绑定证书与App的关系,这个App就可以实现消息推送功能
image.png

选择刚刚创建的CA证书
WechatIMG10.png

创建成功,下载证书,并添加到钥匙串中
image.png

导出.p12文件备用
image.png

3:如果之前创建了App ID,我们需要为此App ID开启推送

image.png

4:如果已经创建描述文件,需要重新保存

WechatIMG13.png

5:使用证书方式推送,我们去友盟为此方式进行配置

image.png

3:设置xcode,开启推送功能

在xcode中为我们的项目打开我们的消息推送功能

image.png

其他消息推送功能也记录下,关于app后台运行的功能

voice over ip 简称voip,需要配置证书,如果你的项目包含语音通话,类似微信语音视频功能,可以选择此项,app处于后台或者杀死app,收到此消息都会唤醒app执行一个方法,审核需要提供呼叫功能演示视频
Remote nitifications 静默推送,推送方式类似消息推送,不过不会弹出消息框,app处于后台会被唤醒调用一个方法,我们可以在这个方法中处理一些事情,但是杀掉app就收不到此推送
APNS 普通消息推送,app处于后台或者杀死app都能收到,但不会唤醒app调用方法

这里我选择开启后台的静默推送

image.png

添加推送的代码,使用友盟推送

// Push功能配置
    UMessageRegisterEntity * entity = [[UMessageRegisterEntity alloc] init];
    entity.types = UMessageAuthorizationOptionBadge|UMessageAuthorizationOptionAlert|UMessageAuthorizationOptionSound;
    if (@available(iOS 10.0, *)) {
        // 如果要在iOS10显示交互式的通知,必须注意实现以下代码
        UNNotificationAction *action1_ios10 = [UNNotificationAction actionWithIdentifier:@"action1_identifier" title:@"打开应用" options:UNNotificationActionOptionForeground];
        UNNotificationAction *action2_ios10 = [UNNotificationAction actionWithIdentifier:@"action2_identifier" title:@"忽略" options:UNNotificationActionOptionForeground];
        
        //UNNotificationCategoryOptionNone
        //UNNotificationCategoryOptionCustomDismissAction  清除通知被触发会走通知的代理方法
        //UNNotificationCategoryOptionAllowInCarPlay       适用于行车模式
        UNNotificationCategory *category1_ios10 = [UNNotificationCategory categoryWithIdentifier:@"category1" actions:@[action1_ios10, action2_ios10] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
        NSSet *categories = [NSSet setWithObjects:category1_ios10, nil];
        entity.categories = categories;
        
        [UNUserNotificationCenter currentNotificationCenter].delegate = self;
    }else {
        // 如果你期望使用交互式(只有iOS 8.0及以上有)的通知,请参考下面注释部分的初始化代码
        UIMutableUserNotificationAction *action1 = [[UIMutableUserNotificationAction alloc] init];
        action1.identifier = @"action1_identifier";
        action1.title=@"打开应用";
        action1.activationMode = UIUserNotificationActivationModeForeground;//当点击的时候启动程序
        
        UIMutableUserNotificationAction *action2 = [[UIMutableUserNotificationAction alloc] init];  //第二按钮
        action2.identifier = @"action2_identifier";
        action2.title=@"忽略";
        action2.activationMode = UIUserNotificationActivationModeBackground;//当点击的时候不启动程序,在后台处理
        action2.authenticationRequired = YES;//需要解锁才能处理,如果action.activationMode = UIUserNotificationActivationModeForeground;则这个属性被忽略;
        action2.destructive = YES;
        UIMutableUserNotificationCategory *actionCategory1 = [[UIMutableUserNotificationCategory alloc] init];
        actionCategory1.identifier = @"category1"; //这组动作的唯一标示
        [actionCategory1 setActions:@[action1, action2] forContext:(UIUserNotificationActionContextDefault)];
        NSSet *categories = [NSSet setWithObjects:actionCategory1, nil];
        entity.categories = categories;
    }
    [UMessage registerForRemoteNotificationsWithLaunchOptions:launchOptions Entity:entity completionHandler:^(BOOL granted, NSError * _Nullable error) {
        if (granted) {
            DLog(@"注册消息通知成功");
        }else {
            
        }
    }];

// 注册消息推送成功,收到token
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    //获取终端设备标识,这个标识需要通过接口发送到服务器端,服务器端推送消息到APNS时需要知道终端的标识,APNS通过注册的终端标识找到终端设备。
    NSLog(@"推送的token %@",[[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
                  stringByReplacingOccurrencesOfString: @">" withString: @""]
                 stringByReplacingOccurrencesOfString: @" " withString: @""]);
//    DLog(@"推送的token %@", currentDeviceToken);
    [UMessage registerDeviceToken:deviceToken];
}

// ios10以下 前台收到推送消息
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    DLog(@"推送消息 didReceiveRemoteNotification")
}
// ios10以下 后台收到消息推送
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [UMessage setAutoAlert:NO];
    DLog(@"推送消息 didReceiveRemoteNotification fetchCompletionHandler");
    if([[[UIDevice currentDevice] systemVersion] intValue] < 10){
        [UMessage didReceiveRemoteNotification:userInfo];
    }
    completionHandler(UIBackgroundFetchResultNewData);
}

//iOS10新增:处理前台 *收到通知的代理方法
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler API_AVAILABLE(ios(10.0)){
    NSDictionary * userInfo = notification.request.content.userInfo;
    if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
        // 不要开启弹出框
        [UMessage setAutoAlert:NO];
        // 应用处于前台时的远程推送接受
        // 必须加这句代码
        [UMessage didReceiveRemoteNotification:userInfo];
    }else{
        //应用处于前台时的本地推送接受
    }
    DLog(@"推送消息 userNotificationCenter willPresentNotification");
    completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
}

//iOS10新增:处理后台 *点击通知的代理方法(后台静默推送会调用此方法)
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler API_AVAILABLE(ios(10.0)){
    NSDictionary * userInfo = response.notification.request.content.userInfo;
    if (@available(iOS 10.0, *)) {
        if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
            //应用处于后台时的远程推送接受
            //必须加这句代码
            [UMessage didReceiveRemoteNotification:userInfo];
        }else{
            //应用处于后台时的本地推送接受
        }
    } else {
        // Fallback on earlier versions
    }
    DLog(@"推送消息 userNotificationCenter didReceiveNotificationResponse");
}

4:遇到的坑,关于使用友盟推送遇到的问题记录

使用友盟推送时,当我们使用development证书调试时,无法收到推送的消息,推送失败如下device-token全部失败

image.png

我们可以发现下图中,debug下选择的development证书的ID与TeamID不相同
development

我们看看release下选择的distribution证书ID和TeamID是相同的
distribution

尝试在debug下使用distribution证书,真机无法运行起来
image.png

解决办法1:将程序打包成Ad hoc安装,这样就可以收到消息推送
解决办法2:使用测试消息推送的工具,比如Pusher,测试工具需要选择证书推送的情况下才能使用

image.png

5:记录下消息推送的格式

iOS10之前的格式

{  
   "aps":{  
      "alert":"内容",
      "badge":1,
      "sound":"default",
      "userinfo":{"username":"tom"}
   }
}

iOS 10及之后(iOS7、iOS8、iOS9可通用此模板)

{  
   "aps":{  
      "alert":{  
         "title":"标题", // iOS7、8设置无效,iOS9一般设置为appName
         "subtitle":"子标题", // 一般使用title就能满足需求
         "body":"内容"
      },
      "badge":1, //角标数
      "sound":"default", //声音
      "userinfo":{ //通知内容信息
           "playid":"123",
           "username":"tom",
           "sex":1
      }
   }
}
参考文章:

https://leancloud.cn/docs/ios_push_cert.html#hash1133282448
https://developer.umeng.com/docs/66632/detail/66734
https://blog.csdn.net/zykccss/article/details/58259240

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

推荐阅读更多精彩内容