以下是一位开发者在集成个推iOS推送SDK过程中的真实经历。

作者:Ezreallp

一次偶然的机会,公司的项目要用到推送,我自己本来就很懒,不愿意去弄整套APNS的流程,刚好之前跟朋友聊起过他们的产品中集成了个推的Android推送,说是体验还可以,那这次我就试一下他们的iOS推送。于是抱着试一试的心态,我先建个demo,试着去集成一下个推iOS推送SDK,摸索着完成了整个流程,言归正传,直接上硬菜!

如何集成个推iOS SDK

看了个推的官网,发现他们集成的方式有两种,分别是XCode集成和CocoaPods集成。本人比较懒,越简单越好,越轻松越好,毫不犹豫的选择了Cocoapods集成方式,程序猿么,就是要想尽办法的懒,搞起!

CocoaPods集成

1.安装CocoaPods

安装方式简单, Mac 下都自带 ruby,使用 ruby 的 gem 命令即可下载安装:

$ sudo gem install cocoapods
$ pod setup

2.准备Podfile文件

在我们的工程目录下,新建一个名为Podfile的文件,如下格式,将依赖的库名字依次列在文件中即可:

作者这里使用的是标准版本:

target 'GeTuipush' do
platform :ios, "7.0"
pod 'GTSDK'
end target 'NotificationService' do
platform :ios, "10.0"
pod 'GTExtensionSDK'
end

3.完成GTSDK导入

在项目根目录中执行如下命令:

$ pod install

执行完成后,项目目录结构如下图所示:

注意:在pod install之前,首先你的工程必须创建好,并且如果Podfile文件里面如果有target:NotificationService,那在pod install之前需要创建好通知扩展的Target。

4.开启推送功能:既然是推送,当然是要开推送功能啦!:

5.后台运行权限设置:看个推的官网上面说是为了更好的支持消息推送,提供更多的推送样式,提高消息到达率,既然这么说了,那就不管三七二十一先开了再说,如下图所示:

6.XCode10建议开启WiFi信息授权:在 Xcode 10.x 以上,找到应用Target设置中的Capabilities -> Access WiFi Information,确认开关已经设为ON状态。如下图所示:

注意:主Target和通知扩展的Target都需要打开

7.代码部分,下来就是我们程序猿最喜欢的部分了,粘贴复制。由于是第一次集成个推SDK的代码,我还是仔细的研究了下。

初始化SDK注册APNs并获取CID

1.为AppDelegate增加回调接口类:

#import <UIKit/UIKit.h>
#import <GTSDK/GeTuiSdk.h> // iOS10 及以上需导入 UserNotifications.framework
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
#import <UserNotifications/UserNotifications.h>
#endif @interface AppDelegate : UIResponder <UIApplicationDelegate, GeTuiSdkDelegate, UNUserNotificationCenterDelegate> @property (strong, nonatomic) UIWindow *window; @end

2.初始化SDK并注册APNs:

#import "AppDelegate.h"

/// 个推开发者网站中申请App时,注册的AppId、AppKey、AppSecret
#define kGtAppId @"GVZZTqh7lu6S4VLMacneZ7"
#define kGtAppKey @"RRYDFjGzO17TJXZfGeTuq3"
#define kGtAppSecret @"7BXDJ0IgWF6a8M0xCgo4G" @interface AppDelegate () @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self];
// 注册 APNs
[self registerRemoteNotification];
return YES;
}

注册APNs获取DeviceToken:

/** 注册 APNs */
- (void)registerRemoteNotification { UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay) completionHandler:^(BOOL granted, NSError *_Nullable error) {
if (!error) {
NSLog(@"request authorization succeeded!");
}
}]; [[UIApplication sharedApplication] registerForRemoteNotifications];
}

个推demo里面给开发者提供演示代码,根据APP支持的iOS系统不同,进行修改。我们的工程最低支持iOS10。

获取CID信息:

