Due to a recent project on voip services, a note: We all know that when an application exits to the background, the socket is disconnected and the application is suspended. What we’re going to do now is wake up our APP directly in this case.
PushKit background
PushKit is apple’s new framework for ios8, a new type of push notification called voip push. PushKit is designed to be different from normal APNs push in that it doesn’t pop up a notification. Instead, it simply wakes up your APP and goes into a callback, which means we can run our own code without hitting the APP launch button.
Official introduction to PushKit :(Developer.apple.com/documentati…)
The PushKit framework sends specific types of notifications (such as VoIP invitations, watchOS complexity updates, and file provider change notifications) directly to your application for processing.
PushKit notifications are different from the notifications you handle using the UserNotifications framework. Specifically, PushKit notifications never display an alert, mark an app’s icon, or play a sound. They also have the following advantages over user notifications:
- The device only wakes up when it receives a PushKit notification, which extends battery life.
- After receiving PushKit notification, the system will automatically start the application if it is not running. In contrast, user notification does not guarantee that your application will start.
- The system handles PushKit notifications for your application execution time (possibly in the background).
- PushKit notifications can contain more data than user notifications.
Class PKPushRegistey (PKPushRegistey);
/* Target push type */ PK_EXPORT PKPushType const PKPushTypeVoIP NS_AVAILABLE_IOS(8_0); PK_EXPORT PKPushType const PKPushTypeComplication NS_AVAILABLE_IOS(9_0); //VOIP push PK_EXPORT PKPushType const PKPushTypeComplication NS_AVAILABLE_IOS(9_0); //Watch update PK_EXPORT PKPushType const PKPushTypeFileProvider NS_AVAILABLE_IOS(11_0); // File transfer NS_CLASS_AVAILABLE_IOS(8_0) @interface PKPushRegistry: NSObject @property (readwrite,weak,nullable) id<PKPushRegistryDelegate> delegate; // @property (readwrite,copy,nullable) NSSet<PKPushType> *desiredPushTypes; - (nullable NSData *)pushTokenForType:(PKPushType)type; // initialize and set the worker thread - (instancetype)initWithQueue:(nullable dispatch_queue_t)queue NS_DESIGNATED_INITIALIZER; @end@protocol PKPushRegistryDelegate <NSObject> @required // callback method after applying Token update - (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)pushCredentials forType:(PKPushType)type; @optional // callback method executed after receiving push - (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(PKPushType)type NS_DEPRECATED_IOS(8_0, 11_0); // Callback method executed after receiving push, The last block need active correction in logical processing is completed - (void) pushRegistry: (PKPushRegistry *) registry didReceiveIncomingPushWithPayload: (PKPushPayload *)payload forType:(PKPushType)type withCompletionHandler:(void(^)(void))completion NS_AVAILABLE_IOS(11_0); / / callback methods of Token fails - (void) pushRegistry: (PKPushRegistry *) registry didInvalidatePushTokenForType (PKPushType) type; @end NS_ASSUME_NONNULL_ENDCopy the code
PushKit Indicates the certificate application
Similar to APNs push, PushKit voip push also requires a certificate application. The procedure for applying a certificate is as follows:
According to the application step operation can be completed, I believe that everyone has the experience of applying for a certificate, here is not much mouth. After the certificate is generated, download it and double-click it to install it in the KeyChain. You need to export the key of the VoIP certificate in. P12 format from the KeyChain and send it to your background personnel. (The certificate format to be used by the background varies depending on the situation. P12 files are generated by nodes command to generate. Pem files for the background.)
Project configuration
As with APNS, you need to enable push and Background Capabilities in Project-> Capabilities, and Voice over IP in Background Modes. Enable both Background Fetch and Remote Notification options, and add pushKit. framework to Build Phases.
It is said that Xcode9 Background Modes do not have the Voice over IP option. If not, you can manually add it to the info.plist file. Add an App provides Voice over IP Services to Required Background Modes.
Simple code implementation
#import <PushKit/ pushkit. h> register PushKit. Note that PushKit is available for ios8 and later
If (CurrentSystemVersion floatValue > = 8.0) {PKPushRegistry * pushRegistry = [[PKPushRegistry alloc] initWithQueue: nil]; pushRegistry.delegate = self; pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP]; }Copy the code
Implement proxy method to obtain token:
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type { NSString * tokenString = [[[[credentials.token description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: "] stringByReplacingOccurrencesOfString: @ "@" "withString: @" "]; }Copy the code
The device obtains a VoIP token from apple servers, which is different from APNs. The APP passes the token it receives to the push server. (The process is similar to APNs, but the proxy method and token accepted are different.) The obtained token is also 64-bit, like APNs, with <> and Spaces removed.
Do receive push processing
/ / iOS 8.0-11.0 - (void) pushRegistry: (PKPushRegistry *) registry didReceiveIncomingPushWithPayload: (PKPushPayload *)payload forType:(NSString *)type {NSLog(@" receive push"); NSDictionary *dic=payload.dictionaryPayload[@"aps"]; UIUserNotificationType theType = [UIApplication sharedApplication].currentUserNotificationSettings.types; if (theType == UIUserNotificationTypeNone){ UIUserNotificationSettings *userNotifySetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:userNotifySetting]; } UILocalNotification *backgroudMsg = [[UILocalNotification alloc] init]; backgroudMsg.timeZone = [NSTimeZone defaultTimeZone]; backgroudMsg.alertBody= [dic objectForKey:@"alert" ]; backgroudMsg.soundName = [dic objectForKey:@"sound"]; [[UIApplication sharedApplication] presentLocalNotificationNow:backgroudMsg]; }Copy the code
PKPushRegistry. H file, in iOS8.0 to iOS11.0, the above proxy method is used to implement the wake up operation, but after iOS11.0, the system also provides another method:
/ / after the iOS 11.0 - (void) pushRegistry: (PKPushRegistry *) registry didReceiveIncomingPushWithPayload (PKPushPayload *) content forType:(PKPushType)type withCompletionHandler:(void(^)(void))completionCopy the code
If everything is normal, even if the program to kill process, restart, retreated to the background, the news of the server push over will walk this agent method, in order to see the content of the push here, here I am to receive the contents of the generated a local issue to the push, and play sounds, in this method should handle actually wake up APP after operation.
Push the test
Here I do push test when using the Easy APNs Provider application, it is very convenient to use. Attach the download address
1. The Token value to be sent must be added in three ways:
2. Select the voip_services.cer certificate.
3. Connect to the server. Select Sandbox for Debug mode and Push for Release mode.Then click the “Connect to” button to check whether the connection is successful.
4. Set the content to be sent (push load)
5. Click Send Push.