Installation and configuration (iOS)
In this article, you will find out how to install and initialize the Synerise SDK in an iOS application. While performing the actions from this guide, keep the presented order.
IMPORTANT: The Settings article contains additional information about SDK behaviors you may need prior to configuration.
If you want to find out what kind of benefits you can get from integrating with mobile SDK, go here.
Requirements
You need:
- Access to a workspace
- A Profile API Key
When creating the API key, use allowlisting or denylisting to only allow the events you intend to use. - One of the following dependency managers:
- CocoaPods - CocoaPods is a dependency manager for iOS projects.
- Carthage - Carthage is a simple, decentralized dependency manager for iOS projects.
- Swift Package Manager - Swift Package Manager (SPM) is a dependency manager built into Xcode.
- Recommended environment:
- Xcode 16
- iOS SDK 18
- Target deployment:
- iOS 13.0+ for SDK versions 5.0.0 and higher
- iOS 9.0+ for SDK versions lower than 5.0.0
NOTE: Bitcode is not supported in SDK version 5.0.0 and higher. Xcode ignores bitcode.
Apple Frameworks
The Synerise SDK references the following Apple frameworks:
Foundation.frameworkUIKit.frameworkCoreGraphics.frameworkSystemConfiguration.frameworkMobileCoreServices.frameworkCoreTelephony.frameworkSecurity.frameworkCommonCrypto.frameworkWebKit.frameworkUserNotifications.framework
3rd Party Frameworks
Installation
CocoaPods
- Add CocoaPods dependency to Synerise SDK into your
Podfile:
use_frameworks! target YOUR_PROJECT_TARGET do pod 'SyneriseSDK' end - Execute the following shell command in the directory depending on your project configuration:
pod repo update pod install
Swift Package Manager (SPM)
- Go to Xcode project’s settings and navigate to the Package Dependencies tab.
- Below the packages list, click the Add button.
- Enter the URL of Synerise SDK repository (https://github.com/Synerise/synerise-ios-sdk) in the search text field.
- Under the Dependency Rule section, select the SDK version. Finally, click Add Package.
- Select the package that best suits your needs and click Add Package.
Carthage
- Add the Carthage dependency to Synerise SDK into your
Cartfile:
github "synerise/ios-sdk" - Execute the shell command in directory depending on your project configuration:
carthage update - Go to Xcode project target's General section.
- In Finder, open
<YOUR_XCODE_PROJECT_DIRECTORY>/Carthage/Build/iOS - Drag
SyneriseSDK.frameworkto Embedded Binaries. - Make sure the Copy items if needed option is selected.
- Click Finish.
Initialization
Setting up
- Go to Xcode project target's General section.
- Find the Other Linker Flags property and add the -ObjC flag.
If you are going to use push notifications:
Go to
Info.plist- Add a row for Required background mode with the following array type value:
App downloads content in response to push notificationsor add the code below directly:
<key>UIBackgroundModes</key> <array> <string>remote-notification</string> </array>
If you are going to use HTTP addresses (instead of only HTTPS), change the allowlist domains in your app by adding configuration to
Info.plistin one of the following ways:Add configured domain/domains that you need.
<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>yourdomain.com</key> <dict> <!--Include to allow subdomains--> <key>NSIncludesSubdomains</key> <true/> <!--Include to allow HTTP requests--> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> <!--Include to specify minimum TLS version--> <key>NSTemporaryExceptionMinimumTLSVersion</key> <string>TLSv1.1</string> </dict> </dict> </dict>- Give permission for all domains.
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key><true/> </dict>
Importing Synerise SDK
Import the Synerise SDK header into the files that contain code relating to SDK.
import SyneriseSDK
#import <SyneriseSDK/SyneriseSDK.h>
NOTE: In Objective-C, you can include it in your Prefix Header (PCH) and Synerise SDK will be imported to all files automatically.
Basic initialization
Initialize Synerise SDK and provide the Profile API Key.
You may initialize it wherever you want and when you need.
Synerise.initialize(apiKey: "YOUR_PROFILE_API_KEY") // 1
Synerise.setDebugModeEnabled(false) // 2
Synerise.setCrashHandlingEnabled(true) // 3
Synerise.setDelegate(self) // 4
[SNRSynerise initializeWithApiKey:@"YOUR_PROFILE_API_KEY"]; // 1
[SNRSynerise setDebugModeEnabled:NO]; // 2
[SNRSynerise setCrashHandlingEnabled:YES]; // 3
[SNRSynerise setDelegate:self]; // 4
Basic methods you need:
Synerise.initialize(apiKey:)- Initializes Synerise SDK.Synerise.setDebugModeEnabled(_:)- Enables debug mode for Synerise SDK. See Debug mode section for more information.Synerise.setCrashHandlingEnabled(_:)- Enables crash handling. Synerise SDK sends a crash event automatically when an uncaught exception occurs.Synerise.setDelegate(_:)- Sets delegate to handle main actions from Synerise SDK. SeeSyneriseDelegatesection for more information.
Initialization with custom API environment
To change API base URL for on-premise installations, use the following initialization method:
Synerise.initialize(apiKey: "YOUR_PROFILE_API_KEY", baseUrl: "YOUR_API_BASE_URL")
[SNRSynerise initializeWithClientApiKey:@"YOUR_PROFILE_API_KEY" andBaseUrl:@"YOUR_API_BASE_URL"];
Advanced initialization
This is an example of advanced initialization with:
- custom API base URL for on-premise installations
- request validation salt configured
- debug mode enabled
- crash handling enabled
- most of the settings options available
- main delegate
SyneriseDelegate - client's state delegate
ClientStateDelegate
IMPORTANT: We highly recommend to configure settings when Synerise SDK is initialized, before invoking the Synerise.initialize(apiKey:) method. See Settings section for more details about settings options.
IMPORTANT: Secure sensitive keys (for example, apiKey and requestValidationSalt) with mechanisms like string obfuscation or encryption.
NOTE: You can find more information about all Synerise iOS SDK delegates here.
Synerise.settings.sdk.enabled = true
Synerise.settings.sdk.appGroupIdentifier = "YOUR_APP_GROUP_IDENTIFIER"
Synerise.settings.sdk.keychainGroupIdentifier = "YOUR_KEYCHAIN_GROUP_IDENTIFIER"
Synerise.settings.sdk.minTokenRefreshInterval = 1800
Synerise.settings.sdk.shouldDestroySessionOnApiKeyChange = false
Synerise.settings.notifications.enabled = true
Synerise.settings.notifications.disableInAppAlerts = true
Synerise.settings.notifications.encryption = false
Synerise.settings.tracker.autotracking.enabled = true
Synerise.settings.tracker.autotracking.mode = AutoTrackMode.Fine
Synerise.settings.tracker.autotracking.excludedClasses = [SampleViewController.self]
Synerise.settings.tracker.autotracking.excludedViewTags = [0, 1, 2]
Synerise.settings.tracker.tracking.enabled = true
Synerise.settings.tracker.minBatchSize = 10
Synerise.settings.tracker.maxBatchSize = 100
Synerise.settings.tracker.autoFlushTimeout = 5.0
Synerise.settings.tracker.autoTracking.mode = .fine
Synerise.settings.tracker.locationAutomatic = true
Synerise.settings.injector.automatic = true
Synerise.initialize(apiKey: "YOUR_PROFILE_API_KEY", baseUrl: "YOUR_API_BASE_URL")
Synerise.setRequestValidationSalt("YOUR_REQUEST_VALIDATION_SALT")
Synerise.setDebugModeEnabled(false)
Synerise.setCrashHandlingEnabled(true)
Synerise.setDelegate(self)
Client.setClientStateDelegate(self)
SNRSynerise.settings.sdk.enabled = @YES;
SNRSynerise.settings.sdk.appGroupIdentifier = @"YOUR_APP_GROUP_IDENTIFIER";
SNRSynerise.settings.sdk.keychainGroupIdentifier = @"YOUR_KEYCHAIN_GROUP_IDENTIFIER";
SNRSynerise.settings.sdk.minTokenRefreshInterval = 1800;
SNRSynerise.settings.sdk.shouldDestroySessionOnApiKeyChange = NO;
SNRSynerise.settings.notifications.enabled = YES;
SNRSynerise.settings.notifications.disableInAppAlerts = YES;
SNRSynerise.settings.notifications.encryption = NO;
SNRSynerise.settings.tracker.autotracking.enabled = YES;
SNRSynerise.settings.tracker.autotracking.mode = SNRTrackerAutoTrackModeFine;
SNRSynerise.settings.tracker.autotracking.excludedClasses = [SampleViewController.class];
SNRSynerise.settings.tracker.autotracking.excludedViewTags = [@0, @2, @3];
SNRSynerise.settings.tracker.tracking.enabled = YES;
SNRSynerise.settings.tracker.minBatchSize = 10;
SNRSynerise.settings.tracker.maxBatchSize = 100;
SNRSynerise.settings.tracker.autoFlushTimeout = 5.0;
SNRSynerise.settings.tracker.autoTracking.mode = SNRTrackerAutoTrackModeFine;
SNRSynerise.settings.tracker.locationAutomatic = YES;
SNRSynerise.settings.injector.automatic = YES;
[SNRSynerise initializeWithApiKey:@"YOUR_PROFILE_API_KEY" andBaseUrl:@"YOUR_API_BASE_URL"];
[SNRSynerise setRequestValidationSalt:@"YOUR_REQUEST_VALIDATION_SALT"];
[SNRSynerise setDebugModeEnabled:NO];
[SNRSynerise setCrashHandlingEnabled:YES];
[SNRSynerise setDelegate:self];
[SNRClient setClientStateDelegate:self];
Initialization process
During initialization, the library starts and when it is ready or an error occurs, the SDK notifies you.
When the delegate method is called, Synerise is ready to use.
// MARK: - SyneriseDelegate
// This method is called when the Synerise SDK is initialized.
func snr_initialized() {
//...
}
// This method is called when an error occurs while initializing the Synerise SDK.
func snr_initializationError(error: Error) {
//...
}
#pragma mark - SNRSyneriseDelegate
// This method is called when the Synerise SDK is initialized.
- (void)SNR_initialized {
//...
}
// This method is called when an error occurs while initializing the Synerise SDK.
- (void)SNR_initializationError:(NSError *)error {
//...
}
Debug Mode
You can enable debug logs for Synerise SDK by method Synerise.setDebugModeEnabled(_:).
WARNING: Do not use Debug Mode in a release version of your application.
Synerise.setDebugModeEnabled(true) // Enables logging for all modules
[SNRSynerise setDebugModeEnabled:YES]; // Enables logging for all modules
You can receive some logs about:
- Core: push notifications
- Tracker: auto-tracked events, declarative events, sending process
- Client: customer state, authorization
- Injector: campaigns, UI
- Promotions: promotions, vouchers
- Content: content widget, documents, recommendations
Background Tasks
Background Tasks is a mechanism to schedule and run code in the background to keep your app up to date.
The SDK has supported this feature since version 4.23.0. Since version 6.1.0, the SDK uses two Background Tasks:
- Main Background Task: periodically refreshes the registration for Push Notifications.
- Request Retry Background Task: when the device is back online, re-sends requests that failed because of network problems.
Each Background Task needs its own identifier configured in the host application. You can pass the identifiers to the SDK in two equivalent ways:
- With the dedicated methods:
Synerise.setMainBackgroundTaskIdentifier(_:)andSynerise.setRequestRetryBackgroundTaskIdentifier(_:) - With the
Synerise.setBackgroundTaskIdentifiers(_:)method. The first element of the array is the identifier of the Main Background Task. The second element is the identifier of the Request Retry Background Task.
Setting up
To configure Background Tasks in your app:
- Go to the Signing & Capabilities section of your Xcode project target.
- In the Background Modes capability (you may need to add it), enable Background fetch and Background processing.
- Go to
Info.plist. - Add a row with the key Permitted background task scheduler identifiers (
BGTaskSchedulerPermittedIdentifiers) and the array type. - Add a separate string item for each Background Task you want to use: one for the Main Background Task and one for the Request Retry Background Task.
The identifiers must be different. - Pass the identifiers to the SDK BEFORE the application finishes launching, with one of the two methods described below.
Sample \*.plist configuration for Background Tasks:
Option 1: Dedicated methods
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Synerise.setMainBackgroundTaskIdentifier("YOUR_MAIN_BACKGROUND_TASK_IDENTIFIER")
Synerise.setRequestRetryBackgroundTaskIdentifier("YOUR_REQUEST_RETRY_BACKGROUND_TASK_IDENTIFIER")
return true
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[SNRSynerise setMainBackgroundTaskIdentifier:@"YOUR_MAIN_BACKGROUND_TASK_IDENTIFIER"];
[SNRSynerise setRequestRetryBackgroundTaskIdentifier:@"YOUR_REQUEST_RETRY_BACKGROUND_TASK_IDENTIFIER"];
return YES;
}
Option 2: setBackgroundTaskIdentifiers(_:)
The first element of the array is the identifier of the Main Background Task. The second element (optional) is the identifier of the Request Retry Background Task.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Synerise.setBackgroundTaskIdentifiers(["YOUR_MAIN_BACKGROUND_TASK_IDENTIFIER", "YOUR_REQUEST_RETRY_BACKGROUND_TASK_IDENTIFIER"])
return true
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[SNRSynerise setBackgroundTaskIdentifiers:@[@"YOUR_MAIN_BACKGROUND_TASK_IDENTIFIER", @"YOUR_REQUEST_RETRY_BACKGROUND_TASK_IDENTIFIER"]];
return YES;
}
Setup requirements and limitations
- Use the identifiers only for the SDK. Do not use them for other Background Tasks in your app.
- Invoke the methods before the application finishes launching, for example, in
application(_:didFinishLaunchingWithOptions:). Otherwise, the Background Task is not registered and the SDK logs an error. - When you use
setBackgroundTaskIdentifiers(_:), a Background Task without an identifier in the array is unregistered. An array with one element registers only the Main Background Task. - Set
SyneriseDelegatebefore the SDK initialization. Both Background Tasks use it to request the registration for Push Notifications. - Background Tasks are not available in the iOS Simulator. Test them on a physical device.
- iOS decides when a Background Task runs. The SDK only defines the conditions under which a task can run, such as network or power availability. For details, see Main Background Task and Request Retry Background Task.
- If the user force-quits the application, iOS does not run its Background Tasks until the user opens the application again.
To learn more about Background Tasks, see Apple Developer - Using background tasks to update your app.
Main Background Task
You can set the identifier of this task with Synerise.setMainBackgroundTaskIdentifier(_:) or as the first element of the array in Synerise.setBackgroundTaskIdentifiers(_:)
The Main Background Task refreshes the registration token for Push Notifications every 20 days, even when the application is not running. When the task runs, the SDK invokes the snr_registerForPushNotificationsIsNeeded(origin:) method (with the requestEntry origin) or the snr_registerForPushNotificationsIsNeeded() method of SyneriseDelegate, and the application registers for Push Notifications in the same way as on a regular launch.
The task runs when the device is connected to the network and to a power source. The SDK schedules the task automatically. No additional action is required.
Request Retry Background Task
You can set the identifier of this task with Synerise.setRequestRetryBackgroundTaskIdentifier(_:) or as the second element of the array in Synerise.setBackgroundTaskIdentifiers(_:). This task has been available since SDK version 6.1.0.
The Request Retry Background Task re-sends requests that failed because of network problems, for example, when the device was offline. Currently, the mechanism covers the registration for Push Notifications (Client.registerForPush(...)). When the task runs, the SDK invokes the snr_registerForPushNotificationsIsNeeded(origin:) method (with the requestEntry origin) or the snr_registerForPushNotificationsIsNeeded() method of SyneriseDelegate, so the delegate must be set for the retry to work.
The task runs when the device is connected to the network. A power source is not required. The SDK schedules the task when the application goes to the background while there are requests waiting to be sent. If the application is launched in the foreground before the task runs, the SDK follows the regular launch flow and discards the waiting requests.
Privacy manifest
From 1 May 2024, Apple requires you to add a privacy manifest. It's a file in your project that describes your reason and method for collecting data.
Third-party frameworks that track data should have a privacy manifest. When you create the application privacy report, these privacy manifest files are automatically aggregated into a single file.
Synerise supports privacy manifests since SDK version 4.17.0. When you use an SDK version older than 4.17.0, refer to the Synerise API usage requirements defined below when creating an Apple privacy manifest.
APIs usage
| API | Reason | Description |
|---|---|---|
| User defaults APIs | CA92.1 1C8F.1 |
Synerise uses User Defaults to persist the SDK data and share them between the application and extensions |
Tracking
Synerise does not track any data that is protected by the App Tracking Transparency framework.
Collected Data
| Data type | Value | Purpose |
|---|---|---|
| User ID | NSPrivacyCollectedDataTypeUserID | Analytics, Product Personalization |
| Other usage data | NSPrivacyCollectedDataTypeOtherUsageData | Analytics, Product Personalization, App Functionality |
| Product interaction | NSPrivacyCollectedDataTypeProductInteraction | Analytics |
| Advertising data | NSPrivacyCollectedDataTypeAdvertisingData | Other Purposes, App Functionality |
| Crash data | NSPrivacyCollectedDataTypeOtherUserContent | Analytics |
Warnings and limitations
During keychain deletion operations do NOT delete Synerise data. It's stored in SDK library data keys named snr.[KEY_NAME]