2022-06-08

iOS 推送SDK 集成指南

本文介绍译码小二郎即时通讯如何集成推送SDK

1.简介

本 iOS SDK 方便开发者基于个推来快捷地为 iOS 应用增加推送功能,减少开发者集成 APNs(Apple Push Notification Service) 需要的工作量,降低开发复杂度。

个推推送是一个端到端的推送服务,通过集成个推SDK,开发者能够及时有效地将服务端消息推送到客户端上,从而积极地保持与用户的连接,并提高用户活跃度和留存率。

2.主要功能及特点

(1).个推iOS SDK为应用提供推送服务,当应用在前台时,维持与推送服务器的长连接,实时接收推送消息;当应用在后台时,通过苹果APNs推送通知。
(2).集成简单快速。
(3).可以根据用户属性建立不同标签,进行定向推送。
(4).个推SDK不仅提供云端到客户端的推送服务,也提供从客户端上传至云端的消息服务,即推送消息链路支持上下行双向通道,开发者与云端之间互动更便利。
(5).支持 APNs 多媒体推送和通知的展示、点击统计功能。
(6).支持 iOS10 及以上多媒体推送展示。

3.技术要点

3.1 离线用户通过APNs下发通知
由于iOS系统限制,应用在后台无法长时间运行,从而无法维持与服务端的长连接。个推服务器发送消息给离线用户时,会通过苹果提供的 APNs 发送通知到用户设备上。需要应用开发者在个推开发者平台上提交 APNs 推送证书。
3.2 创建Apple应用ID和APNs推送证书
应用开发者需要使用苹果开发帐号,在https://developer.apple.com/中创建应用ID,并生成推送证书。
相关操作流程,请参照:创建APNs推送证书

4.推送流程

个推 iOS 推送服务框架如下图所示:

[图片上传失败...(image-b4b20a-1654674370401)]

个推 iOS 推送包括 2 个部分,APNs推送与应用内消息。

绿色部分是 APNs 推送,个推平台替开发者的应用通过苹果 APNs 服务器向指定的目标设备进行推送。由 APNs Server 将通知推送到相应的 iOS 设备上。
红色部分是个推应用内推送部分,即 App 启动时,应用内集成的个推SDK会开启长连接到个推服务器,从而开发者可通过个推服务器推送消息到 App 里,这条链路性能和稳定性更强,是APNs的一个很重要的补充。

客户端集成

1.pod方式 导入 SDK

1.cd 至项目根目录
2.执行 pod init
3.执行open -e Podfile
4.添加导入配置
如果使用标准版本:

target 'GtSdkDemo-objc' do
    platform :ios, "8.0"
    pod 'GTSDK'
end

如果使用无 IFDA 版本:

target 'GtSdkDemo-objc' do
    platform: ios, "8.0"
    pod 'GTSDK', 'xxx-noidfa' #xxx代表当前最新版本号
end

5.执行 pod install
6.双击打开 .xcworkspace

注意事项:
1.pod 'GTSDK'为添加在主 target 上
2.在 App 内无广告情况下还是建议开发者使用获取 IDFA 版本,并参考【IDFA版SDK注意事项说明】中所说的方式提交 AppStore 审核。当然,如果开发者不想使用 IDFA 或者担忧采集 IDFA 而未集成任何广告服务遭到 Apple 拒绝,我们也准备了该无 IDFA 版本供开发者集成。

2.手动方式 导入 SDK

(1).个推iOS SDK资料包结构

GETUI_IOS_SDK/
|- readme.txt (SDK资料包说明)
|- Lib/
| |- GtSdkLib/ (标准版个推SDK.framework文件)
| | |- GTExtensionSDK.framework
| | |- GTSDK.framework
| |- GtSdkLib-noidfa/ (无IDFA版个推SDK.framework文件)
| | |- GTExtensionSDK.framework
| | |- GTSDK.framework
| - Demo/
| |- GtSdkDemo-Manual/ (Objective-C手动集成演示Demo工程)
| |- GtSdkDemo-Pods/ (Objective-C CocoaPods集成演示Demo工程)
| |- GtSdkDemo-Swift/ (Swift标准集成框架代码工程)
| |- GtSdkDemo-SwiftUI/ (SwiftUI标准集成框架代码工程)
| |- GtSdkLib/ (个推SDK库文件,供上述Demo工程引用)

GtSdkDemo-Manual:Objective-C手动集成演示Demo工程。
GtSdkDemo-Pods:Objective-C Cocoapods集成 Demo。
GtSdkDemo-Swift: Swift 集成 Demo,方便 Swift 开发者集成个推 SDK。
GtSdkDemo-SwiftUI: SwiftUI 集成 Demo,方便 SwiftUI 开发者集成个推 SDK。

GtSdkLib:标准版个推SDK,包含集成所需的静态库和头文件
使用标准版本SDK需添加 AdSupport.framework 库支持

