iOS 推送SDK 集成指南
本文介紹譯碼小二郎即時通訊如何集成推送SDK
1.簡介
本 iOS SDK 方便開發(fā)者基于個推來快捷地為 iOS 應(yīng)用增加推送功能,減少開發(fā)者集成 APNs(Apple Push Notification Service) 需要的工作量,降低開發(fā)復(fù)雜度。
個推推送是一個端到端的推送服務(wù),通過集成個推SDK,開發(fā)者能夠及時有效地將服務(wù)端消息推送到客戶端上,從而積極地保持與用戶的連接,并提高用戶活躍度和留存率。
2.主要功能及特點
(1).個推iOS SDK為應(yīng)用提供推送服務(wù),當(dāng)應(yīng)用在前臺時,維持與推送服務(wù)器的長連接,實時接收推送消息;當(dāng)應(yīng)用在后臺時,通過蘋果APNs推送通知。
(2).集成簡單快速。
(3).可以根據(jù)用戶屬性建立不同標(biāo)簽,進行定向推送。
(4).個推SDK不僅提供云端到客戶端的推送服務(wù),也提供從客戶端上傳至云端的消息服務(wù),即推送消息鏈路支持上下行雙向通道,開發(fā)者與云端之間互動更便利。
(5).支持 APNs 多媒體推送和通知的展示、點擊統(tǒng)計功能。
(6).支持 iOS10 及以上多媒體推送展示。
3.技術(shù)要點
3.1 離線用戶通過APNs下發(fā)通知
由于iOS系統(tǒng)限制,應(yīng)用在后臺無法長時間運行,從而無法維持與服務(wù)端的長連接。個推服務(wù)器發(fā)送消息給離線用戶時,會通過蘋果提供的 APNs 發(fā)送通知到用戶設(shè)備上。需要應(yīng)用開發(fā)者在個推開發(fā)者平臺上提交 APNs 推送證書。
3.2 創(chuàng)建Apple應(yīng)用ID和APNs推送證書
應(yīng)用開發(fā)者需要使用蘋果開發(fā)帳號,在https://developer.apple.com/中創(chuàng)建應(yīng)用ID,并生成推送證書。
相關(guān)操作流程,請參照:創(chuàng)建APNs推送證書
4.推送流程
個推 iOS 推送服務(wù)框架如下圖所示:
[圖片上傳失敗...(image-5ce0d5-1654659957653)]
個推 iOS 推送包括 2 個部分,APNs推送與應(yīng)用內(nèi)消息。
綠色部分是 APNs 推送,個推平臺替開發(fā)者的應(yīng)用通過蘋果 APNs 服務(wù)器向指定的目標(biāo)設(shè)備進行推送。由 APNs Server 將通知推送到相應(yīng)的 iOS 設(shè)備上。
紅色部分是個推應(yīng)用內(nèi)推送部分,即 App 啟動時,應(yīng)用內(nèi)集成的個推SDK會開啟長連接到個推服務(wù)器,從而開發(fā)者可通過個推服務(wù)器推送消息到 App 里,這條鏈路性能和穩(wěn)定性更強,是APNs的一個很重要的補充。
開始集成
1.pods方式 導(dǎo)入 SDK
1.cd 至項目根目錄
2.執(zhí)行 pod init
3.執(zhí)行open -e Podfile
4.添加導(dǎo)入配置
如果使用標(biāo)準(zhǔn)版本:
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代表當(dāng)前最新版本號
end
此處以集成標(biāo)準(zhǔn)版本為例
5.執(zhí)行 pod install
6.雙擊打開 .xcworkspace
注意事項:
1.pod 'GTSDK'為添加在主 target 上
2.在 App 內(nèi)無廣告情況下還是建議開發(fā)者使用獲取 IDFA 版本,并參考【IDFA版SDK注意事項說明】中所說的方式提交 AppStore 審核。當(dāng)然,如果開發(fā)者不想使用 IDFA 或者擔(dān)憂采集 IDFA 而未集成任何廣告服務(wù)遭到 Apple 拒絕,我們也準(zhǔn)備了該無 IDFA 版本供開發(fā)者集成。
2.手動方式 導(dǎo)入 SDK
(1).個推iOS SDK資料包結(jié)構(gòu)
GETUI_IOS_SDK/
|- readme.txt (SDK資料包說明)
|- Lib/
| |- GtSdkLib/ (標(biāo)準(zhǔn)版?zhèn)€推SDK.framework文件)
| | |- GTExtensionSDK.framework
| | |- GTSDK.framework
| |- GtSdkLib-noidfa/ (無IDFA版?zhèn)€推SDK.framework文件)
| | |- GTExtensionSDK.framework
| | |- GTSDK.framework
| - Demo/
| |- GtSdkDemo-Manual/ (Objective-C手動集成演示Demo工程)
| |- GtSdkDemo-Pods/ (Objective-C CocoaPods集成演示Demo工程)
| |- GtSdkDemo-Swift/ (Swift標(biāo)準(zhǔn)集成框架代碼工程)
| |- GtSdkDemo-SwiftUI/ (SwiftUI標(biāo)準(zhǔn)集成框架代碼工程)
| |- GtSdkLib/ (個推SDK庫文件,供上述Demo工程引用)
GtSdkDemo-Manual:Objective-C手動集成演示Demo工程。
GtSdkDemo-Pods:Objective-C Cocoapods集成 Demo。
GtSdkDemo-Swift: Swift 集成 Demo,方便 Swift 開發(fā)者集成個推 SDK。
GtSdkDemo-SwiftUI: SwiftUI 集成 Demo,方便 SwiftUI 開發(fā)者集成個推 SDK。
GtSdkLib:標(biāo)準(zhǔn)版?zhèn)€推SDK,包含集成所需的靜態(tài)庫和頭文件
使用標(biāo)準(zhǔn)版本SDK需添加AdSupport.framework庫支持
GtSdkLib-noidfa:無IDFA版?zhèn)€推SDK,包含集成所需的靜態(tài)庫和頭文件。
在 App 內(nèi)無廣告情況下還是建議開發(fā)者使用獲取 IDFA 版本,并參考【IDFA版SDK注意事項說明】中所說的方式提交 AppStore 審核。當(dāng)然,如果開發(fā)者不想使用 IDFA 或者擔(dān)憂采集 IDFA 而未集成任何廣告服務(wù)遭到 Apple 拒絕,我們也準(zhǔn)備了該無 IDFA 版本供開發(fā)者集成。
使用無IDFA版本SDK需刪除AdSupport.framework庫支持
GTSDK.framework:個推SDK核心庫文件,支持i386、x86_64、arm64、armv7,因此同時支持simulator和device設(shè)備。
(2).導(dǎo)入個推SDK資源
打開自己的xcode工程,將GTSDK.framework添加到項目工程目錄下:
[圖片上傳失敗...(image-622acb-1654659957654)]
[圖片上傳失敗...(image-b6f17d-1654659957654)]
庫引用檢查
在導(dǎo)入時,Xcode正常情況下會自動添加引用,但是偶爾也會不添加,注意檢查下圖中的引用路徑,如果報錯找不到庫或者頭文件,一般都是下面的引用沒有添加。
[圖片上傳失敗...(image-42c50b-1654659957654)]
添加 Other Linker Flags: -ObjC
[圖片上傳失敗...(image-e46d36-1654659957654)]
在項目設(shè)置中添加以下系統(tǒng)庫支持:
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-74e73d-1654659957654)]
IDFA版SDK注意事項說明
在 App 內(nèi)無廣告情況下還是建議開發(fā)者使用獲取 IDFA 版本,可參考下圖中所說的方式提交 AppStore 審核。當(dāng)然,如果開發(fā)者不想使用 IDFA 或者擔(dān)憂采集 IDFA 而未集成任何廣告服務(wù)遭到 Apple 拒絕,我們也準(zhǔn)備了該無 IDFA 版本供開發(fā)者集成。
注意事項:
(1)、在 App 內(nèi)投放廣告,獲取 IDFA 可通過蘋果審核。
(2)、App 內(nèi)無廣告,但由于先前投放的特定廣告,可參考如下勾選,通過蘋果審核。
[圖片上傳失敗...(image-c3c6fa-1654659957654)]
3.項目配置
3.1 開啟推送功能
在 Xcode 11.x 以上,必須開啟Push Notification能力。找到應(yīng)用Target設(shè)置中的Signing & Capabilities,點擊左上角+添加。如果沒有開啟該開關(guān),應(yīng)用將獲取不到DeviceToken:
[圖片上傳失敗...(image-549b01-1654659957654)]
3.2 后臺運行權(quán)限設(shè)置
為了更好支持消息推送,提供更多的推送樣式,提高消息到達率,需要配置后臺運行權(quán)限:
[圖片上傳失敗...(image-ab8f42-1654659957654)]
Remote notifications:APNs靜默推送權(quán)限
4. 編寫集成代碼
4.1 在 AppDelegate 中實現(xiàn)個推回調(diào)接口
為AppDelegate增加回調(diào)接口類。示例代碼如下:
// AppDelegate.h
#import <UIKit/UIKit.h>
#import <GTSDK/GeTuiSdk.h> // GetuiSdk頭文件
@interface AppDelegate : UIResponder <UIApplicationDelegate, GeTuiSdkDelegate>
實現(xiàn)個推回調(diào)接口,示例代碼如下:
/// 通知展示(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];
// [ 參考代碼,開發(fā)者注意根據(jù)實際需求自行修改 ] 根據(jù)APP需要,判斷是否要提示用戶Badge、Sound、Alert等
//completionHandler(UNNotificationPresentationOptionNone); 若不顯示通知,則無法點擊通知
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert);
}
/// 收到通知信息
/// @param userInfo apns通知內(nèi)容
/// @param center UNUserNotificationCenter(iOS10及以上版本)
/// @param response UNNotificationResponse(iOS10及以上版本)
/// @param completionHandler 用來在后臺狀態(tài)下進行操作(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) {
// [ 參考代碼,開發(fā)者注意根據(jù)實際需求自行修改 ] 根據(jù)APP需要自行修改參數(shù)值
completionHandler(UIBackgroundFetchResultNoData);
}
}
/// 收到透傳消息
/// @param userInfo 推送消息內(nèi)容
/// @param fromGetui YES: 個推通道 NO:蘋果apns通道
/// @param offLine 是否是離線消息,YES.是離線消息
/// @param appId 應(yīng)用的appId
/// @param taskId 推送消息的任務(wù)id
/// @param msgId 推送消息的messageid
/// @param completionHandler 用來在后臺狀態(tài)下進行操作(通過蘋果apns通道的消息 才有此參數(shù)值)
- (void)GeTuiSdkDidReceiveSlience:(NSDictionary *)userInfo fromGetui:(BOOL)fromGetui offLine:(BOOL)offLine appId:(NSString *)appId taskId:(NSString *)taskId msgId:(NSString *)msgId fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// [ GTSDK ]:匯報個推自定義事件(反饋透傳消息),開發(fā)者可以根據(jù)項目需要決定是否使用, 非必須
// [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) {
// [ 參考代碼,開發(fā)者注意根據(jù)實際需求自行修改 ] 根據(jù)APP需要自行修改參數(shù)值
completionHandler(UIBackgroundFetchResultNoData);
}
}
- (void)GeTuiSdkNotificationCenter:(UNUserNotificationCenter *)center openSettingsForNotification:(UNNotification *)notification {
// [ 參考代碼,開發(fā)者注意根據(jù)實際需求自行修改 ] 根據(jù)APP需要自行修改參數(shù)值
}
- (void)GeTuiSdkDidOccurError:(NSError *)error {
NSString *msg = [NSString stringWithFormat:@"[ TestDemo ] [GeTuiSdk GeTuiSdkDidOccurError]:%@\n\n",error.localizedDescription];
// SDK發(fā)生錯誤時,回調(diào)異常錯誤信息
NSLog(@"%@", msg);
}
4.2 初始化SDK并注冊APNs
在AppDelegate didFinishLaunchingWithOptions方法中調(diào)用個推sdk初始化方法,傳入DCloud平臺分配的 AppID、AppKey、AppSecret。同時,調(diào)用APNs注冊方法,嘗試獲取APNs DeviceToken。示例代碼如下:
/// DCloud開發(fā)者網(wǎng)站中申請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,注:該方法需要在主線程中調(diào)用
[GeTuiSdk startSdkWithAppId:kGtAppId appKey:kGtAppKey appSecret:kGtAppSecret delegate:self];
// 注冊遠程通知
[GeTuiSdk registerRemoteNotification: (UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge)];
return YES;
}
4.3 獲取CID信息
個推SDK初始化完成后,可以在GeTuiSdkDelegate GeTuiSdkDidRegisterClient回調(diào)方法中獲取注冊成功的ClientID(即CID)
/** SDK啟動成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
//個推SDK已注冊,返回clientId
NSLog(@"\n>>>[GeTuiSdk RegisterClient]:%@\n\n", clientId);
}