Handling Push Notifications in iOS

improve this page | report issue

Overview

MobileFirst-provided Notifications API can be used in order to register & unregister devices, and subscribe & unsubscribe to tags. In this tutorial, you will learn how to handle push notification in iOS applications using Swift.

For information about Silent or Interactive notifications, see:

Prerequisites:

Jump to:

Notifications Configuration

Create a new Xcode project or use and existing one. If the MobileFirst Native iOS SDK is not already present in the project, follow the instructions in the Adding the Mobile Foundation SDK to iOS applications tutorial.

Adding the Push SDK

  1. Open the project’s existing podfile and add the following lines:

    use_frameworks!
    
    platform :ios, 8.0
    target "Xcode-project-target" do
         pod 'IBMMobileFirstPlatformFoundation'
         pod 'IBMMobileFirstPlatformFoundationPush'
    end
    
    post_install do |installer|
         workDir = Dir.pwd
    
         installer.pods_project.targets.each do |target|
             debugXcconfigFilename = "#{workDir}/Pods/Target Support Files/#{target}/#{target}.debug.xcconfig"
             xcconfig = File.read(debugXcconfigFilename)
             newXcconfig = xcconfig.gsub(/HEADER_SEARCH_PATHS = .*/, "HEADER_SEARCH_PATHS = ")
             File.open(debugXcconfigFilename, "w") { |file| file << newXcconfig }
    
             releaseXcconfigFilename = "#{workDir}/Pods/Target Support Files/#{target}/#{target}.release.xcconfig"
             xcconfig = File.read(releaseXcconfigFilename)
             newXcconfig = xcconfig.gsub(/HEADER_SEARCH_PATHS = .*/, "HEADER_SEARCH_PATHS = ")
             File.open(releaseXcconfigFilename, "w") { |file| file << newXcconfig }
         end
    end
    
    • Replace Xcode-project-target with the name of your Xcode project’s target.
  2. Save and close the podfile.
  3. From a Command-line window, navigate into to the project’s root folder.
  4. Run the command pod install
  5. Open project using the .xcworkspace file.

Notifications API

MFPPush Instance

All API calls must be called on an instance of MFPPush. This can be done by using a var in a view controller such as var push = MFPPush.sharedInstance();, and then calling push.methodName() throughout the view controller.

Alternatively you can call MFPPush.sharedInstance().methodName() for each instance in which you need to access the push API methods.

Challenge Handlers

If the push.mobileclient scope is mapped to a security check, you need to make sure matching challenge handlers exist and are registered before using any of the Push APIs.

Learn more about challenge handlers in the credential validation tutorial.

Client-side

Swift Methods Description
initialize() Initializes MFPPush for supplied context.
isPushSupported() Does the device support push notifications.
registerDevice(completionHandler: ((WLResponse!, NSError!) -> Void)!) Registers the device with the Push Notifications Service.
sendDeviceToken(deviceToken: NSData!) Sends the device token to the server
getTags(completionHandler: ((WLResponse!, NSError!) -> Void)!) Retrieves the tag(s) available in a push notification service instance.
subscribe(tagsArray: [AnyObject], completionHandler: ((WLResponse!, NSError!) -> Void)!) Subscribes the device to the specified tag(s).
getSubscriptions(completionHandler: ((WLResponse!, NSError!) -> Void)!) Retrieves all tags the device is currently subscribed to.
unsubscribe(tagsArray: [AnyObject], completionHandler: ((WLResponse!, NSError!) -> Void)!) Unsubscribes from a particular tag(s).
unregisterDevice(completionHandler: ((WLResponse!, NSError!) -> Void)!) Unregisters the device from the Push Notifications Service

Initialization

Initialization is required for the client application to connect to MFPPush service.

  • The initialize method should be called first before using any other MFPPush APIs.
  • It registers the callback function to handle received push notifications.
MFPPush.sharedInstance().initialize();

Is push supported

Checks if the device supports push notifications.

let isPushSupported: Bool = MFPPush.sharedInstance().isPushSupported()

if isPushSupported {
    // Push is supported
} else {
    // Push is not supported
}

