很多同學(xué)在接入APNS服務(wù)的時(shí)候构捡,十有八九會(huì)遇到不少問題忠聚。尤其是在接某些第三方推送服務(wù)SDK的時(shí)候挠日。這里介紹一下如何使用Easy APNs Provider測(cè)試推送逮京,以后就可以判斷是在哪個(gè)環(huán)節(jié)出了問題了,非常方便腻窒。
推送設(shè)置
要實(shí)現(xiàn)推送需要兩個(gè)前提:
-
打開capabilities的push notifications選項(xiàng)
-
打開capabilities的background modes中的Remote notifications
當(dāng)然最為重要的還是需要在AppDelegate中寫相關(guān)的代碼昵宇,下面是一個(gè)簡單的例子磅崭,可以在這個(gè)邏輯更改儿子。很多同學(xué)會(huì)遇到為什么什么娶不到token的問題,原因就是或多或少你少了下面的某些代碼砸喻。
推送代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
[self registRemoteNotification];
return YES;
}
- (void)registRemoteNotification {
#ifdef __IPHONE_8_0
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
}
#else
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
#endif
}
#pragma mark - remote Notification
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)devToken {
NSString *devToken_str = [NSString stringWithFormat:@"%@",devToken];
devToken_str = [self removeSpace:devToken_str];
devToken_str = [self removeBracket:devToken_str];
NSLog(@"%@", devToken_str);
[[NSNotificationCenter defaultCenter] postNotificationName:@"PUSHTOEKN" object:nil userInfo:@{@"token":devToken_str}];
}
- (void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
NSLog(@"%@",error);
}
//ios 7.0
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"did recevive remote noti userInfo %@ for ios 7 ",userInfo);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
/**
* 系統(tǒng)會(huì)估量App消耗的電量柔逼,并根據(jù)傳遞的UIBackgroundFetchResult 參數(shù)記錄新數(shù)據(jù)是否可用
* 調(diào)用完成的處理代碼時(shí),應(yīng)用的界面縮略圖會(huì)自動(dòng)更新
*/
NSLog(@"did Receive Remote Notification userInfo %@",userInfo);
switch (application.applicationState) {
case UIApplicationStateActive:
completionHandler(UIBackgroundFetchResultNewData);
break;
case UIApplicationStateInactive:
completionHandler(UIBackgroundFetchResultNewData);
break;
case UIApplicationStateBackground:
completionHandler(UIBackgroundFetchResultNewData);
break;
default:
break;
}
}
- (NSString *)removeSpace:(NSString *)str{
NSString *r_str = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
return r_str;
}
- (NSString *)removeBracket:(NSString *)str{
NSString *r_str = [str stringByReplacingOccurrencesOfString:@"<" withString:@""];
r_str = [r_str stringByReplacingOccurrencesOfString:@">" withString:@""];
return r_str;
}
測(cè)試工具
這是一個(gè)良心的測(cè)試工具割岛,Mac AppStore下載地址Easy APNs Provider
具體使用頁面:
使用步驟按照界面所標(biāo)注的1——6進(jìn)行愉适,接下來分別介紹。
1. 添加Token
添加Token界面.
建議不要弄什么花里胡哨的癣漆,最好使用手動(dòng)添加维咸。
連接真機(jī)運(yùn)行,打Log獲取deviceToken
#pragma mark 注冊(cè)通知
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken
{
NSLog(@"deviceToken:%@",deviceToken);
}
注意:輸出的deviceToken是NSData類型的,要的就是這個(gè).
輸出的Log如下:
deviceToken:<9bf8412c 55df912e 12e689f3 4c4a4c72 361262bb efbdf526 e01ebb6d 223a80c9>
把那一串數(shù)字字符組合粘貼出來刪除空格癌蓖,然后復(fù)制粘貼到手動(dòng)添加的框里
注: 1瞬哼、不要token兩端的尖括號(hào) 2、空格刪完之后再添加租副,那個(gè)框框只能放64個(gè)字符,多的會(huì)自動(dòng)刪除
2. 添加證書
一般推送證書有一下三類坐慰。voip相關(guān)的證書可能有些同學(xué)用不到,這也沒關(guān)系用僧。這里講講Token和證書之間的關(guān)系结胀,非常非常重要!T鹧糟港!
- Token和推送證書必須配對(duì),也就是Debug下的Token院仿,不能用Release的推送證書着逐;Release下的Token,不能用Debug的推送證書意蛀,
-
蘋果會(huì)根據(jù)應(yīng)用是開發(fā)包(Debug)還是發(fā)布包(Release)發(fā)送不同的Token耸别。如下圖所示
3. 選擇蘋果APNS地址
Apple提供了Debug和Release的兩個(gè)地址,一個(gè)是gateway.sandbox.push.apple.com
县钥,另一個(gè)是gateway.sandbox.push.apple.com
秀姐。如下所示
同樣APNS地址和證書也必須匹配。
4. 設(shè)置推送內(nèi)容
支持推送的內(nèi)容有標(biāo)題若贮、內(nèi)容省有、未讀數(shù)(圖標(biāo))、聲音谴麦。比較遺憾的是沒有支持iOS10之后可以推送圖片視圖等入口蠢沿。不過對(duì)于一般推送而言已經(jīng)夠了。
不要被這里的圖標(biāo)所迷惑了匾效,其實(shí)這里的圖標(biāo)就是所謂的未讀數(shù)舷蟀。
注意一下Content-Avaliable:
5.發(fā)送推送
在發(fā)送之前一定要在步驟3的時(shí)候,連接到APNS地址
如果一切正常的情況下面哼,會(huì)在下面的信息框中提示:
正在連接到gateway.sandbox.push.apple.com
已連接至服務(wù)器野宜,正在驗(yàn)證身份...
身份已驗(yàn)證,您可以發(fā)送推送消息了魔策。
推送已嘗試發(fā)送至test匈子,APN識(shí)別:0x0BC5816B
當(dāng)然,如果你證書和服務(wù)器不匹配闯袒,則會(huì)提示:
正在連接到gateway.push.apple.com
已連接至服務(wù)器虎敦,正在驗(yàn)證身份...
身份已驗(yàn)證游岳,您可以發(fā)送推送消息了。
服務(wù)端主動(dòng)斷開連接其徙,這可能是由于證書錯(cuò)誤吭历,發(fā)送的數(shù)據(jù)錯(cuò)誤,網(wǎng)絡(luò)錯(cuò)誤等原因引起的擂橘。
如果你的token和證書不匹配晌区,則會(huì)提示:
正在連接到gateway.sandbox.push.apple.com
已連接至服務(wù)器,正在驗(yàn)證身份...
身份已驗(yàn)證通贞,您可以發(fā)送推送消息了朗若。
推送已嘗試發(fā)送至test,APN識(shí)別:0x22E82902
嘗試發(fā)送推送到test失敗昌罩,錯(cuò)誤描述:無效的設(shè)備Token哭懈,APN識(shí)別:0x22E82902
服務(wù)端主動(dòng)斷開連接,這可能是由于證書錯(cuò)誤茎用,發(fā)送的數(shù)據(jù)錯(cuò)誤遣总,網(wǎng)絡(luò)錯(cuò)誤等原因引起的。
6. 斷開連接
一般在想要換證書或者服務(wù)器地址的時(shí)候才需要斷開轨功,進(jìn)而重新建立連接旭斥。
可能遇到的問題
process launch failed
Debug環(huán)境運(yùn)行沒問題,Release環(huán)境會(huì)彈出以下提示:
解決辦法古涧,在Release的環(huán)境下去掉斷點(diǎn)即可垂券,參照下圖:
注:Debug executable 意思是是否可以斷點(diǎn)執(zhí)行,Release模式下不可以打斷點(diǎn)羡滑,所以這項(xiàng)要勾掉菇爪,勾掉之后不會(huì)影響Log的輸出。
token不匹配
一般在我們?cè)谏蟼鞣?wù)端token的時(shí)候會(huì)標(biāo)識(shí)當(dāng)前的環(huán)境是debug還是release環(huán)境下的token柒昏。我們簡稱devtype凳宙,0代表release,1代表debug职祷。那么在特別注意在debug環(huán)境下一定要傳1氏涩,release環(huán)境下傳0。而實(shí)際項(xiàng)目中往往有多個(gè)開關(guān)控制環(huán)境堪旧,比如調(diào)用的API的削葱、傳遞token的。千萬不要忘了其中一個(gè)淳梦!