APNS
一膀斋、簡述APNS
APNS全稱是Apple Push Notification service(蘋果推送通知服務(wù)) 痕慢。是蘋果工程師們的杰作旷余。早期iOS設(shè)備CPU和內(nèi)存資源有限棚菊,為節(jié)約資源,系統(tǒng)不允許app進程常駐后臺警检,但是開發(fā)商需要有一個穩(wěn)定的網(wǎng)絡(luò)通道能每隔一段時間推送新的內(nèi)容到用戶設(shè)備,就是這個矛盾催促了apns的誕生害淤。
二扇雕、APNS機制
apns的機制,官網(wǎng)上一張圖窥摄,已經(jīng)說明了一切~
apns推送機制
三镶奉、APNS的限制
能夠有效收到apns推送,首先必須要確保設(shè)備處于online的狀態(tài)崭放。其次蘋果只會存儲發(fā)送給用戶一條最新的推送哨苛,之前發(fā)送的推送會被舍棄。而且每條離線推送是有過期時間的币砂。蘋果apns服務(wù)器每天要處理至少幾十億設(shè)置上百億條推送消息建峭,所以偶然的一次推送不成功,就不要糾結(jié)了~
四道伟、申請APNS推送證書
apns推送證書
如上圖所示迹缀,apns推送有生產(chǎn)證書和發(fā)布證書兩種,一般生產(chǎn)證書比較少會使用(前期與后臺調(diào)試使用蜜徽,只能直推祝懂,可真機測試)。發(fā)布證書是上線使用的拘鞋,根據(jù)發(fā)布證書生成p12文件砚蓬,與配置文件一起發(fā)給后臺即可。
這里提一下盆色,有使用推送功能的小伙伴灰蛙,別忘了勾選上appid設(shè)置里的Push Notifications。
五隔躲、代碼設(shè)置
- 在didFinishLaunchingWithOptions方法里注冊apns推送摩梧。
UIApplication *application = [UIApplication sharedApplication];
application.applicationIconBadgeNumber = 0;
if (IOS10) { //iOS10+
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!error) {
NSLog(@"succeeded!");
}
}];
[application registerForRemoteNotifications];
} else if (IOS8_10){ //iOS8-iOS10
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
} else { //iOS8以下
[application registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
}
- 在didRegisterForRemoteNotificationsWithDeviceToken方法里獲取apns的deviceToken。
// 1.獲取deviceToken宣旱,并去除非法字符
NSString *deviceTokenStr = [[deviceToken description] stringByReplacingOccurrencesOfString:@" " withString:@""];
deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@"<" withString:@""];
deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@">" withString:@""];
// 2.保存deviceToken
NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName];
[groupDefault setValue:checkValue(deviceTokenStr) forKey:EUCDeviceTokenKey];
[groupDefault synchronize];
- 在didFailToRegisterForRemoteNotificationsWithError方法里清空問題deviceToken仅父。
NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName];
[groupDefault setValue:checkValue(@"") forKey:EUCDeviceTokenKey];
[groupDefault synchronize];
- iOS8在didRegisterUserNotificationSettings方法里注冊推送。
[application registerForRemoteNotifications];
- 在didReceiveRemoteNotification方法里做跳轉(zhuǎn)處理,本地推送也會執(zhí)行此方法笙纤。
VoIP
一耗溜、簡述VoIP
VOIP全稱voice-over-ip,是iOS8新引入的一種推送方式類型省容。它可以使用戶收到一個來電時喚醒App抖拴。有了這種新推送,麻麻再也不用擔(dān)心App長時間在后臺被系統(tǒng)殺死的問題了腥椒,因為這種推送消息可以在后臺喚醒App阿宅。
二、申請VoIP推送證書
voip推送證書
VoIP推送證書只有發(fā)布證書笼蛛,所以調(diào)試起來是個問題家夺。小伙伴在處理這個問題上一定要有耐心。
三伐弹、xcode配置
-
xcode9之前配置主target下capabilities的Background Modes
VoIP配置2 -
xcode9+配置plist文件
VoIP配置1 -
Link Binary With Libraries里引入PushKit系統(tǒng)動態(tài)庫
引入系統(tǒng)庫
四拉馋、代碼設(shè)置
- 在didFinishLaunchingWithOptions方法里注冊VoIP推送
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0)
{
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
}
- 在pushKit回調(diào)方法didUpdatePushCredentials里獲取VoIP的deviceToken
// 1.獲取deviceToken,并去除非法字符
NSString *deviceTokenStr = [[credentials.token description] stringByReplacingOccurrencesOfString:@" " withString:@""];
deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@"<" withString:@""];
deviceTokenStr = [deviceTokenStr stringByReplacingOccurrencesOfString:@">" withString:@""];
// 2.本地保存deviceToken
NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName];
[groupDefault setValue:checkValue(deviceTokenStr) forKey:EUCDeviceTokenKey];
[groupDefault synchronize];
- 在pushKit回調(diào)方法didInvalidatePushTokenForType里清除問題deviceToken
NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName];
[groupDefault setValue:checkValue(@"") forKey:EUCDeviceTokenKey];
[groupDefault synchronize];
- 在pushKit回調(diào)方法didReceiveIncomingPushWithPayload處理VoIP推送惨好。一般做本地推送處理或者結(jié)合callKit彈出電話頁面煌茴。