Awesome
IBM Cloud Mobile Services - Client SDK Swift Push
The IBM Cloud Push Notifications service provides a unified push service to send real-time notifications to mobile and web applications. The SDK enables iOS apps to receive push notifications sent from the service.
Ensure that you go through IBM Cloud Push Notifications service documentation before you start.
Contents
- Prerequisites
- Installation
- Initialize SDK
- Register for notifications
- Push Notification service tags
- Receiving push notifications on iOS devices
- Notification options
- Advanced options
- Enable monitoring
- Open URL by clicking push notifications
- Parameterize Push Notifications
- API documentation
- Samples and videos
Prerequisites
- iOS 8.0 or later
- Xcode 8.0 or later
- Swift 3.0 or later
- Cocoapods latest version
- Carthage
Installation
The IBM Cloud Push Notifications iOS SDK
is available through Cocoapods and Carthage.
Cocoapods
If your project does not have a Podfile
yet, use the pod init
command to create one. To install IBM Cloud Push Notifications iOS SDK
using Cocoapods, add the following to your Podfile:
use_frameworks!
target 'MyApp' do
platform :ios, '8.0'
pod 'BMSCore', '~> 2.0'
pod 'BMSPush', '~> 3.0'
end
From the terminal, go to your project folder and install the dependencies with the pod install
command.
For apps built with Swift 3.0, you may receive a prompt saying "Convert to Current Swift Syntax?" when opening your project in Xcode 8 (following the installation of BMSCore). Do not convert BMSPush, BMSCore or BMSAnalyticsAPI.
This will install the required dependencies and create a new Xcode workspace.
Note: Ensure that you always open the new Xcode workspace, instead of the original Xcode project file: <strong>MyApp.xcworkspace</strong>.
Carthage
To install BMSPush using Carthage, complete the following steps:
- Add it to your Cartfile:
github "ibm-bluemix-mobile-services/bms-clientsdk-swift-push"
- Run the
carthage update
command. - Upon a successful build, add
BMSPush.framework
,BMSCore.framework
andBMSAnalyticsAPI.framework
into your Xcode project.
To complete the integration, follow the instructions here.
Xcode 8
Choose either of the following options:
- For
Swift 3.+
apps, usecarthage update
.
Xcode 12
To make the carthage work in Xcode 12 you can follow the official Carthage documentation here OR use the following script,
- create a file named
tmp.xcconfig
and add the code below.
EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_simulator__NATIVE_ARCH_64_BIT_x86_64=arm64 arm64e armv7 armv7s armv6 armv8
EXCLUDED_ARCHS=$(inherited) $(EXCLUDED_ARCHS__EFFECTIVE_PLATFORM_SUFFIX_$(EFFECTIVE_PLATFORM_SUFFIX)__NATIVE_ARCH_64_BIT_$(NATIVE_ARCH_64_BIT))
- create a
build.sh
file and add the following
export XCODE_XCCONFIG_FILE=$PWD/tmp.xcconfig
carthage update --platform iOS --no-use-binaries --cache-builds
- From now on run
sh build.sh
instead ofcarthage build
.
Initialize SDK
Complete the following steps to enable iOS applications to receive notifications.
-
Add the
import
statements in your.swift
file.import BMSCore import BMSPush
-
Initialize the Core SDK and Push SDK
BMSClient.sharedInstance.initialize(bluemixRegion: "Location where your app Hosted") BMSPushClient.sharedInstance.initializeWithAppGUID(appGUID: "your push appGUID", clientSecret:"your push client secret")
Where bluemixRegion
specifies the location where the application is hosted. You can use following values:
BMSClient.Region.usSouth
BMSClient.Region.unitedKingdom
BMSClient.Region.sydney
BMSClient.Region.germany
BMSClient.Region.jpTok
BMSClient.Region.usEast
The appGUID
is the Push service instance Id value, and clientSecret
is the Push service instance client secret value.
Note: If you are using Xcode8 beta, add
yourApp.entitlements
. To do this, go to Targets > Capabilities and enable Push Notifications capability.
Register for notifications
Upon successful initialization, Apple Push Notification service (APNs) will give a token in didRegisterForRemoteNotificationsWithDeviceToken
method. Pass the token to Push Notifications service register API.
The following options are supported:
-
Register without UserId
To register without userId use the following pattern:
func application (_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){ BMSPushClient.sharedInstance.registerWithDeviceToken(deviceToken: deviceToken) { (response, statusCode, error) -> Void in if error.isEmpty { print( "Response during device registration: \(response) and status code is:\(statusCode)") } else { print( "Error during device registration: \(error) and status code is: \(statusCode)") } }
-
Register with UserId
The
userId
can be specified while registering the device with Push Notifications service. The register method will accept one more parameter -userId
func application (_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){ BMSPushClient.sharedInstance.registerWithDeviceToken(deviceToken: deviceToken, WithUserId: "your userId") { (response, statusCode, error) -> Void in if error.isEmpty { print( "Response during device registration : \(response) and status code is:\(statusCode)") } else { print( "Error during device registration \(error) and status code is:\(statusCode) ") } }
Where
WithUserId
is the user identifier value you want to register the device in the push service instance.Note: If userId is provided, the client secret value must be provided during initialization.
-
Unregister device from notifications
Use the following code snippets to unregister the device from Push Notification service instance:
BMSPushClient.sharedInstance.unregisterDevice(completionHandler: { (response, statusCode, error) -> Void in if error.isEmpty { print( "Response during unregistering device : \(response) and status code is:\(statusCode)") } else { print( "Error during unregistering device \(error) and status code is:\(statusCode)") } }
Note:To unregister from the
UserId
based registration, you have to call the registration method without userId.
Push Notification service tags
Retrieve tags
The retrieveAvailableTagsWithCompletionHandler
API returns the list of tags to which the device can subscribe. After the device is subscribed to a particular tag, the device can receive notifications that are sent for that tag.
Use the following code snippets into your Swift mobile application to get a list of tags to which the device can subscribe.
BMSPushClient.sharedInstance.retrieveAvailableTagsWithCompletionHandler(completionHandler: { (response, statusCode, error) -> Void in
if error.isEmpty {
print( "Response during retrieve tags : \(response) and status code is:\(statusCode)")
} else {
print( "Error during retrieve tags \n - status code: \(statusCode) \n Error :\(error) \n")
}
}
Subscribe to tags
The subscribeToTags
API will subscribe the iOS device for the list of given tags. After the device is subscribed to a particular tag, the device can receive any push notifications that are sent for that tag.
Add the following code snippets to your Swift mobile application to subscribe a list of tags.
BMSPushClient.sharedInstance.subscribeToTags(tagsArray: response!, completionHandler: { (response, statusCode, error) -> Void in
if error.isEmpty {
print( "Response during Subscribing to tags : \(response?.description) and status code is:\(statusCode)")
} else {
print( "Error during subscribing tags \n - status code: \(statusCode) \n Error :\(error) \n")
}
}
Retrieve subscribed tags
The retrieveSubscriptionsWithCompletionHandler
API will return the list of tags to which the device is subscribed.
Add the following code snippets to your Swift mobile application to get the subscription list.
BMSPushClient.sharedInstance.retrieveSubscriptionsWithCompletionHandler(completionHandler: { (response, statusCode, error) -> Void in
if error.isEmpty {
print( "Response during retrieving subscribed tags : \(response?.description) and status code is:\(statusCode)")
} else {
print( "Error during retrieving subscribed tags \n - status code: \(statusCode) \n Error :\(error) \n")
}
}
Unsubscribing from tags
The unsubscribeFromTags
API will remove the device subscription from the list tags.
Use the following code snippets to unsubsribe from tags:
BMSPushClient.sharedInstance.unsubscribeFromTags(tagsArray: response!, completionHandler: { (response, statusCode, error) -> Void in
if error.isEmpty {
print( "Response during unsubscribed tags : \(response?.description) and status code is:\(statusCode)")
} else {
print( "Error during unsubscribed tags \(error)and status code is:\(statusCode)")
}
}
Receiving push notifications on iOS devices
To receive push notifications on iOS devices, add the following Swift method to the appDelegate.swift
of your application:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
//UserInfo dictionary will contain data sent from the server
}
Notification options
Silent notification
Silent notifications do not appear on the device screen. These notifications are received by the application in the background, which wakes up the application for up to 30 seconds to perform the specified background task. A user might not be aware of the notification arrival.
To handle silent push notifications, use the didReceiveRemoteNotification_fetchCompletionHandler
method.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
let contentAPS = userInfo["aps"] as [NSObject : AnyObject]
if let contentAvailable = contentAPS["content-available"] as? Int {
//silent or mixed push
if contentAvailable == 1 {
completionHandler(UIBackgroundFetchResult.NewData)
} else {
completionHandler(UIBackgroundFetchResult.NoData)
}
} else {
//Default notification
completionHandler(UIBackgroundFetchResult.NoData)
}
}
Interactive notifications
To enable interactive push notifications, the notification action objects must be passed during initialization. The following is a sample code to enable interactive notifications:
let acceptButton = BMSPushNotificationAction(identifierName: "Accept", buttonTitle: "Accept", isAuthenticationRequired: false, defineActivationMode: UIUserNotificationActivationMode.background)
let rejectButton = BMSPushNotificationAction(identifierName: "Reject", buttonTitle: "Reject", isAuthenticationRequired: false, defineActivationMode: UIUserNotificationActivationMode.background)
let category = BMSPushNotificationActionCategory(identifierName: "category", buttonActions: [acceptButton, rejectButton])
let notificationOptions = BMSPushClientOptions()
notificationOptions.setInteractiveNotificationCategories(categoryName: [category])
BMSPushClient.sharedInstance.initializeWithAppGUID(appGUID: "your push appGUID", clientSecret:"your push client secret", options: notificationOptions)
Handling interactive push notifications
Implement the callback method on AppDelegate.swift
:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
switch response.actionIdentifier {
case "Accept":
print("Clicked Accept")
case "Reject":
print("Clicked Reject")
default:
}
completionHandler()
}
This callback method is invoked when user clicks the action button. The implementation of this method must perform tasks associated with the specified identifier and execute the block in the completionHandler parameter.
Adding custom DeviceId for registration
To send Device Identifier
, use the setDeviceId
method of BMSPushClientOptions
.
let notificationOptions = BMSPushClientOptions()
notificationOptions.setDeviceId(deviceId: "YOUR_DEVICE_ID")
Note: Remember to keep custom Device Identifier <strong>unique</strong> for each device.
Enabling rich media notifications
Rich media notifications are supported on iOS 10 or later. To receive rich media notifications, implement <strong>UNNotificationServiceExtension</strong>. The extension will intercept and handle the rich media notification.
In the didReceive()
method of your service extension, add the following code to retrieve the rich push notification content.
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
BMSPushRichPushNotificationOptions.didReceive(request, withContentHandler: contentHandler)
}
Advanced options
iOS badge
For iOS devices, the number to display as the badge of the app icon. If this property is absent, the badge is not changed. To remove the badge, set the value of this property to 0.
Custom sound
Add a sound file to your iOS application.
Enable monitoring
To see the notification monitoring status for iOS, you have to add the following code snippets:
//Send notification status when app is opened by clicking notifications
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
let push = BMSPushClient.sharedInstance
let respJson = (userInfo as NSDictionary).value(forKey: "payload") as! String
let data = respJson.data(using: String.Encoding.utf8)
let jsonResponse:NSDictionary = try! JSONSerialization.jsonObject(with: data! , options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
let messageId:String = jsonResponse.value(forKey: "nid") as! String
push.sendMessageDeliveryStatus(messageId: messageId) { (res, ss, ee) in
print("Send message status to the Push server")
}
}
// Send notification status when the app is in background mode
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let payLoad = ((((userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary).value(forKey: "alert") as! NSDictionary).value(forKey: "body") as! NSString)
self.showAlert(title: "Recieved Push notifications", message: payLoad)
let push = BMSPushClient.sharedInstance
let respJson = (userInfo as NSDictionary).value(forKey: "payload") as! String
let data = respJson.data(using: String.Encoding.utf8)
let jsonResponse:NSDictionary = try! JSONSerialization.jsonObject(with: data! , options: JSONSerialization.ReadingOptions.allowFragments) as! NSDictionary
let messageId:String = jsonResponse.value(forKey: "nid") as! String
push.sendMessageDeliveryStatus(messageId: messageId) { (res, ss, ee) in
completionHandler(UIBackgroundFetchResult.newData)
}
}
Note: To get the message status when the app is in background, you have to send either MIXED or SILENT push notifications. No message delivery status would be received if the app was exited forcefully.
Open URL by clicking push notifications
To open a url by clicking the push notification, you can send a url
field inside the payload.
{
"message": {
"alert": "Notification alert message",
"url":"https://console.ng.bliuemix.net"
}
}
In your applications, go to AppDelegate
file and inside didFinishLaunchingWithOptions
. check the value for url
.
let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary
if remoteNotif != nil {
let urlField = (remoteNotif?.value(forKey: "url") as! String)
application.open(URL(string: urlField)!, options: [:], completionHandler: nil)
}
Parameterize Push Notifications
To enable the Parameterize IBM Cloud Push Notifications, do the following ,
- Add the variables key vaue pair in the
BMSPushClientOptions
let variables = [
"username":"testname",
"accountNumber":"3564758697057869"
]
let notifOptions = BMSPushClientOptions()
notifOptions.setPushVariables(pushVaribales: variables)
-
Pass the
BMSPushClientOptions
in theinitializeWithAppGUID()
method. While registering the device IBM Cloud Push Notifications iOS SDK will pass these variables to IBM Cloud Push Notifications service. -
In the
application:didReceiveRemoteNotification:fetchCompletionHandler ()
add the following to handle the template based push notifications,let push = BMSPushClient.sharedInstance push.didReciveBMSPushNotification(userInfo: userInfo) { (res, error) in completionHandler(UIBackgroundFetchResult.newData) }
-
While sending push notification add the varibale key in
{{}}
{
"message": {
"alert": "hello {{username}} , balance on your account {{accountNumber}} is $1200"
}
}
Note: If the app is force killed , the Template based notifications may not appear in the device.
API documentation
Find the API documentation here - http://ibm-bluemix-mobile-services.github.io/API-docs/client-SDK/BMSPush/Swift/index.html
Samples and videos
-
For samples, visit - Github Sample
-
For video tutorials visit - IBM Cloud Push Notifications
Learning more
Connect with IBM Cloud
Twitter | YouTube | Blog | Facebook |
======================= Copyright 2020-21 IBM Corp.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.