IOS push remote push (iOS Notification Of Remote Notification)

Note: This article only now can not fit iOS10, iOS10 push using a new method to do iOS9 and below the system can read this article.

The company recently upgrade reconstruction (Rewriting) in addition to the original, I am responsible for the module, then finally stepped in to push (local and remote) related modules, the way to push the knowledge over. Work on the last day of ten consecutive days later through the night (blind) (AO) of (a) Dan (night), is also have succeeded in carrying out an assignment. This article in addition to explain the basic knowledge related to remote push, it will involve some push related techniques. In addition, this article mainly to explain the remote push, the follow-up will be a iOS push local push (iOS Notification Of Local) sister articles.

The logic of this article is as shown below:

Figure IOS push remote push (iOS Notification Of Remote Notification)
0-0 this article logic diagram

Remote push principle

Learn something before I thought it best to understand the principle of it, so that when we meet some problems, you can quickly find where the mistakes, if not interested in principle students can directly turn to the remote application part [push].

Most of the iOS app is based on the development of client/server mode, client is installed on our device app, server is a remote server, mainly to provide data for our app, because it is also known as Provider. So the question is, when App is in the Terminate state, when client and server disconnect, client how to communicate with server? Yes, this time Remote Notifications is a good solution to this dilemma. Apple provides a service called Apple Push service Notification, is what we call the APNs.

Push message transfer path: Provider-APNs-Client App

Our equipment network (either cellular network or Wi-Fi network) will establish a long connection with Apple’s APNs server (persistent IP connection), when the Provider push a notice, the notice is not directly pushed to our equipment, and is the first to push Apple’s APNs server above, while Apple’s APNs server with equipment to establish the long connection and the notice pushed to our equipment (see Figure 1-1 and Figure 1-2). And when the device is in the non state of things, the last one to tell the APNs server will retain the Provider push, when the device into a state of networking, APNs put a final notice of its reservation to our equipment; if the equipment long time in non network state, then a final notice APNs the server is saved would be lost. Remote Notification must be able to receive the device in a networked state, and receiving a remote push notification too often has an impact on the battery life of the device.

IOS push remote push (iOS Notification Of Remote Notification)
1-1 Pushing remote from a provider a to client app notification a
IOS push remote push (iOS Notification Of Remote Notification)
1-2 Pushing notifications multiple providers to multiple remote from devices

Generation of deviceToken

When a App is registered to receive remote notification, the system will send a APNs request to the server, the APNs server receives the request according to the request with the key value of the one and only generates a value value also is called the deviceToken, then the APNs server will put this deviceToken package into a NSData object to send to the corresponding request App. Then App sends this deviceToken to our own server, which is called Provider. Provider received deviceToken after storage and other related processing, after the Provider to our device push notification, you must include this deviceToken. (refer to figure 1-3, figure 1-4)

Figure IOS push remote push (iOS Notification Of Remote Notification) 1-3 Managing the device token
Figure IOS push remote push (iOS Notification Of Remote Notification) 1-4 Sharing the device token

This time you might ask deviceToken what is it? What’s the usage? Why is it unique?

  • What is deviceToken is according to the registered remote notification is sent to the APNs server Token key, Token key contains UDID and App equipment Bundle Identifier, apple APNs server and then generate a deviceToken according to the Token key encoding. DeviceToken can be simply understood as a string of code that contains device information and application information.
  • What is the use of the above mentioned: Provider push time to send the message must be with the deviceToken, then this message is based on deviceToken (UDID + App’s Bundle Identifier) to find the corresponding equipment and the corresponding application on the device, so as to push the messages pushed to the application.
  • Uniqueness: Apple APNs encoding technology and the unique role of deviceToken to ensure his uniqueness. Uniqueness is not to say that an application on a device will always have only one deviceToken, deviceToken will change when the user upgrades the system.

Remote push application

Register remote notification (deviceToken)

Method for registering remote notification

Are generally in the App start to complete the registration of remote notification registration method calls are generally in the didFinishLaunchingWithOptions: method