/** SDK启动成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId { NSLog(@"clientId:%@", clientId);
}

这三个参数kGtAppId、kGtAppKey、kGtAppSecret是干啥用的,这三个参数如何获取?回头又看了下个推的官网才搞明白,正好记录下如何申请者三个参数,跟我应用的bundleID绑定。

如何获取kGtAppId、kGtAppKey、kGtAppSecret

1.创建个推开发者账号

访问个推开发者中心,申请个推账号

2.登记新应用

注意:登记新应用是在应用管理页面而不是消息推送页面。

在登记应用界面填写应用名和应用表示,勾选个推产品,勾选iOS,填写包名和bundleID,如下图所示:

这里我有点疑惑。创建应用的时候想勾选iOS,但是看到默认选择了Android平台,并要填写Android签名,这签名是what,这如何搞?看到跟前有个提示如何获取,点了一下,发现里面有SHA256的签名,抱着试一试的态度,直接copy过来,呦呵,能用哦,心里美滋滋。

提交成功后就可以获取到kGtAppId、kGtAppKey、kGtAppSecret,将三个参数填入我们的工程中,然后运行工程,在GeTuiSdkDidRegisterClient的回调方法中获取到cid了,嗯,看来我们已经成功了一一小部分了,距离成功还要继续加油。

注册DeviceToken并统计APNs通知的点击数

1.向个推服务器注册DeviceToken:

/** 远程通知注册成功委托 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//向个推服务器注册deviceToken 为了方便开发者,建议使用新方法
NSLog(@"deviceToken:%@",deviceToken);
[GeTuiSdk registerDeviceTokenData:deviceToken];
}

2.处理APNs通知点击事件:

因为我们的工程最低适配到iOS10,这里我就只添加了iOS10及以后版本的通知点击事件,要是想兼容iOS10以下的,可以在个推的demo中找到。

iOS 10及以后版本,处理APNs通知点击事件

//  iOS 10: 点击通知进入App时触发,在该方法内统计有效用户点击数
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler { NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo); // [ GTSdk ]:将收到的APNs信息传给个推统计
[GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo]; completionHandler();
}

3.接受个推通道下发的透传消息:

/** SDK收到透传消息回调 */
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
//收到个推消息
NSString *payloadMsg = nil;
if (payloadData) {
payloadMsg = [[NSString alloc] initWithBytes:payloadData.bytes length:payloadData.length encoding:NSUTF8StringEncoding];
} NSString *msg = [NSString stringWithFormat:@"taskId=%@,messageId:%@,payloadMsg:%@%@",taskId,msgId, payloadMsg,offLine ? @"<离线消息>" : @""];
NSLog(@"\n>>>[GexinSdk ReceivePayload]:%@\n\n", msg);
}

获取到了透传消息,但是当应用在后台或者应用杀死的情况下,我们如何获取到APNs消息,这里我们就需要在个推平台用到推送证书,如何获取推送证书?因为本人也是第一次搞推送这书,而且也踩了不少的坑,为了下次不再踩同样的坑,所以在这里就对如何制作推送证书进行了一次规整。

如何制作推送证书?

1.进入苹果开发者中心,选择证书选项,如下图所示:

2.创建推送证书之前必须创建一个APPID,因为推送证书是和APPID绑定在一起的,如下图所示:

在下面的App Services中选择允许推送(Push Notifications),如下图所示:

3.APPID创建好了之后,这个时候需要去创建推送证书,而且还要根据需要的环境选择对应的推送证书,包括开发环境推送证书和生产环境推送证书,然后还要跟刚才创建好的APPID相关联,如下图所示:

这个时候需要上传CSR文件,我们回到桌面,打开钥匙串,从颁发机构申请证书并保存到本地磁盘,如下图所示:

这样CSR文件就创建好了,我们回到苹果开发者中心,继续创建我们的推送证书,选择保存到本地的CSR文件,如下图所示:

这样,我们的推送证书就创建完成了,在本地下载中找到下载的推送证书并双击添加到钥匙串中,然后打开钥匙串找到创建好的推送证书,右键导出P12证书,并输入证书密码,如下图所示:

4.打开我们的个推开发者中心,在个推·消息推送-应用列表-应用配置”中上传正确的APNs证书,如下图所示:

接下来最重要的时刻来了,那就是测试了,看看我们的推送能不能成功。

推送测试

本人是在个推平台上面进行推送测试的,在应用列表里面点击之前创建的应用上的创建推送按钮,如下图所示:

进入后,我有点懵逼,因为之前没有了解过个推SDK的逻辑,在询问了个推技术支持后,技术支持告诉我怎么在个推平台上面去推,也是自己太粗心了,人家进去第一句话就写的很清楚,推送通知目前仅支持安卓用户,iOS请使用透传消息。尴尬!那就透传消息页面试试推。如下图所示:

透传消息测试:

APNs消息测试

NICE啊,这下应用在前台、应用在后台和应用被杀死的情况下都可以收到推送消息了,爽歪歪啊!看来我们已经成功看了百分之九十了!

Notification Service Extension

正在沾沾自喜的时候,突然发现个推的官网上面还有多媒体推送,我靠,还有这种操作,好奇心的趋势下,让我重新审视如何去做多媒体推送。因为我们之前已经把通知扩展的target创建好了,所以,直接上代码。

1.Notification Service Extension 添加成功后会在项目中自动生成 NotificationService.h 和 NotificationService.m 两个类,包含以下两个方法:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy]; // [ 测试代码 ] TODO:用户可以在这里处理通知样式的修改,eg:修改标题,开发阶段可以用于判断是否运行通知扩展
//self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [WillIn]", self.bestAttemptContent.title]; // [ GTSDK ] 统计APNs到达情况和多媒体推送支持接口, 建议使用该接口
[GeTuiExtSdk handelNotificationServiceRequest:request withAttachmentsComplete:^(NSArray *attachments, NSArray *errors) { // self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Success]", self.bestAttemptContent.title]; self.bestAttemptContent.attachments = attachments; // 设置通知中的多媒体附件
self.contentHandler(self.bestAttemptContent);
}];
}

我们可以在这个方法中处理我们的 APNs 通知,并个性化展示给用户。APNs 推送的消息送达时会调用这个方法,此时你可以对推送的内容进行处理,然后使用contentHandler方法结束这次处理。但是如果处理时间过长,将会进入serviceExtensionTimeWillExpire方法进行最后的紧急处理。

- (void)serviceExtensionTimeWillExpire {
// [ GTSDK ] 销毁SDK,释放资源
[GeTuiExtSdk destory]; //self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Timeout]", self.bestAttemptContent.title]; self.contentHandler(self.bestAttemptContent);
}

如果didReceiveNotificationRequest方法在限定时间内没有调用 contentHandler方法结束处理,则会在过期之前进行回调本方法。此时你可以对你的 APNs 消息进行紧急处理后展示,如果没有处理,则显示原始 APNs 推送。

接下来就是测试我们的多媒体推送是否成功,我在网上找了个小狗的照片,直接在个推平台上面推。

多媒体测试

6啊,终于搞定了!棒棒哒~~~

但是,之前的一个老项目说也要集成推送,我透,老项目要用XCode集成,这对于我这种懒人来说,简直是一种折磨啊,哎,折磨归折磨,该搞还要搞。但是之前已经用CocoaPods搞过一遍,这次用XCode集成还不是手到擒来。但是为了防止出错,本人还是先做了个demo,这样后面在自己项目上面集成的话把握性会更大,踩的坑也就会更少。

XCode集成

1.导入个推SDK:

2.库引用检查:

3.添加系统依赖库:

libc++.tbd
libz.tbd
libsqlite3.tbd
libresolv.tbd
Security.framework
MobileCoreServices.framework
SystemConfiguration.framework
CoreTelephony.framework
AVFoundation.framework
CoreLocation.framework
UserNotifications.framework (iOS 10 及以上需添加,使用 Optional 方式接入)
AdSupport.framework (如果使用无IDFA版本SDK,则需删除该 AdSupport 库)

幸亏后面的步骤基本上都是一样的,唯一的欣慰呀!

4.开启推送功能、后台运行权限设置、开启WiFi信息授权

这里跟上面步骤一样,就不啰嗦了。

5.copy代码,这是我们程序猿最喜欢的啦,哈哈哈,之前搞过,这里就不累赘了。

6.添加Notification Service Extension

(1).打开XCode,菜单中选择File->New->Target->Notification Service Extension。如下图所示:

注意:1.Extension的Bundle Identifier不能和Main Target(也就是自己的App Target)的Bundle Identifier相同,否则会报BundleID重复的错误。2.Extension 的 Bundle Identifier 需要在 Main Target 的命名空间下,比如说 Main Target 的 BundleID 为 ent.getui.xxx,那么Extension的BundleID应该类似与ent.getui.xxx.yyy这样的格式。如果不这么做,会引起命名错误。

这个是在个推官网上面看到的,之前自己也踩了这个坑,这里就记录下来。

添加 Notification Service Extension 后会生成相应的 Target。点Finish按钮后会弹出是否激活该 Target 对应 scheme 的选项框,选择 Activate,如果没有弹出该选项框,需要自行添加相应的 scheme。如下图所示:

(2).Notification Service Extension 添加成功后会在项目中自动生成 NotificationService.h 和 NotificationService.m 两个类

这里跟上面一样,就不累赘了。

(3).添加GtExtensionSdk依赖库

选择Notification Service Extension所对应的Target,添加如下依赖库:

libz.tbd
libsqlite3.tbd
GTExtensionSDK.framework
UserNotifications.framework

(4).XCode10建议开启WiFi信息授权:在 Xcode 10.x 以上,找到应用Target设置中的Capabilities -> Access WiFi Information,确认开关已经设为ON状态。如下图所示:

(5).开启多媒体地址Http访问支持:

集成过程中遇到的问题

无效的deviceToken

最让我印象深刻的就是无效的deviceToken,在测试APNS推送的时候,询问过个推那边的技术支持,他们说可以先在应用配置里面测试一下,然后我就拿着我的deviceToken去测试一下,结果提示我是无效的deviceToken,我晕,然后继续咨询个推的技术支持,他们说这个原因有可能是我证书环境的问题。经过一番仔细的检查之后,发现,我在个推平台上面上传的是通用证书,然后我XCode上面的授权证书是开发环境下,这样一来,拿到的是开发环境下的deviceToken,用测试一下,当然会出错。

解决的方案有两种:第一,在个推开发平台上传开发环境下的推送证书。第二:将自己的授权证书更换为生产环境。

通知扩展里面修改标题的代码不生效

self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Success]", self.bestAttemptContent.title];

发现demo里面有这么一行代码,我把这行代码打开后,推送一条消息,发现标题没有变化,我惊呆了!询问个推技术支持,个推技术支持说,让我先运行主target,然后再运行通知扩展,运行通知扩展的时候会让我们去找主targetAPP,选择主target,然后再推送就会有了,嗯,想了下,这个应该是XCode的bug。

结语

最后,我要说,消息推送功能的集成对APP而言真的真的很重要。以上是个推iOS推送SDK集成的全步骤,给大家做个参考。特别需要注意的几点是:

1.在个推平台上上传的推送证书一定要正确并且要和自己的环境相对应,推荐上传P8证书;

2.主target和通知扩展target是两个target,命名和bundleID上要注意,本人是按照个推官网给的建议命名的。

原文链接:

https://www.jianshu.com/p/cce2200c0ed7

