Mobile Apps – technical documentation for iOS
Requirements
- App should be written in Swift and target iOS 16
- App should have configured Firebase Cloud Messaging (link: https://firebase.google.com/docs/cloud-messaging/ios/client) to handle push notifications
- App should have configured requests for appropriate permissions
Installation
To add the package as a dependency to your Xcode project, follow the steps:
- Select File > Add Package Dependency and enter the repository URL
https://github.com/GetResponse/MobileSDK-IOS
- Click Add package and select your main target.
- Repeat the steps for the Notification Service Extension target (see Preparation).
Alternatively:
- Go to your main target options.
- Under
General > Frameworks, Libraries, and Embedded Content
, click the + button - Select
Add other > Add package
dependency and follow the steps above. - Repeat the steps for
Notification Service Extension
target (see Preparation).
Preparation
To fully support notifications and collect statistics, you need to add the Notification Service Extension
target.
- If you don’t have it already, add a
Notification Service Extension
target:- Go to
File > New > Target
. - Select
Notification Service Extension
, give it a name and clickFinish
. - Click
Cancel
on the next dialog that asks to activate the scheme.
- Go to
- If you haven’t done it already, add this package to the newly created target.
Next, configure required app capabilities by going to Signing & Capabilities > + Capability
:
- In main target, add:
- App Groups
- Select an existing group or create one.
- Push Notifications
- Background Modes
- Select Background fetch and Remote notifications
- App Groups
- In Notification Service Extension target, add:
- App Groups
- Select the same group as in the main target
- Push Notifications The SDK uses Firebase Cloud Messaging to handle push notifications from the GetResponse App.
- App Groups
- Follow the steps in the official Firebase guide to add Firebase to your project. You only need the FirebaseMessaging package.
- Note: Initialising Firebase in your app is covered in the code snippets below.
- Upload your APN keys to Firebase.
Usage
Managing consent
- Create a
NotificationManager class
– you will use it to manage notifications permission and request a token used for subscribing users to notifications.
@MainActor
class NotificationManager: ObservableObject{
@Published private(set) var hasPermission = false
@Published var token: String?
init() {
Task{
await getAuthStatus()
}
}
func request() async{
do {
try await UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound])
await getAuthStatus()
} catch{
print(error)
}
}
func requestToken() {
Messaging.messaging().token { token, error in
if let error = error {
print("Error fetching FCM registration token: \(error)")
} else if let token = token {
print("FCM registration token: \(token)")
self.token = token
}
}
}
func getAuthStatus() async {
let status = await UNUserNotificationCenter.current().notificationSettings()
switch status.authorizationStatus {
case .authorized, .ephemeral, .provisional:
hasPermission = true
default:
hasPermission = false
}
}
}
- Extend the
AppDelegate class
to fully support token registration and sending tokens to GetResponse.- Go to app.getresponse.com > Web Push Notifications > Mobile apps to get the
Application ID, Secret, and Entrypoint
- Go to app.getresponse.com > Web Push Notifications > Mobile apps to get the
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
application.registerForRemoteNotifications()
FirebaseApp.configure()
Messaging.messaging().delegate = self
UNUserNotificationCenter.current().delegate = self
GetResponsePushNotificationService.shared.configure(secret: /*secret*/, applicationId:/*applicationId*/, entrypoint: /*entrypoint*/)
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
@objc func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
guard let token = fcmToken else {
return
}
let tokenDict = ["token": fcmToken ?? ""]
NotificationCenter.default.post(
name: Notification.Name("FCMToken"),
object: nil,
userInfo: tokenDict)
}
}
- Create an instance of the
NotificationManager
in your main view to use across the app
@StateObject var notificationManager = NotificationManager()
Available methods
- Request system notification permission
await notificationManager.request()
- Check system notification permission status
notificationManager.hasPermission
Note that the notificationManager.hasPermission
is a @Published
property
- Request and access the registration token to send targeted notifications to any particular instance of your app
notificationManager.requestToken()
notificationManager.token
Note that the notificationManager.token
is a @Published
property
The registration token may change when:
- The app is restored on a new device
- The user uninstalls/reinstalls the app
- The user clears app data
- Consent to the notifications in GetResponse with the registration token in GetResponse
await GetResponsePushNotificationService.shared.consent(lang:/*LanguageCode*/, externalId: /*externalId*/, email: \*email*\, fcmToken: notificationManager.token!)
The consent expires after 4 weeks. Refresh the consent on every app run to prevent it from being revoked.
lang
– user languageexternalId
– custom unique user IDemail
– optional user email- Remove the consent to stop sending notifications (e.g. on logout)
await GetResponsePushNotificationService.shared.removeConsent()
Handling GetResponse notifications
To access all data in the incoming notification use the method below. It automatically sends statistics about the state of the notification lifecycle (see Handling notification statistics).
GetResponsePushNotificationService.shared.handleIncomingNotification(userInfo: /* userInfo */, eventType: /*EventType*/)
It returns a NotificationHandler
object.
public struct NotificationHandler {
public let title: String
public let body: String
public let imageURL: String?
public let action: ActionType
public let redirectionURL: String?
public let deeplinkPath: String?
public let customData: [String: String]
}
title
– title of notificationbody
– message body of notificationimageURL
– image url of notification (optional)action
– selected action on notification tap (see Handling actions)
public enum ActionType {
case openApp
case openURL
case deeplink
}
redirectionURL
– URL to open for openURL actiondeeplinkPath
– path of deeplink for deeplink actioncustomData
– map (key, value) of custom properties that can be configured in notification settings in the GetResponse App
Handling actions
There are 3 types of actions:
- open application
- open URL
- open deeplink
Open deeplink action requires additional configuration. You can access the deeplink path through the NotificationHandler.deeplinkPath
and use it to redirect the user manually after they click the notification.
Modifying notifications before they are shown
You can modify the content of the incoming notifications with the NotificationService from the Notification Service Extension target. In the following code, it is used for handling the notification’s showed
statistics.
class NotificationService: UNNotificationServiceExtension {
...
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
let _ = try? GetResponsePushNotificationService.handleIncomingNotification(userInfo: bestAttemptContent.userInfo, eventType: EventType.showed)
Messaging.serviceExtension().populateNotificationContent(bestAttemptContent, withContentHandler: contentHandler)
}
}
...
}
Handling notification click
To handle a notification being clicked, add the following code to your AppDelegate class. This code also handles the notification’s clicked
statistics.
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler:
@escaping (UNNotificationPresentationOptions) -> Void
) {
completionHandler([[.banner, .sound]])
}
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
let notification = try? GetResponsePushNotificationService.shared.handleIncomingNotification(userInfo: userInfo, eventType: EventType.clicked)
completionHandler()
}
Handling notification statistics
There are 3 types of notification statistics:
- showed
- can be tracked in the
didReceive
method of theUNNotificationServiceExtension
class (see Modifying notifications before they are shown)
- can be tracked in the
- clicked
- can be tracked in the
userNotificationCenter
method of theAppDelegate
class (see Handling notification click)
- can be tracked in the
- closed
To send notification statistics to GetResponse use the following method:
GetResponsePushNotificationService.shared.handleIncomingNotification(userInfo: /* userInfo */, eventType: /*EventType*/)