- (BOOL) application: (UIApplication * application) didFinishLaunchingWithOptions: (NSDictionary * launchOptions) {/ / registration method of remote notification before iOS8, if the project is to support the previous version of iOS8, you must write this method UIRemoteNotificationType types = UIRemoteNotificationTypeBadge UIRemoteNotificationTypeSound | | UIRemoteNotificationTypeAlert; [[UIApplication sharedApplication] registerForRemoteNotificationTypes:types]; / / registered remote notification after iOS8 UIUserNotificationType types | = UIUserNotificationTypeBadge UIUserNotificationTypeSound UIUserNotificationTypeAlert = [UIUserNotificationSettings *mySettings UIUserNotificationSettings |; settingsForTypes:types categories:nil]; [[UIApplication Sha RedApplication] registerUserNotificationSettings:mySettings];}

Callback method for processing registered remote notification

/ / registered callback method, which deviceToken is returned by APNs token - (void) application: (UIApplication * application) didRegisterForRemoteNotificationsWithDeviceToken: (NSData * deviceToken) {[self sendProviderDeviceToken:deviceToken]; / / send this deviceToken to Provider} / / failed to register a callback method, treatment failure (void) - application: (UIApplication * application didFailToRegisterForRemoteNotificationsWithError: (NSError) *) {error}

After the iOS8 has been added to the actionable notification type, the operational notification allows the developer to add custom jump events. These advanced features of this article do not explain, interested students can get to know UIUserNotificationAction UIMutableUserNotificationAction UIUserNotificationCategory UIMutableUserNotificationCategory the class of its own.

Processing receives a remote notification message (one of the following methods will be returned)

Application: didFinishLaunchingWithOptions:

This method is called in the program for the first time, that is, when the state of the App from the Terminate into the Foreground state, according to the method code to determine whether there is a push message.

- (BOOL) application: (UIApplication * application) didFinishLaunchingWithOptions: (NSDictionary * launchOptions) {/ / userInfo to receive remote notification content NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; if (userInfo) {/ / there is a push message processing, push the message} return YES;}
Application: didReceiveRemoteNotification:

If App is in the Background state, the method is called only if the user clicks on the notification message; if the App is in the Foreground state, the method is called directly.

- (void) application: (UIApplication *) application didReceiveRemoteNotification: (NSDictionary *) userInfo}}
Application: didReceiveRemoteNotification: fetchCompletionHandler:

IOS7 Apple does not support multi tasking, which is also one of the reasons for the iOS system hardware requirements, good fluency. After iOS7, apple began to support multitasking, that App can do some updates in the background UI, download the data, such as operation. If you want to receive remote push to do something in the background you need to push the background remote push mode. Don’t fit iOS7 before using this system project background mode, make full use of the multi task model apple, apple does not have a painstaking ah! Set the background mode method items corresponding to the specific settings of the TARGETS-Capabilities-Background Modes-Remote Notifications as shown below (Figure 2-1).

Figure IOS push remote push (iOS Notification Of Remote Notification) 2-1 Setting App Background Modes

This method, regardless of whether the App is in the Foreground state or in the Background state, will be called immediately when a remote push message is received. This method needs to configure the background mode and in the push load must have content-available this key value, the corresponding value value of 1 (details refer to the following [remote notification load content]).

- (void) application: (UIApplication * application) didReceiveRemoteNotification: (NSDictionary * userInfo (void) fetchCompletionHandler: (completionHandler ^) (UIBackgroundFetchResult)) {/ / this method must be called the completionHandler callback, tell whether the system successfully UIBackgroundFetchResultNewData / / UIBackgroundFetchResultNoData / / successfully received the data, not receiving data UIBackgroundFetchResultFailed / / if (accept failure userInfo completionHandler (UIBackgroundFetchResultNewData)) {else}; {completionHandler}} (UIBackgroundFetchResultNoData);
A callback method for an operable notification type when a push message is received
Corresponding to the two / callback method of operation notice type, the specific use of the above methods are easy to understand, not in detail - (void) application: (UIApplication *) application handleActionWithIdentifier: (nullable NSString * identifier (NSDictionary) forRemoteNotification: * userInfo (void) completionHandler: (^) (completionHandler) - (void) {} (application:) UIApplication * application (nullable * NSString) handleActionWithIdentifier:) forRemoteNotification: identifier (NSDictionary *) userInfo withResponseInfo: (NSDictionary *) responseInfo completionHandler: (void) completionHandler ((^)) {}