手把手教你搞定个推iOS推送SDK集成的更多相关文章

  1. iOS开发——实用技术OC篇&8行代码教你搞定导航控制器全屏滑动返回效果

    8行代码教你搞定导航控制器全屏滑动返回效果 前言 如果自定了导航控制器的自控制器的leftBarButtonItem,可能会引发边缘滑动pop效果的失灵,是由于 self.interactivePop ...

  2. CHUCK手把手带你搞定OPENSTACK

    一.OpenStack初探 1.1 OpenStack简介 OpenStack是一整套开源软件项目的综合,它允许企业或服务提供者建立.运行自己的云计算和存储设施.Rackspace与NASA是最初重要 ...

  3. 一张图教你搞定Mac App Store 应用安装包存储路径

    还在为找不到App Store 更新应用的安装文件发愁吗?是否有过多个人同时需要更新Xcode,都自己下载一次的痛苦经历? 大家都知道通过苹果服务器下载东西,确实难耐!AppStore 甚至都经常提示 ...

  4. 忘记MySQL密码怎么办?一招教你搞定!

    在安装完 MySQL 或者是在使用 MySQL 时,最尴尬的就是忘记密码了,墨菲定律也告诉我们,如果一件事有可能出错,那么它一定会出错.那如果我们不小心忘记了 MySQL 的密码,该如何处理呢?别着急 ...

  5. (转载)iOS 极光推送SDK 集成指南

    iOS SDK 集成指南 使用提示 本文匹配的 SDK版本:r1.2.5 以后. 查看最近更新了解最新的SDK更新情况. 产品功能说明 极光推送(JPush)是一个端到端的推送服务,使得服务器端消息能 ...

  6. Android消息推送 SDK 集成指南

    使用提示 本文是 Android SDK 标准的集成指南文档. 匹配的 SDK 版本为:r1.8.0及以后版本. 本文随SDK压缩包分发.在你看到本文时,可能当前的版本与本文已经不是很适配.所以建议关 ...

  7. 个推安卓推送SDK集成步骤详解

    以下是一位开发者在集成个推安卓推送SDK时候的亲身经历: 作者:吃饱了想睡. 概述 公司准备采用个推作为第三方推送平台,我作为客户端的头号小鸟,掐指一算已经毕业 0.1 年了,Leader 准备把这个 ...

  8. 手把手教你在Mac中搭建iOS的 React Native环境

    准备工作 1.你需要一台Mac电脑..(这不是废话?我所用的是Air~~穷..) 2.我所操作的电脑系统环境是 3.xcode版本:8.0正式版 必需的软件 1.Homebrew Homebrew, ...

  9. 教你搞定Android自定义View

    Android App开发过程中,很多时候会遇到系统框架中提供的控件无法满足我们产品的设计需求,那么这时候我们可以选择先Google下有没有比较成熟的开源项目可以让我们用,当然现在Github上面的项 ...

随机推荐

  1. ubuntu使用iptables 持久化

    iptables 持久化 安装持久化工具apt-get install iptables-persistent Ubuntu 16.04 调用语法netfilter-persistent savene ...

  2. 通过proxychains实现Ubuntu终端代理

    1.在终端内使用代理,需要使用proxychains: sudo apt-get install proxychains 2.编辑 /etc/proxychains.conf sudo gedit / ...

  3. linux 进程2

    一. exec族函数 1.1. 为什么需要exec函数 a. fork子进程是为了执行新程序(fork创建了子进程后,子进程和父进程同时被OS调度执行,因此子进程可以单独的执行一个程序,这个程序宏观上 ...

  4. Luogu P1864 [NOI2009]二叉查找树

    题目 \(v\)表示权值,\(F\)表示频率. 首先我们显然可以把这个权值离散化. 然后我们想一下,这个东西它是一棵树对吧,但是我们改变权值会引起其树形态的改变,这样很不好做,所以我们考虑把它转化为序 ...

  5. 题解 CF1140D 【Minimum Triangulation】

    题意:求将一个n边形分解成(n-2)个三边形花费的最小精力,其中花费的精力是所有三角形的三顶点编号乘积的和(其中编号是按照顶点的顺时针顺序编写的) 考虑1,x,y连了一个三角形,x,y,z连了一个三角 ...

  6. mui前端框架下拉刷新分页加载数据

    前台 mui.init(); (function($) { //阻尼系数 var deceleration = mui.os.ios?0.003:0.0009; $('.mui-scroll-wrap ...

  7. 阿里云服务器重启出现An error occurred 如何处理

    最近网站重启阿里云服务后,出现 An error occurred, An error occurred. Sorry, the page you are looking for is current ...

  8. Windows 10 IoT Core Dashboard 无法安装的问题

    有人在answers.microsoft.com问这个问题,官方给了个这样的回答,然后还锁定了问题不让别人回复 您好, 了解到您在使用时遇到问题. 请您详细描述下您的操作,请问您是在打开安装程序还是在 ...

  9. mysqldump: [Warning] Using a password on the command line interface can be insecure.

    MySQL 5.6 警告信息 command line interface can be insecure 修复 在命令行输入密码,就会提示这些安全警告信息. Warning: Using a pas ...

  10. SpringBoot_03mybatisPlus

    注意: mybatisPlus默认加载resources下的mapper文件夹下的xml文件 默认将数据库表的字段用驼峰标识转换成实体类的属性 官方网站: https://mp.baomidou.co ...