Register device & send device token

Register the device to the push notifications service.

MFPPush.sharedInstance().registerDevice(nil) { (response, error) -> Void in
    if error == nil {
        self.enableButtons()
        self.showAlert("Registered successfully")
        print(response?.description ?? "")
    } else {
        self.showAlert("Registrations failed.  Error \(error?.localizedDescription)")
        print(error?.localizedDescription ?? "")
    }
}
MFPPush.sharedInstance().sendDeviceToken(deviceToken)

Note: This is typically called in the AppDelegate in the didRegisterForRemoteNotificationsWithDeviceToken method.

Get tags

Retrieve all the available tags from the push notification service.

MFPPush.sharedInstance().getTags { (response, error) -> Void in
    if error == nil {
        print("The response is: \(response)")
        print("The response text is \(response?.responseText)")
        if response?.availableTags().isEmpty == true {
            self.tagsArray = []
            self.showAlert("There are no available tags")
        } else {
            self.tagsArray = response!.availableTags() as! [String]
            self.showAlert(String(describing: self.tagsArray))
            print("Tags response: \(response)")
        }
    } else {
        self.showAlert("Error \(error?.localizedDescription)")
        print("Error \(error?.localizedDescription)")
    }
}

Subscribe

Subscribe to desired tags.

var tagsArray: [String] = ["Tag 1", "Tag 2"]

MFPPush.sharedInstance().subscribe(self.tagsArray) { (response, error)  -> Void in
    if error == nil {
        self.showAlert("Subscribed successfully")
        print("Subscribed successfully response: \(response)")
    } else {
        self.showAlert("Failed to subscribe")
        print("Error \(error?.localizedDescription)")
    }
}

Get subscriptions

Retrieve tags the device is currently subscribed to.

MFPPush.sharedInstance().getSubscriptions { (response, error) -> Void in
   if error == nil {
       var tags = [String]()
       let json = (response?.responseJSON)! as [AnyHashable: Any]
       let subscriptions = json["subscriptions"] as? [[String: AnyObject]]
       for tag in subscriptions! {
           if let tagName = tag["tagName"] as? String {
               print("tagName: \(tagName)")
               tags.append(tagName)
           }
       }
       self.showAlert(String(describing: tags))
   } else {
       self.showAlert("Error \(error?.localizedDescription)")
       print("Error \(error?.localizedDescription)")
   }
}

Unsubscribe

Unsubscribe from tags.

var tags: [String] = {"Tag 1", "Tag 2"};

// Unsubscribe from tags
MFPPush.sharedInstance().unsubscribe(self.tagsArray) { (response, error)  -> Void in
    if error == nil {
        self.showAlert("Unsubscribed successfully")
        print(String(describing: response?.description))
    } else {
        self.showAlert("Error \(error?.localizedDescription)")
        print("Error \(error?.localizedDescription)")
    }
}

Unregister

Unregister the device from push notification service instance.

MFPPush.sharedInstance().unregisterDevice { (response, error)  -> Void in
   if error == nil {
       // Disable buttons
       self.disableButtons()
       self.showAlert("Unregistered successfully")
       print("Subscribed successfully response: \(response)")
   } else {
       self.showAlert("Error \(error?.localizedDescription)")
       print("Error \(error?.localizedDescription)")
   }
}

Handling a push notification

Push notifications are handled by the native iOS framework directly. Depending on your application lifecyle, different methods will be called by the iOS framework.

For example if a simple notification is received while the application is running, AppDelegate’s didReceiveRemoteNotification will be triggered:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
    print("Received Notification in didReceiveRemoteNotification \(userInfo)")
    // display the alert body
      if let notification = userInfo["aps"] as? NSDictionary,
        let alert = notification["alert"] as? NSDictionary,
        let body = alert["body"] as? String {
          showAlert(body)
        }
}

Learn more about handling notifications in iOS from the Apple documentation

Image of the sample application

Sample application

Click to download the Xcode project.

Sample usage

Follow the sample’s README.md file for instructions.

Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.
Last modified on April 04, 2019