GtSdkLib-noidfa:无IDFA版个推SDK,包含集成所需的静态库和头文件。
在 App 内无广告情况下还是建议开发者使用获取 IDFA 版本,并参考【IDFA版SDK注意事项说明】中所说的方式提交 AppStore 审核。当然,如果开发者不想使用 IDFA 或者担忧采集 IDFA 而未集成任何广告服务遭到 Apple 拒绝,我们也准备了该无 IDFA 版本供开发者集成。
使用无IDFA版本SDK需删除 AdSupport.framework 库支持

GTSDK.framework:个推SDK核心库文件,支持i386、x86_64、arm64、armv7,因此同时支持simulator和device设备。

(2).导入个推SDK资源

打开自己的xcode工程,将GTSDK.framework添加到项目工程目录下:
[图片上传失败...(image-c9ce0e-1654674370402)]
[图片上传失败...(image-7f56c0-1654674370402)]

库引用检查

在导入时,Xcode正常情况下会自动添加引用,但是偶尔也会不添加,注意检查下图中的引用路径,如果报错找不到库或者头文件,一般都是下面的引用没有添加。
[图片上传失败...(image-ffc62a-1654674370402)]

添加 Other Linker Flags: -ObjC

[图片上传失败...(image-d22712-1654674370402)]

在项目设置中添加以下系统库支持:

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-bdf877-1654674370402)]

IDFA版SDK注意事项说明

在 App 内无广告情况下还是建议开发者使用获取 IDFA 版本,可参考下图中所说的方式提交 AppStore 审核。当然,如果开发者不想使用 IDFA 或者担忧采集 IDFA 而未集成任何广告服务遭到 Apple 拒绝,我们也准备了该无 IDFA 版本供开发者集成。

注意事项:

(1)、在 App 内投放广告,获取 IDFA 可通过苹果审核。

(2)、App 内无广告,但由于先前投放的特定广告,可参考如下勾选,通过苹果审核。
[图片上传失败...(image-45a82c-1654674370402)]

3.项目配置

3.1 开启推送功能
在 Xcode 11.x 以上,必须开启Push Notification能力。找到应用Target设置中的Signing & Capabilities,点击左上角+添加。如果没有开启该开关,应用将获取不到DeviceToken:
[图片上传失败...(image-ce3d56-1654674370402)]
3.2 后台运行权限设置
为了更好支持消息推送,提供更多的推送样式,提高消息到达率,需要配置后台运行权限:
[图片上传失败...(image-b1522a-1654674370402)]

Remote notifications:APNs静默推送权限

4. 编写集成代码

4.1 在 AppDelegate 中实现个推回调接口
为AppDelegate增加回调接口类。示例代码如下:

// AppDelegate.h

#import <UIKit/UIKit.h>
#import <GTSDK/GeTuiSdk.h>     // GetuiSdk头文件

@interface AppDelegate : UIResponder <UIApplicationDelegate, GeTuiSdkDelegate>

实现个推回调接口,示例代码如下:

/// 通知展示(iOS10及以上版本)
/// @param center center
/// @param notification notification
/// @param completionHandler completionHandler
- (void)GeTuiSdkNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification completionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    NSString *msg = [NSString stringWithFormat:@"[ TestDemo ] [APNs] %@ \n%@", NSStringFromSelector(_cmd), notification.request.content.userInfo];
    [self.homePage logMsg:msg];
    // [ 参考代码,开发者注意根据实际需求自行修改 ] 根据APP需要,判断是否要提示用户Badge、Sound、Alert等
    //completionHandler(UNNotificationPresentationOptionNone); 若不显示通知,则无法点击通知
    completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}

/// 收到通知信息
/// @param userInfo apns通知内容
/// @param center UNUserNotificationCenter(iOS10及以上版本)
/// @param response UNNotificationResponse(iOS10及以上版本)
/// @param completionHandler 用来在后台状态下进行操作(iOS10以下版本)
- (void)GeTuiSdkDidReceiveNotification:(NSDictionary *)userInfo notificationCenter:(UNUserNotificationCenter *)center response:(UNNotificationResponse *)response fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    NSString *msg = [NSString stringWithFormat:@"[ TestDemo ] [APNs] %@ \n%@", NSStringFromSelector(_cmd), userInfo];
    [self.homePage logMsg:msg];
    if(completionHandler) {
        // [ 参考代码,开发者注意根据实际需求自行修改 ] 根据APP需要自行修改参数值
        completionHandler(UIBackgroundFetchResultNoData);
    }
}


/// 收到透传消息
/// @param userInfo    推送消息内容
/// @param fromGetui   YES: 个推通道  NO:苹果apns通道
/// @param offLine     是否是离线消息,YES.是离线消息
/// @param appId       应用的appId
/// @param taskId      推送消息的任务id
/// @param msgId       推送消息的messageid
/// @param completionHandler 用来在后台状态下进行操作(通过苹果apns通道的消息 才有此参数值)
- (void)GeTuiSdkDidReceiveSlience:(NSDictionary *)userInfo fromGetui:(BOOL)fromGetui offLine:(BOOL)offLine appId:(NSString *)appId taskId:(NSString *)taskId msgId:(NSString *)msgId fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // [ GTSDK ]:汇报个推自定义事件(反馈透传消息),开发者可以根据项目需要决定是否使用, 非必须
    // [GeTuiSdk sendFeedbackMessage:90001 andTaskId:taskId andMsgId:msgId];
    NSString *msg = [NSString stringWithFormat:@"[ TestDemo ] [APN] %@ \nReceive Slience: fromGetui:%@ appId:%@ offLine:%@ taskId:%@ msgId:%@ userInfo:%@ ", NSStringFromSelector(_cmd), fromGetui ? @"个推消息" : @"APNs消息", appId, offLine ? @"离线" : @"在线", taskId, msgId, userInfo];
    [self.homePage logMsg:msg];

    if(completionHandler) {
        // [ 参考代码,开发者注意根据实际需求自行修改 ] 根据APP需要自行修改参数值
        completionHandler(UIBackgroundFetchResultNoData);
    }
}

