小白也能掌握的個(gè)推iOS推送集成教程
一次偶然的機(jī)會(huì)贩汉,公司的項(xiàng)目要用到推送,我自己本來(lái)就很懶臣疑,不愿意去弄整套APNS的流程谒所,剛好之前跟朋友聊起過(guò)他們的產(chǎn)品中集成了個(gè)推的Android推送,說(shuō)是體驗(yàn)還可以消返,那這次我就試一下他們的iOS推送载弄。于是抱著試一試的心態(tài)耘拇,我先建個(gè)demo,試著去集成一下個(gè)推iOS推送SDK宇攻,摸索著完成了整個(gè)流程惫叛,言歸正傳,直接上硬菜逞刷!
如何集成個(gè)推iOS SDK
看了個(gè)推的官網(wǎng)嘉涌,發(fā)現(xiàn)他們集成的方式有兩種,分別是XCode集成和CocoaPods集成夸浅。本人比較懶仑最,越簡(jiǎn)單越好,越輕松越好帆喇,毫不猶豫的選擇了Cocoapods集成方式警医,程序猿么,就是要想盡辦法的懶坯钦,搞起预皇!
CocoaPods集成
1.安裝CocoaPods
安裝方式簡(jiǎn)單, Mac 下都自帶 ruby,使用 ruby 的 gem 命令即可下載安裝:
$ sudo gem install cocoapods
$ pod setup
2.準(zhǔn)備Podfile文件
在我們的工程目錄下婉刀,新建一個(gè)名為Podfile的文件吟温,如下格式,將依賴的庫(kù)名字依次列在文件中即可:
作者這里使用的是標(biāo)準(zhǔn)版本:
target 'GeTuipush' do
platform :ios, "7.0"
pod 'GTSDK'
end
target 'NotificationService' do
platform :ios, "10.0"
pod 'GTExtensionSDK'
end
3.完成GTSDK導(dǎo)入
在項(xiàng)目根目錄中執(zhí)行如下命令:
$ pod install
執(zhí)行完成后突颊,項(xiàng)目目錄結(jié)構(gòu)如下圖所示:
注意:在pod install之前鲁豪,首先你的工程必須創(chuàng)建好,并且如果Podfile文件里面如果有target:NotificationService洋丐,那在pod install之前需要?jiǎng)?chuàng)建好通知擴(kuò)展的Target呈昔。
4.開(kāi)啟推送功能:既然是推送挥等,當(dāng)然是要開(kāi)推送功能啦友绝!
5.后臺(tái)運(yùn)行權(quán)限設(shè)置:看個(gè)推的官網(wǎng)上面說(shuō)是為了更好的支持消息推送,提供更多的推送樣式肝劲,提高消息到達(dá)率迁客,既然這么說(shuō)了,那就不管三七二十一先開(kāi)了再說(shuō)辞槐,如下圖所示:
6.XCode10建議開(kāi)啟WiFi信息授權(quán):在 Xcode 10.x 以上掷漱,找到應(yīng)用Target設(shè)置中的Capabilities -> Access WiFi Information,確認(rèn)開(kāi)關(guān)已經(jīng)設(shè)為ON狀態(tài)榄檬。如下圖所示:
注意:主Target和通知擴(kuò)展的Target都需要打開(kāi)
7.代碼部分卜范,下來(lái)就是我們程序猿最喜歡的部分了,粘貼復(fù)制鹿榜。由于是第一次集成個(gè)推SDK的代碼海雪,我還是仔細(xì)的研究了下锦爵。
初始化SDK注冊(cè)APNs并獲取CID
1.為AppDelegate增加回調(diào)接口類(lèi):
#import <UIKit/UIKit.h>
#import <GTSDK/GeTuiSdk.h>
// iOS10 及以上需導(dǎo)入 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并注冊(cè)APNs:
#import "AppDelegate.h"
/// 個(gè)推開(kāi)發(fā)者網(wǎng)站中申請(qǐng)App時(shí),注冊(cè)的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];
// 注冊(cè) APNs
[self registerRemoteNotification];
return YES;
}
注冊(cè)APNs獲取DeviceToken:
/** 注冊(cè) 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];
}
個(gè)推demo里面給開(kāi)發(fā)者提供演示代碼,根據(jù)APP支持的iOS系統(tǒng)不同湾宙,進(jìn)行修改樟氢。我們的工程最低支持iOS10。
獲取CID信息:
/** SDK啟動(dòng)成功返回cid */
- (void)GeTuiSdkDidRegisterClient:(NSString *)clientId {
NSLog(@"clientId:%@", clientId);
}
這三個(gè)參數(shù)kGtAppId侠鳄、kGtAppKey埠啃、kGtAppSecret是干啥用的,這三個(gè)參數(shù)如何獲取?回頭又看了下個(gè)推的官網(wǎng)才搞明白伟恶,正好記錄下如何申請(qǐng)者三個(gè)參數(shù)霸妹,跟我應(yīng)用的bundleID綁定。
如何獲取kGtAppId知押、kGtAppKey叹螟、kGtAppSecret
1.創(chuàng)建個(gè)推開(kāi)發(fā)者賬號(hào)
訪問(wèn)個(gè)推開(kāi)發(fā)者中心,申請(qǐng)個(gè)推賬號(hào)
2.登記新應(yīng)用
注意:登記新應(yīng)用是在應(yīng)用管理頁(yè)面而不是消息推送頁(yè)面台盯。
在登記應(yīng)用界面填寫(xiě)應(yīng)用名和應(yīng)用表示罢绽,勾選個(gè)推產(chǎn)品,勾選iOS静盅,填寫(xiě)包名和bundleID,如下圖所示:
這里我有點(diǎn)疑惑良价。創(chuàng)建應(yīng)用的時(shí)候想勾選iOS,但是看到默認(rèn)選擇了Android平臺(tái)蒿叠,并要填寫(xiě)Android簽名明垢,這簽名是what,這如何搞市咽?看到跟前有個(gè)提示如何獲取痊银,點(diǎn)了一下,發(fā)現(xiàn)里面有SHA256的簽名施绎,抱著試一試的態(tài)度溯革,直接copy過(guò)來(lái),呦呵谷醉,能用哦致稀,心里美滋滋。
提交成功后就可以獲取到kGtAppId俱尼、kGtAppKey抖单、kGtAppSecret,將三個(gè)參數(shù)填入我們的工程中,然后運(yùn)行工程矛绘,在GeTuiSdkDidRegisterClient的回調(diào)方法中獲取到cid了躺酒,嗯,看來(lái)我們已經(jīng)成功了一一小部分了蔑歌,距離成功還要繼續(xù)加油羹应。
注冊(cè)DeviceToken并統(tǒng)計(jì)APNs通知的點(diǎn)擊數(shù)
1.向個(gè)推服務(wù)器注冊(cè)DeviceToken:
/** 遠(yuǎn)程通知注冊(cè)成功委托 */
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//向個(gè)推服務(wù)器注冊(cè)deviceToken 為了方便開(kāi)發(fā)者,建議使用新方法
NSLog(@"deviceToken:%@",deviceToken);
[GeTuiSdk registerDeviceTokenData:deviceToken];
}
2.處理APNs通知點(diǎn)擊事件:
因?yàn)槲覀兊墓こ套畹瓦m配到iOS10次屠,這里我就只添加了iOS10及以后版本的通知點(diǎn)擊事件园匹,要是想兼容iOS10以下的,可以在個(gè)推的demo中找到劫灶。
iOS 10及以后版本裸违,處理APNs通知點(diǎn)擊事件
// iOS 10: 點(diǎn)擊通知進(jìn)入App時(shí)觸發(fā),在該方法內(nèi)統(tǒng)計(jì)有效用戶點(diǎn)擊數(shù)
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSLog(@"didReceiveNotification:%@", response.notification.request.content.userInfo);
// [ GTSdk ]:將收到的APNs信息傳給個(gè)推統(tǒng)計(jì)
[GeTuiSdk handleRemoteNotification:response.notification.request.content.userInfo];
completionHandler();
}
3.接受個(gè)推通道下發(fā)的透?jìng)飨ⅲ?/p>
/** SDK收到透?jìng)飨⒒卣{(diào) */
- (void)GeTuiSdkDidReceivePayloadData:(NSData *)payloadData andTaskId:(NSString *)taskId andMsgId:(NSString *)msgId andOffLine:(BOOL)offLine fromGtAppId:(NSString *)appId {
//收到個(gè)推消息
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);
}
獲取到了透?jìng)飨⒈净瑁钱?dāng)應(yīng)用在后臺(tái)或者應(yīng)用殺死的情況下供汛,我們?nèi)绾潍@取到APNs消息,這里我們就需要在個(gè)推平臺(tái)用到推送證書(shū)涌穆,如何獲取推送證書(shū)怔昨?因?yàn)楸救艘彩堑谝淮胃阃扑瓦@書(shū),而且也踩了不少的坑宿稀,為了下次不再踩同樣的坑趁舀,所以在這里就對(duì)如何制作推送證書(shū)進(jìn)行了一次規(guī)整。
如何制作推送證書(shū)祝沸?
1.進(jìn)入蘋(píng)果開(kāi)發(fā)者中心矮烹,選擇證書(shū)選項(xiàng),如下圖所示:
2.創(chuàng)建推送證書(shū)之前必須創(chuàng)建一個(gè)APPID,因?yàn)橥扑妥C書(shū)是和APPID綁定在一起的罩锐,如下圖所示:
在下面的App Services中選擇允許推送(Push Notifications)奉狈,如下圖所示:
3.APPID創(chuàng)建好了之后,這個(gè)時(shí)候需要去創(chuàng)建推送證書(shū)涩惑,而且還要根據(jù)需要的環(huán)境選擇對(duì)應(yīng)的推送證書(shū)仁期,包括開(kāi)發(fā)環(huán)境推送證書(shū)和生產(chǎn)環(huán)境推送證書(shū),然后還要跟剛才創(chuàng)建好的APPID相關(guān)聯(lián)境氢,如下圖所示:
這個(gè)時(shí)候需要上傳CSR文件蟀拷,我們回到桌面碰纬,打開(kāi)鑰匙串萍聊,從頒發(fā)機(jī)構(gòu)申請(qǐng)證書(shū)并保存到本地磁盤(pán),如下圖所示:
這樣CSR文件就創(chuàng)建好了悦析,我們回到蘋(píng)果開(kāi)發(fā)者中心寿桨,繼續(xù)創(chuàng)建我們的推送證書(shū),選擇保存到本地的CSR文件,如下圖所示:
這樣亭螟,我們的推送證書(shū)就創(chuàng)建完成了挡鞍,在本地下載中找到下載的推送證書(shū)并雙擊添加到鑰匙串中,然后打開(kāi)鑰匙串找到創(chuàng)建好的推送證書(shū)预烙,右鍵導(dǎo)出P12證書(shū)墨微,并輸入證書(shū)密碼,如下圖所示:
4.打開(kāi)個(gè)推開(kāi)發(fā)者中心扁掸,在個(gè)推·消息推送-應(yīng)用列表-應(yīng)用配置”中上傳正確的APNs證書(shū)翘县,如下圖所示:
接下來(lái)最重要的時(shí)刻來(lái)了,那就是測(cè)試了谴分,看看我們的推送能不能成功锈麸。
推送測(cè)試
本人是在個(gè)推平臺(tái)上面進(jìn)行推送測(cè)試的,在應(yīng)用列表里面點(diǎn)擊之前創(chuàng)建的應(yīng)用上的創(chuàng)建推送按鈕牺蹄,如下圖所示:
進(jìn)入后忘伞,我有點(diǎn)懵逼,因?yàn)橹皼](méi)有了解過(guò)個(gè)推SDK的邏輯沙兰,在詢問(wèn)了個(gè)推技術(shù)支持后氓奈,技術(shù)支持告訴我怎么在個(gè)推平臺(tái)上面去推,也是自己太粗心了鼎天,人家進(jìn)去第一句話就寫(xiě)的很清楚探颈,推送通知目前僅支持安卓用戶,iOS請(qǐng)使用透?jìng)飨⒀荡搿擂挝苯冢∧蔷屯競(jìng)飨㈨?yè)面試試推。如下圖所示:
透?jìng)飨y(cè)試:
APNs消息測(cè)試
NICE啊绩鸣,這下應(yīng)用在前臺(tái)怀大、應(yīng)用在后臺(tái)和應(yīng)用被殺死的情況下都可以收到推送消息了,爽歪歪把轿拧化借!看來(lái)我們已經(jīng)成功看了百分之九十了!
Notification Service Extension
正在沾沾自喜的時(shí)候捡多,突然發(fā)現(xiàn)個(gè)推的官網(wǎng)上面還有多媒體推送蓖康,我靠,還有這種操作垒手,好奇心的趨勢(shì)下蒜焊,讓我重新審視如何去做多媒體推送。因?yàn)槲覀冎耙呀?jīng)把通知擴(kuò)展的target創(chuàng)建好了科贬,所以泳梆,直接上代碼。
1.Notification Service Extension 添加成功后會(huì)在項(xiàng)目中自動(dòng)生成 NotificationService.h 和 NotificationService.m 兩個(gè)類(lèi),包含以下兩個(gè)方法:
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *_Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// [ 測(cè)試代碼 ] TODO:用戶可以在這里處理通知樣式的修改优妙,eg:修改標(biāo)題乘综,開(kāi)發(fā)階段可以用于判斷是否運(yùn)行通知擴(kuò)展
//self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [WillIn]", self.bestAttemptContent.title];
// [ GTSDK ] 統(tǒng)計(jì)APNs到達(dá)情況和多媒體推送支持接口, 建議使用該接口
[GeTuiExtSdk handelNotificationServiceRequest:request withAttachmentsComplete:^(NSArray *attachments, NSArray *errors) {
// self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Success]", self.bestAttemptContent.title];
self.bestAttemptContent.attachments = attachments; // 設(shè)置通知中的多媒體附件
self.contentHandler(self.bestAttemptContent);
}];
}
我們可以在這個(gè)方法中處理我們的 APNs 通知,并個(gè)性化展示給用戶套硼。APNs 推送的消息送達(dá)時(shí)會(huì)調(diào)用這個(gè)方法卡辰,此時(shí)你可以對(duì)推送的內(nèi)容進(jìn)行處理,然后使用contentHandler方法結(jié)束這次處理邪意。但是如果處理時(shí)間過(guò)長(zhǎng)看政,將會(huì)進(jìn)入serviceExtensionTimeWillExpire方法進(jìn)行最后的緊急處理。
- (void)serviceExtensionTimeWillExpire {
// [ GTSDK ] 銷(xiāo)毀SDK抄罕,釋放資源
[GeTuiExtSdk destory];
//self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Timeout]", self.bestAttemptContent.title];
self.contentHandler(self.bestAttemptContent);
}
如果didReceiveNotificationRequest方法在限定時(shí)間內(nèi)沒(méi)有調(diào)用 contentHandler方法結(jié)束處理允蚣,則會(huì)在過(guò)期之前進(jìn)行回調(diào)本方法。此時(shí)你可以對(duì)你的 APNs 消息進(jìn)行緊急處理后展示呆贿,如果沒(méi)有處理嚷兔,則顯示原始 APNs 推送。
接下來(lái)就是測(cè)試我們的多媒體推送是否成功做入,我在網(wǎng)上找了個(gè)小狗的照片冒晰,直接在個(gè)推平臺(tái)上面推。
多媒體測(cè)試
6啊竟块,終于搞定了壶运!棒棒噠~~~
但是,之前的一個(gè)老項(xiàng)目說(shuō)也要集成推送浪秘,我透蒋情,老項(xiàng)目要用XCode集成,這對(duì)于我這種懶人來(lái)說(shuō)耸携,簡(jiǎn)直是一種折磨啊棵癣,哎,折磨歸折磨夺衍,該搞還要搞狈谊。但是之前已經(jīng)用CocoaPods搞過(guò)一遍,這次用XCode集成還不是手到擒來(lái)沟沙。但是為了防止出錯(cuò)河劝,本人還是先做了個(gè)demo,這樣后面在自己項(xiàng)目上面集成的話把握性會(huì)更大矛紫,踩的坑也就會(huì)更少赎瞎。
Xcode集成
1.導(dǎo)入個(gè)推SDK:
2.庫(kù)引用檢查:
3.添加系統(tǒng)依賴庫(kù):
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 (如果使用無(wú)IDFA版本SDK含衔,則需刪除該 AdSupport 庫(kù))
幸虧后面的步驟基本上都是一樣的煎娇,唯一的欣慰呀二庵!
4.開(kāi)啟推送功能贪染、后臺(tái)運(yùn)行權(quán)限設(shè)置缓呛、開(kāi)啟WiFi信息授權(quán)
這里跟上面步驟一樣,就不啰嗦了杭隙。
5.copy代碼哟绊,這是我們程序猿最喜歡的啦,哈哈哈痰憎,之前搞過(guò)票髓,這里就不累贅了。
6.添加Notification Service Extension
(1).打開(kāi)XCode铣耘,菜單中選擇File->New->Target->Notification Service Extension洽沟。如下圖所示:
注意:1.Extension的Bundle Identifier不能和Main Target(也就是自己的App Target)的Bundle Identifier相同,否則會(huì)報(bào)BundleID重復(fù)的錯(cuò)誤蜗细。2.Extension 的 Bundle Identifier 需要在 Main Target 的命名空間下裆操,比如說(shuō) Main Target 的 BundleID 為 ent.getui.xxx,那么Extension的BundleID應(yīng)該類(lèi)似與ent.getui.xxx.yyy這樣的格式炉媒。如果不這么做踪区,會(huì)引起命名錯(cuò)誤。
這個(gè)是在個(gè)推官網(wǎng)上面看到的吊骤,之前自己也踩了這個(gè)坑缎岗,這里就記錄下來(lái)。
添加 Notification Service Extension 后會(huì)生成相應(yīng)的 Target白粉。點(diǎn)Finish按鈕后會(huì)彈出是否激活該 Target 對(duì)應(yīng) scheme 的選項(xiàng)框传泊,選擇 Activate,如果沒(méi)有彈出該選項(xiàng)框鸭巴,需要自行添加相應(yīng)的 scheme或渤。如下圖所示:
(2).Notification Service Extension 添加成功后會(huì)在項(xiàng)目中自動(dòng)生成 NotificationService.h 和 NotificationService.m 兩個(gè)類(lèi)
這里跟上面一樣,就不累贅了奕扣。
(3).添加GtExtensionSdk依賴庫(kù)
選擇Notification Service Extension所對(duì)應(yīng)的Target薪鹦,添加如下依賴庫(kù):
libz.tbd
libsqlite3.tbd
GTExtensionSDK.framework
UserNotifications.framework
(4).XCode10建議開(kāi)啟WiFi信息授權(quán):在 Xcode 10.x 以上,找到應(yīng)用Target設(shè)置中的Capabilities -> Access WiFi Information惯豆,確認(rèn)開(kāi)關(guān)已經(jīng)設(shè)為ON狀態(tài)池磁。如下圖所示:
(5).開(kāi)啟多媒體地址Http訪問(wèn)支持:
集成過(guò)程中遇到的問(wèn)題
無(wú)效的deviceToken
最讓我印象深刻的就是無(wú)效的deviceToken,在測(cè)試APNS推送的時(shí)候楷兽,詢問(wèn)過(guò)個(gè)推那邊的技術(shù)支持地熄,他們說(shuō)可以先在應(yīng)用配置里面測(cè)試一下,然后我就拿著我的deviceToken去測(cè)試一下芯杀,結(jié)果提示我是無(wú)效的deviceToken端考,我暈雅潭,然后繼續(xù)咨詢個(gè)推的技術(shù)支持,他們說(shuō)這個(gè)原因有可能是我證書(shū)環(huán)境的問(wèn)題却特。經(jīng)過(guò)一番仔細(xì)的檢查之后扶供,發(fā)現(xiàn),我在個(gè)推平臺(tái)上面上傳的是通用證書(shū)裂明,然后我XCode上面的授權(quán)證書(shū)是開(kāi)發(fā)環(huán)境下椿浓,這樣一來(lái),拿到的是開(kāi)發(fā)環(huán)境下的deviceToken闽晦,用測(cè)試一下扳碍,當(dāng)然會(huì)出錯(cuò)。
解決的方案有兩種:第一仙蛉,在個(gè)推開(kāi)發(fā)平臺(tái)上傳開(kāi)發(fā)環(huán)境下的推送證書(shū)笋敞。第二:將自己的授權(quán)證書(shū)更換為生產(chǎn)環(huán)境。
通知擴(kuò)展里面修改標(biāo)題的代碼不生效
self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [Success]", self.bestAttemptContent.title];
發(fā)現(xiàn)demo里面有這么一行代碼荠瘪,我把這行代碼打開(kāi)后夯巷,推送一條消息,發(fā)現(xiàn)標(biāo)題沒(méi)有變化巧还,我驚呆了鞭莽!詢問(wèn)個(gè)推技術(shù)支持,個(gè)推技術(shù)支持說(shuō)麸祷,讓我先運(yùn)行主target澎怒,然后再運(yùn)行通知擴(kuò)展阶牍,運(yùn)行通知擴(kuò)展的時(shí)候會(huì)讓我們?nèi)フ抑鱰argetAPP喷面,選擇主target,然后再推送就會(huì)有了走孽,嗯惧辈,想了下,這個(gè)應(yīng)該是XCode的bug磕瓷。
結(jié)語(yǔ)
最后盒齿,我要說(shuō),消息推送功能的集成對(duì)APP而言真的真的很重要困食。以上是個(gè)推iOS推送SDK集成的全步驟边翁,給大家做個(gè)參考。特別需要注意的幾點(diǎn)是:
1.在個(gè)推平臺(tái)上上傳的推送證書(shū)一定要正確并且要和自己的環(huán)境相對(duì)應(yīng)硕盹,推薦上傳P8證書(shū)符匾;
2.主target和通知擴(kuò)展target是兩個(gè)target,命名和bundleID上要注意瘩例,本人是按照個(gè)推官網(wǎng)給的建議命名的啊胶。