The Reteno iOS SDK for Mobile Customer Engagement and Analytics solutions
See the video manual on iOS SDK setup:
Overview
Reteno
is a lightweight SDK for iOS that helps mobile teams integrate Reteno into their mobile apps. The server-side library makes it easy to call the Reteno API
.
The SDK supports:
- Swift projects
- iOS 12.0 or later
Getting Started with Reteno SDK for iOS
Download and install SDK via CocoaPods.
CocoaPods is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate Reteno into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'Reteno', '2.0.18'
Note
If you are developing app modules, read the instructions on installing the SDK via Swift Package Manager
License
Reteno iOS SDK
is released under the MIT license. See LICENSE for details.
Setting Up the SDK
Follow our setup guide to integrate the Reteno SDK with your app.
Step 1: Add the Notification Service Extension
The NotificationServiceExtension
allows your iOS application to receive rich notifications with images, design the buttons in notifications, and get message statuses (delivered, clicked).
Note
If you already have Notification Service Extension in your app, follow Step 1.6.
1.1 In Xcode, Select File → New → Target...
1.2 Select Notification Service Extension , then press Next.
1.3 Enter the product name as NotificationServiceExtension
and press Finish.
Note
Do not select Activate on the dialog that is shown after selecting Finish.
1.4 Press Cancel in the Activate scheme prompt.
By canceling, you keep Xcode debugging your app instead of the extension you’ve just created.
If you activate the prompt by accident, you can switch back to debugging your app in Xcode (next to the Play button).
1.5 In the project navigator, select the project directory and select the NotificationServiceExtension
target in the targets list.
Check that the Deployment Target is set to the same value as your Main Application Target.
Note
iOS versions under 10 will not be able to get Rich Media.
1.6 In the project navigator, select the NotificationServiceExtension
folder and open the NotificationService.swift
, then replace the entire file contents with the following code. Ignore any build errors at this point. We will import the Reteno module, which will resolve any errors.
import UserNotifications
import Reteno
class NotificationService: RetenoNotificationServiceExtension {}
This gives the ability to allow your iOS application to receive rich notifications with images.
More about the Modifying Content in Newly Delivered Notifications Extension
Step 2: Install the SDK via CocoaPods
2.1 If you don't have CocoaPods and the Podfile installed in your project, run the following script in Terminal:
sudo gem install cocoapods
2.2 Run pod init
from the terminal in your project directory.
2.3 Open the newly created Podfile
with your code editor.
2.4 Add the Reteno
dependency under your project name target and the
NotificationServiceExtension
target as below:
platform :ios, '14.0'
target 'RetenoExample' do
use_frameworks!
pod 'Reteno'
target 'NotificationServiceExtension' do
use_frameworks!
pod 'Reteno'
end
end
2.5 Run the following command in your terminal, in your project directory: pod install
2.6 Open the newly created <project-name>.xcworkspace
file.
Step 3: Import Reteno into Your App Delegate File
To setup SDK you need an
SDK_ACCESS_KEY
, visit Managing Mobile SDK Access Keys to get it.
Method 1: UIKit
In UIKit, navigate to your AppDelegate file and add the Reteno
initialization code to the didFinishLaunchingWithOptions
method.
Make sure to import the Reteno
module import Reteno
import UIKit
import Reteno
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Reteno initialization
Reteno.start(apiKey: "SDK_ACCESS_KEY")
// Register for receiving push notifications
// registerForRemoteNotifications will show the native iOS notification permission prompt
// Provide UNAuthorizationOptions or use default
Reteno.userNotificationService.registerForRemoteNotifications(with: [.sound, .alert, .badge], application: application)
return true
}
// Remaining contents of your AppDelegate Class...
}
Method 2: SwiftUI
In SwiftUI, update your main 'APP_NAME'App.swift file and use the code below. Make sure to replace 'YOURAPP_NAME' with your app name.
import SwiftUI
import Reteno
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
// Reteno initialization
Reteno.start(apiKey: "SDK_ACCESS_KEY")
// Register for receiving push notifications
// registerForRemoteNotifications will show the native iOS notification permission prompt
// Provide UNAuthorizationOptions or use default
Reteno.userNotificationService.registerForRemoteNotifications(with: [.sound, .alert, .badge], application: application)
return true
}
}
import SwiftUI
import Reteno
@main
struct YOURAPP_NAME: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Note
Starting from Reteno SDK 2.0.4 onwards, the
start
method was updated. In the previous version, it had the following parameters:apiKey
,isAutomaticScreenReportingEnabled
,isDebugMode
,isPausedInAppMessages
,inAppMessagesPauseBehaviour
. In the new version, it now has the following parameters:apiKey
,configuration
.RetenoConfiguration
is a struct containing the previous setups.
Step 4: Set Up a Notification Permission Request
Option 1. Saving existing logic
If you have already configured subscribing for push notifications by yourself and don't want to change an existing logic, but have Reteno
analytics features, call the Reteno.userNotificationService.processRemoteNotificationResponse(_:)
SDK method right after you have received user response on the push notification. Pass a UNNotificationResponse as a parameter.
For example, you are using UNUserNotificationCenterDelegate
for processing incoming notifications and responding to notification actions. Call the SDK method like described below:
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
completionHandler([.sound, .badge, .alert])
}
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
Reteno.userNotificationService.processRemoteNotificationResponse(response)
completionHandler()
}
}
Option 2. Creating new logic
From Reteno SDK 1.5.4 onwards, method registerForRemoteNotifications
has a closure with user response on notifications permission prompt and you can register for Remote notifications wherever you want. For example, you want to ask a user permissions for Remote notifications only after they have completed onboarding.
func onboardingCompleted() {
Reteno.userNotificationService.registerForRemoteNotifications(with: [.sound, .alert, .badge]) { granted in
// granted == true if user allowed receiving Remote notifications
}
}
Step 5: Add App Groups
App Groups allow additional interposes communication between the app and notification service and are necessary to provide access to Reteno storage data.
5.1 In your Main app target got to "Signing & Capabilities" → "All"
5.2 Click "+ Capability" if you do not have App Groups in your app yet.
5.3 Select App Groups.
5.4 Under App Groups, click the "+" button.
5.5 Fill the "App Groups" container with group.{bundle_id}.reteno-local-storage
, where bundle_id
is the same as "Bundle Identifier" off your app (in the main target), then press OK
.
5.6 In the NotificationServiceExtension
target, repeat steps 5.2 - 5.5 for the extension target.
Note
The group name structure must be
group.{bundle_id}.reteno-local-storage
, wherebundle_id
is the same as your Main App target "Bundle Identifier". Do Not Include NotificationServiceExtension.
For more information, visit Configuring App Groups
Step 6: Provide Device Tokens to the SDK via the Following Method:
Reteno.userNotificationService.processRemoteNotificationsToken(_ deviceToken: String)
Note
Providing device token depends on how you send push notifications: via Firebase Cloud Messaging (FCM) or directly to APNs
Option 1. If you send push notifications via Firebase Cloud Messaging (FCM) include a call to Reteno
processRemoteNotificationsToken:
in your MessagingDelegate
delegate as follows:
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
guard let fcmToken = fcmToken else { return }
Reteno.userNotificationService.processRemoteNotificationsToken(fcmToken)
}
}
Option 2. In case sending push notifications directly to APNs include a call to Reteno
in the AppDelegate method like in the example below:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
Reteno.userNotificationService.processRemoteNotificationsToken(tokenString)
}
Note
Device token data should be converted to
String
as in the example. Don't send this token if you are using Firebase Cloud Messaging (FCM).
Step 7: Add Custom Behavior for Notifications
If you want to add custom behavior in the UNUserNotificationCenterDelegate
methods, provide your implementation in the appropriate closure:
Reteno.userNotificationService.willPresentNotificationHandler = { notification in
// The closure will be called only if the application is in the foreground.
// You can choose to have the notification presented as a sound, badge, alert and/or in the notification list.
// This decision should be based on whether the information in the notification is otherwise visible to the user.
let authOptions: UNNotificationPresentationOptions
if #available(iOS 14.0, *) {
authOptions = [.badge, .sound, .banner]
} else {
authOptions = [.badge, .sound, .alert]
}
return authOptions
}
Reteno.userNotificationService.didReceiveNotificationResponseHandler = { notification in
// Add your code here.
// The closure will be called when the user responded to the notification by opening the application,
// dismissing the notification or choosing a UNNotificationAction.
}
Do it after configuring the Reteno SDK.
Step 8: Run Your App and Send Yourself a Notification
Run your app on a physical iOS device to make sure it builds correctly. You should be prompted to subscribe to push notifications. Send test notifications not from the Firebase but directly from the eSputnik. More on sending test messages from the event debug view >
Note
The iOS Simulator does not support receiving remote push notifications.
Also, we recommend using Debug Mode to detect possible errors and inaccuracies within your Analytics implementation and events' logging.
Installing the SDK via Swift Package Manager
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift
compiler.
Once you have your Swift package set up, adding Reteno as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/reteno-com/reteno-mobile-ios-sdk.git", .upToNextMajor(from: "2.0.18"))
]
Installation process:
1. Go to the project settings and select Package Dependencies
:
2. Press "+" to add a new package to the project. In the opened window enter in a search field reteno-ios-sdk
or paste a full URL https://github.com/reteno-com/reteno-mobile-ios-sdk.git
. Select found package and fill required settings (dependency rule and project you are adding package).
3. Add the Reteno
package to the main target
and don't forget to add it to the NotificationServiceExtension
.