- (void)GeTuiSdkNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(UNNotification *)notification {
    // [ 参考代码,开发者注意根据实际需求自行修改 ] 根据APP需要自行修改参数值
}


- (void)GeTuiSdkDidOccurError:(NSError *)error {
    NSString *msg = [NSString stringWithFormat:@"[ TestDemo ] [GeTuiSdk GeTuiSdkDidOccurError]:%@\n\n",error.localizedDescription];

    // SDK发生错误时,回调异常错误信息
    NSLog(@"%@", msg);
}

4.2 获取DCloud平台分配的 AppID、AppKey、AppSecret

4.2.1 使用 HBuilder 账号登录 开发者中心 ,登录后会进入“我创建的应用”列表,如下图所示,点击创建应用
[图片上传失败...(image-7bdc2-1654674370402)]

应用类型默认选择第一个,输入应用名称并确认。

[图片上传失败...(image-409823-1654674370402)]

4.2.2 点击要操作的应用的应用名称,进入应用管理页面,点击左侧导航中的“Uni Push”-“Uni Push”,进入 Uni Push 设置页面。如下图所示:
[图片上传失败...(image-717a30-1654674370402)]

4.2.3 开通 UniPush,用户首次使用 UniPush 功能时,需要向个推同步身份信息。已通过实名认证的用户,会直接将实名认证信息同步给个推。如下图所示:
[图片上传失败...(image-5633f4-1654674370402)]
未提交实名认证信息的用户,需要在页面中输入相关信息后提交,如下图所示:
[图片上传失败...(image-52ee0-1654674370402)]
应用开通 Uni Push 功能时,需要提交应用相关信息,如下图所示:
注意:在申请开通时,需要确保输入的 Android包名iOS Bundle ID 必须与打包时配置的一致,否则可能会导致无法收到推送消息。
[图片上传失败...(image-381668-1654674370402)]

如果已经开通 Uni Push,会看到如下页面:
[图片上传失败...(image-e0d4b9-1654674370402)]

4.3 iOS推送证书配置

iOS 平台还需要在 “配置管理”-“应用配置” 页面上传推送证书
如何获取推送证书请参考个推官方文档教程 iOS证书配置指南
[图片上传失败...(image-79759d-1654674370402)]

4.4 初始化SDK并注册APNs

AppDelegate didFinishLaunchingWithOptions方法中调用个推sdk初始化方法,传入DCloud平台分配的 AppIDAppKeyAppSecret。同时,调用APNs注册方法,尝试获取APNs DeviceToken。示例代码如下:

/// DCloud开发者网站中申请App时,注册的AppId、AppKey、AppSecret
#define kGtAppId           @"iMahVVxurw6BNr7XSn9EF2"
#define kGtAppKey          @"yIPfqwq6OMAPp6dkqgLpG5"
#define kGtAppSecret       @"G0aBqAD6t79JfzTB6Z5lo5"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // 通过Dcloud平台分配的appId、 appKey 、appSecret 启动SDK,注:该方法需要在主线程中调用
    [GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self];

    // 注册远程通知
    [GeTuiSdk registerRemoteNotification: (UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)];
    return YES;
}

4.5 获取CID信息

个推SDK初始化完成后,可以在GeTuiSdkDelegate GeTuiSdkDidRegisterClient回调方法中获取注册成功的ClientID(即CID)

/** SDK启动成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
    //个推SDK已注册,返回clientId
    NSLog(@"\n>>>[GeTuiSdk RegisterClient]:%@\n\n", clientId);
}

4.5 使用推送

推送使用方法,参考文档 UniPush使用指南

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

推荐阅读更多精彩内容

  • iOS 推送SDK 集成指南 本文介绍译码小二郎即时通讯如何集成推送SDK 1.简介 本 iOS SDK 方便开发...
    storywithyou阅读 239评论 0 0
  • 用到的组件 1、通过CocoaPods安装 2、第三方类库安装 3、第三方服务 友盟社会化分享组件 友盟用户反馈 ...
    SunnyLeong阅读 14,601评论 1 180
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,019评论 4 62
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,691评论 2 59
  • 张利平2021.3.6「学习《情绪按钮》第20天收获: [太阳]今天学习内容: 第七章《情绪的来源》(五)情绪的来...
    张利平专注国学教育139876阅读 5,073评论 1 3