Interaction between client and server

Here I would like to click on the Tucao push, do push personal feeling is quite strenuous. The first time when the user asked to start the App to accept the push message, most users will click refused to push it, anyway, I am so. You have done a good job, to find a way to ensure that the push on time, to find ways to ensure that the arrival rate of the push, the results of a user refused, so you are all in vain effort ah, ha ha ha.

Here I want to say is: we should put the corresponding.P12 (personal information exchange certificate) certificate to the server developers like. Specific can see my another article does not let the apple developer account torture my team development certificate management in the export of.P12 chapter.

Remote push load

Remote push load size

The size of the remote notification load varies according to the API used by Provider. When using HTTP/2 provider API, the maximum load is 4096bytes, that is, 4kB; when using legacy binary interface, the maximum load of 2048bytes, or 2kB. APNs will refuse to send this message when the load exceeds the specified load.

Remote push load content

Content format necessary to know ah, the server will generally want us to define a good format for their clients.

Each notification message will be composed of a JSON dictionary object, the format is as follows, the example of the key value for Apple’s official key. Custom fields to avoid these key values.

{{"APS": "alert": string or dictionary {/ / "title" "string" "body" "string", "title-loc-key": "string or null" "title-loc-args": "array of strings or null" "action-loc-key": "string or null" "loc-key" "" string "loc-args": "array of strings" "launch-image" "string"}, "badge" number "sound," "string" "content-available" number; "category": "string"}}, APS: a push message must have key Alert: a push message containing the key value system Will be set according to the user display standard push information Badge: display the number of messages in the app icon, the lack of the key value, the number of messages will not change, when the elimination of marker key corresponding to the value is set to 0 sound: set up push voice key value, the system default sound prompts the corresponding value value is default content-available: the key value is set to 1, the callback method to receive push message will call a different system, after iOS7 category:UIMutableUserNotificationCategory's identifier configuration background mode operation notice type key value Title: a brief description of the push message to the application of the system after the iOS8.2 version of body: push content: title-loc-key function similar to title, the additional function is international, after the application of the system iOS8.2 version of title-loc-args: title-loc-key Field use, the application of the system after the iOS8.2 version of action-loc-key: Operation notice type key, not described in loc-key: loc-args: title-loc-args launch-image title-loc-key reference reference: click the push message or mobile event when the slider is shown in the picture. If this key value is missing, the default startup image of app is loaded.

Of course, the key value is not each push message will bring the key value should be chosen according to demand required key value, in addition to providing the key value of the system, you can also customize their key values to the load as the message push, custom key value together with APS of the key value. Following format:

{{"APS": "alert": "Provider push messag.", "badge": 9, "sound": "toAlice.aiff"}, Id: 1314, key / / custom value "type": "customType"} / / custom key value

Specify user push

For users to log on to App, push can be specified by the user, the same push some users can receive, but some users can not receive. This is about to mention another token, generally known as userToken, userToken are generally based on their own rules to generate the company. UserToken is based on the user’s account and the corresponding password generated. This combination of the above mentioned deviceToken, you can do according to different users push different messages. DeviceToken to find a corresponding device and the application on the device, and userToken corresponding to find the user. When the client is reported to the deviceToken, the userToken should be reported to the corresponding server is Provider.

Discussion on push third party SDK

