[SDK] [iOS] Release v1.2.2.0

GitHub release
Integration guide

Changelog:

  • iOS 10 media attachment for rich notifications
  • Present notification while app is foreground on iOS 10
  • Identify new devices
  • Fix rare crash on access token fetch

Upgrading

Supporting iOS 10 rich notifications

In order to use rich notifications, you must add a Notification Service Extension to your project and let the WonderPush SDK do the hard work for you.

First, let's add the new application extension to your project:

  • Open the XCode File menu, under New select Target….
  • In the iOS tab, in the Application Extension group, select Notification Service Extension and click Next.
  • Give it a name you like, here we soberly chose NotificationServiceExtension.
    Choose the same team as your application target.
    Make sure that it is linked to your project and embedded in your application, in the bottom.
    Click Finish.
  • XCode will ask you whether you want to activate the new scheme. Click Activate.

Then, we need to link the extension to another pod of the WonderPush SDK.
Open your Podfile and add the following:

# Create a new target using the exact same name that you entered above
target 'NotificationServiceExtension' do
    # Use the same platform as your application target
    platform :ios, '7.0'
 
    pod 'WonderPush/NotificationServiceExtension', '~> 2.0'
end

Then run the following command to incorporate the WonderPush SDK pod to your extension:

pod install

You should see the following files in your Project navigator:

  • YourProject
    • NotificationServiceExtension (this is the name of the service extension you chose earlier)
      • NotificationService.h
      • NotificationService.m
      • Info.plist

We are going to remove almost all generated code to rely on a utility class the implements it all for you.

Open NotificationService.h and modify it so that it reads:

#import <WonderPush/NotificationServiceExtension.h>
 
// We delegate everything to WPNotificationService
@interface NotificationService : WPNotificationService
 
@end

Then open NotificationService.m and modify it so that it reads:

#import "NotificationService.h"
 
@implementation NotificationService
 
// The WPNotificationService superclass already implements everything
 
@end

App Transport Security setting for the Notification Service Extension

You probably have set App Transport Security Settings / Allow Arbitrary Loads to YES in your application, if so, you likely want to repeat the same step for your Notification Service Extension.
Without this, you would not be able to load rich media from HTTP resources and attach them to your notifications, only HTTPS resources would work.

Here are the steps:

  • Select your project in the Project navigator on the left pane
  • Click your Notification Service Extension target (not the application target)
  • Go to the Info tab
  • Add the App Transport Security Settings key
  • Click the + to add an entry inside it
  • Set Allow Arbitrary Loads to YES.

Alternatively, open your Notification Service Extension (not the one from your application) Info.plist file and add the following entry:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

ADVANCED

If you want to have your own code running, by example for notifications sent by other push providers, you can keep the code generated by the XCode template.

If not, then skip this sub-section.

Our NotificationServiceExtension SDK functions return a boolean value indicating whether the call has been handled or not.
You can hence keep the generated code and simply add the following import to your NotificationService.m file:

#import <WonderPush/NotificationServiceExtension.h>

And add the following at the beginning of the two methods of your implementation:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    if ([WonderPushNotificationServiceExtension serviceExtension:self didReceiveNotificationRequest:request withContentHandler:contentHandler]) {
        // Handled by the WonderPush NotificationServiceExtension SDK, we're done
        return;
    }
 
    // […]
    // There should be somewhere a call like this: contentHandler(request.content);
}
 
 
- (void)serviceExtensionTimeWillExpire {
    if ([WonderPushNotificationServiceExtension serviceExtensionTimeWillExpire:self]) {
        // Handled by the WonderPush NotificationServiceExtension SDK, we're done
        return;
    }
 
    // […]
}

If you want instead to be able to modify a notification for your own processing while letting the WonderPush NotificationServiceExtension SDK perform its own processing too,
that is if you want the changes to be cumulative, you should pass a modified request to the SDK as shown below:

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    // Make your own copy of the content
    UNMutableNotificationContent *content = [request.content mutableCopy];
 
    // Modify the content as needed
    //content.title = [NSString stringWithFormat:@"%@ [modified]", content.title];
 
    // Wrap up your changes in a new request
    request = [UNNotificationRequest requestWithIdentifier:request.identifier content:content trigger:request.trigger];
 
    // Forward the call to the WonderPush NotificationServiceExtension SDK
    if (![WonderPushNotificationServiceExtension serviceExtension:self didReceiveNotificationRequest:request withContentHandler:contentHandler]) {
        // The notification was not for the WonderPush NotificationServiceExtension SDK, handle it ourself
        contentHandler(request.content);
    }
}

New UserNotificationCenter delegate

In order to offer full support for iOS 10 notifications, including presenting them while the app is foreground, you must register a new delegate on the UNUserNotificationCenter class.

This is done very simply by calling [WonderPush setupDelegateForUserNotificationCenter] along with your current call to [WonderPush setupDelegateForApplication:] as shown below:

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [WonderPush setClientId:@"YOUR_CLIENT_ID" secret:@"YOUR_CLIENT_SECRET"];
    [WonderPush setupDelegateForApplication:application];
    [WonderPush setupDelegateForUserNotificationCenter]; // ← add this new line and you're done!
    return YES;
}

If you do not wish to use this automatic setup, you will have to implement each method of the UNUserNotificationCenterDelegate protocol that have their matching function in the WonderPush SDK, and call the SDK in each of them.

The use of the automatic delegate setup does not prevent your implementations of the same-named methods from being called.
In fact our delegate makes sure that every message it receives is passed on to your delegate, whether it intercepted it for its own needs or not.