小白也能掌握的个推iOS推送集成教程

小白也能掌握的个推iOS推送集成教程

一次偶然的机会,公司的项目要用到推送,我自己本来就很懒,不愿意去弄整套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

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

image.png

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

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

image.png

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

image.png

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

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

image.png

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.登记新应用

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

image.png

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

image.png

这里我有点疑惑。创建应用的时候想勾选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.进入苹果开发者中心,选择证书选项,如下图所示:

image.png

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

image.png

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

image.png

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

image.png
image.png
image.png
image.png

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

image.png
image.png

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

image.png
image.png

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

image.png

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

image.png

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

推送测试

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

image.png

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

image.png

透传消息测试:

image.png

APNs消息测试

image.png
image.png

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 推送。

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

多媒体测试

image.png

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

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

Xcode集成

1.导入个推SDK:

image.png
image.png

2.库引用检查:

image.png

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 库)
image.png

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

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

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

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

6.添加Notification Service Extension

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

image.png

注意: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。如下图所示:

image.png

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

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

(3).添加GtExtensionSdk依赖库

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

libz.tbd
libsqlite3.tbd
GTExtensionSDK.framework
UserNotifications.framework
image.png

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

image.png

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

image.png

集成过程中遇到的问题

无效的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上要注意,本人是按照个推官网给的建议命名的。

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