There are a lot of SDK push on the third party, there is a common push Baidu push push the push of the push, etc.. In fact, the principle of push is similar, to understand the principle of Apple Push, these third party SDK is also the basic principle of the above expansion. For third party without using SDK in fact, little impact on our clients, push the SDK is mainly to facilitate the third party server developers. The main performance for the server developers do not need to develop and maintain their own push server and APNs docking, do not have to maintain their own update deviceToken. Of course, the third party SDK will also provide some additional features such as JPush provides an application message push, which is similar to the chat scene is very convenient. After reading this section is not found in the third party and SDK integrated push nothing to do, we do not reduce the workload, but a little bit more ah. As for the other functions of the third party SDK, we can go to the official website to learn, there is no longer too much description.

Using runtime to achieve push message universal jump

This reference to @ Hans ha ha ha ha ha ha ha a iOS universal interface method is universal jump jump jump to an arbitrary interface, but the coupling and the server is too strong, we should carefully consider the use of the time, and the company is generally iOS, Android share the same set of rules is very difficult to let the server push to give you a new push rules, not easy to maintain, but also need to consider the cost of. The purpose of writing this paragraph is when the product has such a demand or can refer to.

Define push rules

The client / controller attribute YBViewController: @interface UIViewController / * * * / @property channel Id (nonatomic, copy) NSString *Id type @property; / * * * / channel (nonatomic, copy) NSString *type @end; / / server push data format {"APS": {"alert": "Provider push messag"}, "class": "YBViewController", "property": {"Id": 1314, "type": "customType"}}

Jump logic

/ / receive push after the jump - (void) didReceiveRemoteNotificationAndPushToViewController: (NSDictionary * userInfo) {/ / *class = userInfo[@ NSString to create the class "class"]; const char *className = [class cStringUsingEncoding:NSASCIIStringEncoding]; Class newClass = objc_getClass (className); if (! NewClass) {Class superClass [NSObject = class]; newClass = objc_allocateClassPair (superClass, className 0, objc_registerClassPair (newClass));}; / / create a jump controller object ID destinationViewController [[newClass = alloc] init]; / / the object assignment attribute NSDictionary *propertys = userInfo[@ "property"]; [propertys enumerateKeysAndObjectsUsingBlock:^ (ID _Nonnull key, ID _Nonnull Obj, BOOL * _Nonnull stop) {/ / this is the detection property of if ([self checkIsExitPropertyWithdestinationViewController:destinationViewController verifyPropertyName:key]) {[destinationViewController setValue:obj forKey:key];} / /}]; jump UITabBarController (UITabBarController *) *tabViewController = self.window.rootViewController; UINavigationController = *sourceViewController (UINavigationController * tabViewController.viewControllers[tabViewController.selectedIndex]); [sourceViewController pushViewController:destinationViewController animated:YES];} / / detection of the presence of the object attribute (BOOL) checkIsExitPropertyWithdestinationViewController: (ID) destinationViewContr Oller verifyPropertyName: (NSString * verifyPropertyName) {/ / get the object in the unsigned int outCount attribute list I; objc_property_t, *properties = class_copyPropertyList ([destinationViewController, class], & outCount); for (I = 0; I < outCount; i++) {objc_property_t property = properties[i]; / / attribute name into a string of NSString *propertyName = [[NSString alloc] initWithCString:property_getName (property encoding:NSUTF8StringEncoding]); / / judge whether the property of if ([propertyName isEqualToString:verifyPropertyName]) {free (properties); return YES;}} free (properties); return NO;}


A good understanding of the principle of remote push will find, in fact, is not so difficult to push and push. Some of the pictures above are from Apple’s official documents, some of which are themselves. Some knowledge is also a reference to Apple’s official website documents. Some further push the relevant universal knowledge is not too high, so there is no mention, for example: Operation notice type, notice internationalization, custom notification sound, with Provider-APNs-Device connection and push the bottom load data format. If you are interested in these knowledge is also very welcome to private communication, and common progress. Please look forward to this article’s sister iOS push local push (iOS Notification Of Local Notification).


  • Apple developer documentation Local Remote Notification Programming and Guide
  • IOS universal jump interface method