APNS
一、簡述APNS
APNS全稱是Apple Push Notification service(蘋果推送通知服務) 。是蘋果工程師們的杰作。早期iOS設備CPU和內存資源有限,為節約資源,系統不允許app進程常駐后臺,但是開發商需要有一個穩定的網絡通道能每隔一段時間推送新的內容到用戶設備,就是這個矛盾催促了apns的誕生。
二、APNS機制
apns的機制,官網上一張圖,已經說明了一切~
apns推送機制
三、APNS的限制
能夠有效收到apns推送,首先必須要確保設備處于online的狀態。其次蘋果只會存儲發送給用戶一條最新的推送,之前發送的推送會被舍棄。而且每條離線推送是有過期時間的。蘋果apns服務器每天要處理至少幾十億設置上百億條推送消息,所以偶然的一次推送不成功,就不要糾結了~
四、申請APNS推送證書
apns推送證書
如上圖所示,apns推送有生產證書和發布證書兩種,一般生產證書比較少會使用(前期與后臺調試使用,只能直推,可真機測試)。發布證書是上線使用的,根據發布證書生成p12文件,與配置文件一起發給后臺即可。
這里提一下,有使用推送功能的小伙伴,別忘了勾選上appid設置里的Push Notifications。
五、代碼設置
- 在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方法里做跳轉處理,本地推送也會執行此方法。
VoIP
一、簡述VoIP
VOIP全稱voice-over-ip,是iOS8新引入的一種推送方式類型。它可以使用戶收到一個來電時喚醒App。有了這種新推送,麻麻再也不用擔心App長時間在后臺被系統殺死的問題了,因為這種推送消息可以在后臺喚醒App。
二、申請VoIP推送證書
voip推送證書
VoIP推送證書只有發布證書,所以調試起來是個問題。小伙伴在處理這個問題上一定要有耐心。
三、xcode配置
-
xcode9之前配置主target下capabilities的Background Modes
VoIP配置2 -
xcode9+配置plist文件
VoIP配置1 -
Link Binary With Libraries里引入PushKit系統動態庫
引入系統庫
四、代碼設置
- 在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回調方法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回調方法didInvalidatePushTokenForType里清除問題deviceToken
NSUserDefaults *groupDefault = [[NSUserDefaults alloc] initWithSuiteName:EUCGroupDefaultsName];
[groupDefault setValue:checkValue(@"") forKey:EUCDeviceTokenKey];
[groupDefault synchronize];
- 在pushKit回調方法didReceiveIncomingPushWithPayload處理VoIP推送。一般做本地推送處理或者結合callKit彈出電話頁面。