Integrating on iOS - what to watch out for with XCode 8, iOS 10, and Swift 3?

XCode 8

 A number of people have reported that XCode 8 is turning off capabilities when project settings are migrated. So it's work checking that the capabilities you need are still enabled for your target. For example you may need Push Notifications mode Enabled, like in the example below:

 

Also if you are using location the NSLocationAlwaysUsage Key you must place in your info.plist has been replaced with "Privacy - Location Always Usage Description" :

 

iOS 10

When the app is open in the foreground notifications are no longer automatically placed in the notification center. You need to use new capability found in UNUserNotificationCenter if you want similar behaviour to what happens on earlier iOS versions.

To do this  you need to add the UserNotifications.framework:


and you will need to modify your App delegate. 

 

Objective-C

In Objective-C this requires you to import UserNotifications and add the UNUserNotificationCenterDelegate  in your app delegate header file.


#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>

@interface XPAppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate>  

Then in your app delegate just after you intiate xtremepush in didFinishLaunchingWithOptions you need to  add the line below:

  
    [XPush applicationDidFinishLaunchingWithOptions:launchOptions];
    
    // Add to manage notification-related behaviors on iOS 10
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;
  

And then you need to add a new userNotificationCenter call back method in your app delegate as shown below: 


- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
    [XPush applicationDidReceiveLocalNotification:notification];
}

// Display notification and place it in notification center on iOS 10
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
}
  

 

Swift 

import UserNotifications and add the UNUserNotificationCenterDelegate  in your app delegate file.


import UserNotifications

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

 

 Then a little further on in your app delegate just after you intiate xtremepush in didFinishLaunchingWithOptions you need to add the line below:


        XPush.applicationDidFinishLaunching(options: launchOptions)
        //End - Initialise XPush
        
        // Add to manage notification-related behaviors on iOS 10
        if #available(iOS 10.0, *) {
            UNUserNotificationCenter.current().delegate = self
        }
 

And finally you need to add a new userNotificationCenter call back method in your app delegate as shown below:  


func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
    XPush.applicationDidReceive(notification)
        
 }
    
 // Display notification and place it in notification center on iOS 10
 @available(iOS 10.0, *)
 internal func userNotificationCenter(_ center: UNUserNotificationCenter,
                           willPresent notification: UNNotification,
                           withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void){
        completionHandler([.alert, .sound]);
    }

Swift 3 

If migrating to Swift 3 you will encounter some minor format changes when using certain methods and adding call back methods. For example a method like [XPush applicationDidFinishLaunchingWithOptions:launchOptions]; looks a little different in Swift 3 vs Swift 2:

Swift 2

XPush.applicationDidFinishLaunchingWithOptions(launchOptions)

Swift 3

XPush.applicationDidFinishLaunching(options: launchOptions)

 Similarly a callback method like:


- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
	[XPush applicationDidRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

Swift 2

    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
        XPush.applicationDidRegisterForRemoteNotificationsWithDeviceToken(deviceToken)
    }

Swift 3


    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
        XPush.applicationDidRegisterForRemoteNotifications(withDeviceToken: deviceToken as Data!)
    }
    

Sample App Delegate with xtremepush Swift 3



import UIKit
import UserNotifications

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        //Start - Initialise XPush
        XPush.setLocationEnabled(true)
        XPush.register(forRemoteNotificationTypes: NotificationSettings.getNotificationSettings())
        XPush.applicationDidFinishLaunching(options: launchOptions)
        //End - Initialise XPush
        
        // Add to manage notification-related behaviors on iOS 10
        if #available(iOS 10.0, *) {
            UNUserNotificationCenter.current().delegate = self
        }
        
        return true
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
        XPush.applicationDidRegisterForRemoteNotifications(withDeviceToken: deviceToken as Data!)
    }
    

    
    private func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
        print("didFailToRegisterForRemoteNotifications")
        XPush.applicationDidFailToRegisterForRemoteNotificationsWithError(error)
    }
    
    private func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
        XPush.applicationDidReceiveRemoteNotification(userInfo)
        
    }
    
     func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
        XPush.applicationDidReceive(notification)
        
    }
    
     // Display notification and place it in notification center on iOS 10
    @available(iOS 10.0, *)
    internal func userNotificationCenter(_ center: UNUserNotificationCenter,
                                         willPresent notification: UNNotification,
                                         withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void){
        completionHandler([.alert, .sound]);
    }


    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}
Have more questions? Submit a request

0 Comments

Article is closed for comments.