> Synerise Documentation — Mobile SDK (Part 1 of 2)
>
> This is part 1 of 2 of the "Mobile SDK" section. To reconstruct the full section, fetch all 2 parts in order (part 1, part 2, …) and concatenate them. Each article begins with a top-level "# " heading. The manifest listing all sections is at https://hub.synerise.com/llms-full.txt
# SDK Lifecycle
### Synerise Builder
Synerise builder class.
**Declared In:**
`com.synerise.sdk.core.Synerise.Builder`
**Declaration:**
```Java
public static class Builder
```
```Kotlin
static class Builder
```
**Properties:**
| Property | Type | Optional | Default | Description |
| --- | --- | --- | --- | --- |
| **app** | Application | no | - | Application context |
| **apiKey** | String | no | - | Profile API Key (formerly Client). Can be retrieved from Synerise App |
| **applicationId** | String | no | - | Application ID |
| **baseUrl** | String | no | - | Base URL in the SDK. Can be null |
| **syneriseDebugMode** | Boolean | no | - | Debug mode flag |
| **notificationIcon** | int | no | R.drawable.synerise_ic_default_icon | Notification icon |
| **notificationIconColor** | int | no | R.color.syneriseGrayTranslucent | Notification color |
| **channelDefaultName** | String | no | - | Default notification channel name |
| **channelDefaultId** | String | no | - | Default notification channel ID |
| **channelHighPriorityName** | String | no | - | High priority notification channel name |
| **channelHighPriorityId** | String | no | - | High priority notification channel ID |
| **pushListener** | OnRegisterForPushListener | no | - | Push listener |
| **locationListener** | OnLocationUpdateListener | no | - | Location listener |
| **crashHandlingEnabled** | Boolean | no | - | Crash handling flag |
| **hostApplicationType** | HostApplicationType | yes | - | Host application type |
| **hostApplicationSDKPluginVersion** | String | yes | - | Synerise SDK plugin version in the host application |
| **setRequestValidationSalt** | String | yes | - | Synerise Profile salt string for request validation |
| **messagingServiceType** | String | yes | GMS | Use `GMS` for Google Mobile Services or `HMS` for Huawei Mobile Services |
**Initializers:**
Start initializing Synerise SDK with this method.
To get the Workspace API Key (formerly Business) and Profile API Key (formerly Client), sign in to your Synerise account and go to [Settings > API Key](https://app.synerise.com/spa/modules/settings/apikeys/list).
Then, copy or generate a new API Key for the workspace and API Key for profiles.
public static Builder with(Application app, String apiKey, String appId)
---
Use this method to finish the initialization process.
public void build()
---
**Methods:**
This method sets the icon that will be used as the small icon in notifications.
It must be a drawable resource (not a mipmap) due to Android Oreo adaptive icons restrictions.
public Builder notificationIcon(@DrawableRes int notificationIcon)
---
This method sets the notification icon and text color.
`notificationIconColor` must be in ARGB format.
public Builder notificationIconColor(int notificationIconColor)
---
This method enables/disables logcat logs from Synerise SDK.
It is not recommended to use debug mode in the release version of your application.
public Builder syneriseDebugMode(boolean syneriseDebugMode)
---
This method passes info about Users application crashes as dedicated events to the backend.
It is recommended to use `SyneriseCrashHandling`.
public Builder crashHandlingEnabled(boolean exceptionHandlerEnabled)
---
It is important to register your profiles for push messages, so Synerise SDK may ask you to register a profile for push notifications.
This callback is called after the profile signs in, signs up, or deletes the account.
public Builder pushRegistrationRequired(@NonNull OnRegisterForPushListener listener)
---
This callback is called on demand by push notification, so it may be called at any time.
Check out the [sample application](https://github.com/Synerise/android-sdk/blob/master/sample/src/main/java/com/synerise/sdk/sample/App.java) for example usage and remember to send.
public Builder locationUpdateRequired(@NonNull OnLocationUpdateListener listener)
---
You can provide your custom base URL to use your own API.
You can use one of the constants:
**SyneriseApiUrls.SYNERISE_AZ_API_URL** - `https://api.snrapi.com`
**SyneriseApiUrls.SYNERISE_AZU_API_URL** - `https://api.azu.snrapi.com`
**SyneriseApiUrls.SYNERISE_GEB_API_URL** - `https://api.geb.snrapi.com`
public Builder baseUrl(String baseUrl)
---
You can provide your notification channel name.
By default, the channel name is set to your application name.
public Builder notificationDefaultChannelName(@NonNull String name)
---
You can provide your notification channel ID.
public Builder notificationDefaultChannelId(@NonNull String channelId)
---
You can provide your High Priority notification channel name.
From default, channel name is set to ` High Priority`
public Builder notificationHighPriorityChannelName(@NonNull String name)
---
You can provide your High Priority notification channel ID.
public Builder notificationHighPriorityChannelId(@NonNull String channelId)
---
You can set the Synerise SDK host application type.
public Builder hostApplicationType(HostApplicationType type)
---
You can set Synerise the SDK plugin version of the host application.
public Builder hostApplicationSDKPluginVersion(@NonNull String version)
---
---
---
## InitializationConfig
Configuration class for initialization of the SDK.
**Declared In:**
`com.synerise.sdk.core.types.model.InitializationConfig`
**Declaration:**
All the properties above are accessible by using getters.
**Methods:**
There are getters and setters for the above properties.
---
---
## Settings
Class model for settings.
**Declared In:**
`com.synerise.sdk.core.settings.Settings`
**Declaration:**
```Java
public class Settings
```
```Kotlin
class Settings
```
**Properties:**
| Property | Type | Description |
| --- | --- | --- |
| **sdk** | GeneralSettings | [General settings](/developers/mobile-sdk/settings#general) - This group contains options related to the general functioning of mobile SDK |
| **notifications** | NotificationsSettings | [Notifications settings](/developers/mobile-sdk/settings#notifications) - This group contains options related to push notifications |
| **tracker** | TrackerSettings | [Tracker](/developers/mobile-sdk/settings#tracker) - This group contains options related to tracking the customer activities in a mobile application |
| **inAppMessaging** | InAppMessagingSettings | [In-app messaging](/developers/mobile-sdk/settings#in-app-messaging) - This group contains options related to the [in-app messages](/docs/campaign/in-app-messages) feature |
| **injector** | InjectorSettings | [Injector](/developers/mobile-sdk/settings#injector) - This group contains options related to displaying [campaigns](/docs/campaign/Mobile) |
**Note:**
Learn more about settings [here](/developers/mobile-sdk/settings)
---
---
## TrackMode
This enum contains the values which set a mode for tracking component interactions from the `android.widget` package.
**Declared In:**
`com.synerise.sdk.core.types.enums.TrackMode`
**Declaration:**
```Java
public enum TrackMode
```
```Kotlin
public enum TrackMode
```
**Values:**
| Property | Description |
| --- | --- |
| **PLAIN** | Tracks screen-visits. Events are sent when onStart of activities/Fragments is called. |
| **FINE** | Tracks screen-visits and onClick events from components such as Buttons, ImageButtons, RatingBars |
**Methods:**
There are no methods.
---
---
# Overview
Integrating Synerise Mobile (Android, iOS, React Native, Flutter) SDKs in your mobile application has many benefits, such as:
- **Time-saving and low effort** - The integration is quick, allowing you to get started right away without spending time configuring or managing session tokens. Synerise stores customer tokens (both anonymous and recognized), manages their validity, refreshes and handles the logic of log-ins and log-outs. The integration is quick and you'll be able to secure user's information in no time.
- **Safety guaranteed** - We have a highly secure and encrypted infrastructure: all sensitive data is encrypted in storage and the communication between the servers and the application is encrypted and secured well, which is proven by successfully passed audits.
- **Automatic event tracking** - All customers' activities (events) in a mobile application are tracked in real time and sent in batches to Synerise. This way, you can use the Synerise Decision Hub to analyze the customers' behavior in your mobile app.
There is no auto-tracking option for React Native. To send events to Synerise, you must configure triggers which record and send events to Synerise.
- **Send push notifications** - Integrating your mobile app with Synerise Mobile SDK facilitates push notifications, which you can use to communicate with your customers. All interactions related to push notifications are collected as events, such as: opening a push notification, clicking a link in the notification, rejecting the notification, and so on. Based on [these events](/developers/mobile-sdk/event-tracking#predefined-event-list), you can measure the results of your push notification campaigns in the Synerise Decision Hub.
- **Send in-app messages** - In-app messages allow you to display any creation in a mobile application and implement use cases such as [abandoned cart](/use-cases/abandoned-basket-inapp), [price drop notifications](/use-cases/in-app-price-drop-last-seen-products), sending out discount codes, or implement any information campaign, such as application update. In contrast to push notifications which are sent (pushed) to the app user by Synerise, in-app messages are requested (pulled) by the user’s device through Synerise mobile SDK and they doesn't require a marketing agreement to be displayed.
- **Display recommendations and promotions** - Your mobile app can be a distribution channel where you can display [AI-based recommendations](/docs/ai-hub/recommendations-v2) and [promotions](/docs/ai-hub/personalized-promotions) which you can create in Synerise. Because the SDK keeps the customer context, actions such as fetching a recommendation or a promotion require only one SDK call.
- **Build your application with Synerise Documents** - This feature allows you to build your mobile application based on [documents](/docs/assets/documents) in which you can include [promotions](/docs/ai-hub/personalized-promotions), [recommendations](/docs/ai-hub/recommendations-v2), [dynamic content](/docs/campaign/dynamiccontent) without releasing a new version of your app.
## What's next
---
Proceed to [Installation and configuration](/developers/mobile-sdk/installation-and-configuration).
# SDK Lifecycle
## InitializationConfig
**Declared In:**
Headers/SNRInitializationConfig.h
**Inherits from:**
[NSObject](https://developer.apple.com/documentation/objectivec/nsobject)
**Declaration**:
**Properties:**
| Property | Type | Description |
| --- | --- | --- |
| **sdk** | GeneralSettings | [General settings](/developers/mobile-sdk/settings#general) - This group contains options related to the general functioning of mobile SDK |
| **notifications** | NotificationsSettings | [Notifications settings](/developers/mobile-sdk/settings#notifications) - This group contains options related to push notifications |
| **tracker** | TrackerSettings | [Tracker](/developers/mobile-sdk/settings#tracker) - This group contains options related to tracking the customer activities in a mobile application |
| **inAppMessaging** | InAppMessagingSettings | [In-app messaging](/developers/mobile-sdk/settings#in-app-messaging) - This group contains options related to the [in-app messages](/docs/campaign/in-app-messages) feature |
| **injector** | InjectorSettings | [Injector](/developers/mobile-sdk/settings#injector) - This group contains options related to displaying [campaigns](/docs/campaign/Mobile) |
**Note:**
Learn more about settings [here](/developers/mobile-sdk/settings)
---
---
## TrackerAutoTrackMode
**Declared In:**
Headers/SNRTrackerAutoTrackingSettings.h
`eager` mode was removed in SDK version 5.0.0.
**Declaration:**
```Swift
enum TrackerAutoTrackMode: Int {
plain,
fine,
disabled
}
```
# Sample projects on Github
- [Github sample projects - Android](https://github.com/Synerise/android-sdk)
- [Github sample projects - iOS](https://github.com/Synerise/synerise-ios-sdk)
- [Github sample projects - React Native](https://github.com/Synerise/react-native-synerise-sdk)
- [Github sample projects - Flutter](https://github.com/Synerise/synerise-flutter-sdk)
# Modules
### Synerise
Main Synerise module responsible for whole SDK. This class is responsible for initialization of SDK.
**Declared In:**
`com.synerise.sdk.core.Synerise`
**Declaration:**
```Java
public class Synerise
```
```Kotlin
class Synerise
```
**Properties:**
| Property | Type | Optional | Default | Description |
| --- | --- | --- | --- | --- |
| **settings** | [Settings](/developers/mobile-sdk/class-reference/android/lifecycle#settings) | no | - | Configuration of whole SDK |
**Initializers:**
There are no initializers.
**Methods:**
Method to get applicationContext.
public static Context getApplicationContext()
---
Method that generates the document assigned to a slug.
public static String getClientApiKey()
---
Get application ID.
public static String getAppId()
---
Get base URL.
public static String getBaseUrl()
---
Get flag indicating debugMode state.
public static boolean getSyneriseDebugMode()
---
---
---
### Client
Module responsible for all operations connected with a profile (formerly client).
**Declared In:**
`com.synerise.sdk.client.Client`
**Declaration:**
```Java
public abstract class Client
```
```Kotlin
abstract class Client
```
**Properties:**
There are no properties.
**Initializers:**
There are no initializers.
**Methods:**
This method sets ClientStateChangeListener to get optional callbacks.
public static void setOnClientStateChangeListener(OnClientStateChangeListener listener)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#set-client-state-change-listener)
---
This method removes ClientStateChangeListener.
public static void removeClientStateChangeListener()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#remove-client-state-change-listener)
---
This method changes a Profile (formerly Client) API key dynamically.
public static void changeApiKey(@NonNull String apiKey)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/lifecycle#change-profile-api-key-dynamically)
---
This method changes a Profile (formerly Client) API key dynamically, with additional parameters.
public static void changeApiKey(String apiKey, InitializationConfig initializationConfig)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/lifecycle#change-profile-api-key-dynamically-with-config)
---
This method registers a new customer with an email, password, and optional data.
public static IApiCall registerAccount(@NonNull RegisterClient registerClient)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#register-customer-account)
---
This method activates a customer with email.
public static IApiCall requestAccountActivation(String email)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#request-customer-account-activation)
---
This method confirms a customer account with the confirmation token.
public static IApiCall confirmAccountActivation(String token)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#confirm-customer-account-activation)
---
This method requests a customer's account registration process with the PIN code.
public static IApiCall requestAccountActivationByPin(String email)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#request-customer-account-activation-by-pin)
---
This method confirms a customer's account registration process with the PIN code.
public static IApiCall confirmAccountActivationByPin(String pinCode, String email)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#confirm-customer-account-activation-by-pin)
---
This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests.
public static IApiCall signIn(@NonNull String email, @NonNull String password)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#sign-in-a-customer)
---
This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests.
public static IDataApiCall<AuthConditions> signInConditionally(@NonNull String email, @NonNull String password)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#sign-in-a-customer-conditionally)
---
This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-by-identityprovider)
---
This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-conditionally-by-identityprovider)
---
This method authenticates a customer with OAuth.
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-by-oauth-with-registration) - **REMOVED in version 6.0.0**
---
This method authenticates a customer with OAuth.
public static IApiCall authenticateByOAuthIfRegistered(@NonNull String accessToken, @Nullable String authId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-by-oauth-without-registration) - **REMOVED in version 6.0.0**
---
This method authenticates a customer with Facebook.
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-by-facebook-with-registration) - **REMOVED in version 6.0.0**
---
This method authenticates a customer with Facebook.
public static IApiCall authenticateByFacebookIfRegistered(@NonNull String facebookToken, @Nullable String authId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-by-facebook-without-registration) - **REMOVED in version 6.0.0**
---
This method signs in a customer in with the provided token payload.
public static IApiCall authenticateWithTokenPayload(TokenPayload tokenPayload, @NonNull String authId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-with-token-payload)
---
This method authenticates a customer with Simple Profile Authentication.
public static IApiCall simpleAuthentication(ClientData clientData, String authId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-via-simple-profile-authentication)
---
This method checks if a customer is signed in (via Synerise Authentication - RaaS, OAuth, Facebook, Apple).
public static boolean isSignedIn()
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple)
---
This method checks if a customer is signed in (via Simple Profile Authentication).
public static boolean isSignedInViaSimpleAuthentication()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication)
---
This method signs out a customer out.
public static void signOut()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#sign-out-customer)
---
This method signs out a customer out with a chosen mode.
public static void signOut(ClientSignOutMode mode)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#sign-out-customer-with-mode) - **REMOVED in version 6.0.0**
---
This method signs out a customer out with a chosen mode and Determines if the method should sign out all devices
public static IApiCall signOut(ClientSignOutMode mode, Boolean signOutFromAllDevices)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#sign-out-customer-with-mode-or-from-all-devices)
---
This method refreshes the customer’s current token.
public static IApiCall refreshToken()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#refresh-customer-token)
---
This method retrieves the customer’s current, active token.
public static IDataApiCall<Token> retrieveToken()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#get-customer-token)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#retrieve-customer-token)
---
This method retrieves the customer’s current UUID.
public static String getUuid()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#get-current-customer-uuid)
---
Retrieves the current UUID or generates a new one from a seed.
public static String getUuidForAuthentication(@NonNull String authId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#get-customer-uuid-for-use-in-authentication)
---
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
public static boolean regenerateUuid()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#regenerate-customer)
---
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
public static boolean regenerateUuid(String clientIdentifier)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#regenerate-customer-with-identifier)
---
This method destroys the session completely.
public static void destroySession()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-session#destroy-current-session)
---
This method gets a customer’s account information.
public static IDataApiCall<GetAccountInformation> getAccount()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#get-customer-account-information)
---
This method retrieves events for an authenticated customer.
public static IDataApiCall<List<ClientEventData>> getEvents(ClientEventsQuery clientEventsQuery)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/tracking#get-customers-events)
---
This method updates a customer’s account’s basic information (without identification data: uuid, customId, email).
public static IApiCall updateAccountBasicInformation(@NonNull UpdateAccountBasicInformation accountInformation)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#update-customer-account-basic-information)
---
This method updates a customer’s account information.
public static IApiCall updateAccount(@NonNull UpdateAccountInformation accountInformation)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#update-customer-account-information)
---
This method requests a customer’s password reset with email.
public static IApiCall requestPasswordReset(@NonNull PasswordResetRequest resetRequest)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#request-password-reset-for-customer-account)
---
This method confirm a customer’s password reset with the new password and token provided by password reset request.
public static IApiCall confirmPasswordReset(@NonNull PasswordResetConfirmation resetConfirmation)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#confirm-password-reset-for-customer-account)
---
This method changes a customer’s password.
public static IApiCall changePassword(@NonNull String oldPassword, @NonNull String password)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#change-customers-account-password)
---
This method requests a customer's email change.
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#request-email-change-for-customer-account)
---
This method confirms an email change.
public static IApiCall confirmEmailChange(String token, boolean newsletterAgreement)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#confirm-email-change-for-customer-account)
---
Requests a customer's phone update. A confirmation code is sent to the phone number.
public static IApiCall requestPhoneUpdate(String phone)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#request-phone-update-on-customer-account)
---
This method confirms a phone number update. This action requires the new phone number and confirmation code as parameters.
public static IApiCall confirmPhoneUpdate(String phone, String confirmationCode, @Nullable Boolean smsAgreement)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#confirm-phone-update-on-customer-account)
---
This method deletes a customer's account.
public static IApiCall deleteAccount(String clientAuthFactor, ClientIdentityProvider clientIdentityProvider, @Nullable String authId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account-by-identity-provider)
---
This method deletes a customer's account.
public static IApiCall deleteAccount(String password)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account) - **REMOVED in version 6.0.0**
---
This method deletes a customer's account by OAuth.
public static IApiCall deleteAccountByOAuth(String accessToken, @Nullable String uuid)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account-by-oauth) - **REMOVED in version 6.0.0**
---
This method deletes a customer's account by Facebook.
public static IApiCall deleteAccountByFacebook(String facebookToken, @Nullable String uuid)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account-by-facebook) - **REMOVED in version 6.0.0**
---
This method passes the Firebase Token to Synerise for notifications and doesn't update the agreement of the profile.
public static IApiCall registerForPush(@NonNull String firebaseId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#register-for-push-notifications-without-agreement)
---
This method passes the Firebase Token to Synerise for notifications.
public static IApiCall registerForPush(@NonNull String firebaseId, boolean mobilePushAgreement)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#register-for-push-notifications)
---
---
---
### Tracker
Module responsible for sending events.
**Declared In:**
`com.synerise.sdk.event.Tracker`
**Declaration:**
```Java
public abstract class Tracker
```
```Kotlin
abstract class Tracker
```
**Properties:**
There are no properties.
**Initializers:**
There are no initializers.
**Methods:**
This method sets a custom identifier in the parameters of every event.
public static void setCustomIdentifier(String customIdentifier)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/tracking#set-custom-identifier-for-events)
---
This method sets a custom email in the parameters of every event.
public static void setCustomEmail(String customEmail)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/tracking#set-custom-email-for-events)
---
This method sends an event.
public static void send(Event event)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/tracking#send-event)
---
This method forces sending the events from the queue to the server.
public static void flush()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/tracking#flush-events-from-tracker)
---
---
---
### Injector
Module responsible for handling push notifications and in-app communication.
**Declared In:**
`com.synerise.sdk.injector.Injector`
**Declaration:**
```Java
public abstract class Injector
```
```Kotlin
abstract class Injector
```
**Properties:**
| Property | Type | Optional | Description |
|---|---|---|---|
| inAppContext | HashMap<String, Object> | No | The global context used for personalizing in-app message content. This property is shared between overlay and inline in-app messages |
**Initializers:**
There are no initializers.
**Methods:**
Closes an in-app message and sends an `inApp.discard` event.
Usage examples:
- Closing a top bar or bottom bar when the user taps outside the in-app area.
- Automatically dismissing messages when navigating away from a screen.
- Controlling in-app visibility based on app logic for a smoother user experience.
public static void closeInAppMessage(String campaignHash)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#close-in-app-message)
---
This method handles a notification payload and starts activity.
public static boolean handlePushPayload(Bundle bundle)
public static boolean handlePushPayload(Map<String, String> pushPayload)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#handle-synerise-push-notification)
---
This method decrypts the notification payload.
public static Map<String, String> decryptPushPayload(Map<String, String> pushPayload) throws DecryptionException
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#decrypt-push-notification)
---
This method verifies if a notification is encrypted.
public static boolean isPushEncrypted(Map<String, String> pushPayload)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-encrypted)
---
This method verifies if a notification was sent by Synerise.
public static boolean isSynerisePush(Map<String, String> pushPayload)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-from-synerise)
---
This method verifies if a notification's sender is Synerise and if the notification is a Silent Command.
public static boolean isSilentCommand(Map<String, String> pushPayload)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-silent-command)
---
This method verifies if a notification's sender is Synerise and if the notification is a Silent SDK Command.
public static boolean isSilentCommandSdk(Map<String, String> pushPayload)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-silent-sdk-command)
---
This method verifies if a notification’s sender is Synerise and if the notification is a Simple Push campaign
public static boolean isSyneriseSimplePush(Map<String, String> pushPayload)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-simple-push-campaign)
---
This method verifies if a notification’s sender is Synerise and if the notification is a Banner campaign.
public static boolean isSyneriseBanner(Map<String, String> pushPayload)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-banner-campaign) - **REMOVED in version 6.0.0**
---
This method converts push payload into SilentCommand object.
public static SilentCommand getSilentCommand(Map<String, String> payload) throws ValidationException
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#get-a-silent-command)
---
This method fetches a walkthrough.
public static void getWalkthrough()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#get-walkthrough) - **REMOVED in version 6.0.0**
---
This method shows a walkthrough when it is loaded.
public static boolean showWalkthrough()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#show-walkthrough) - **REMOVED in version 6.0.0**
---
This method checks if a walkthrough is loaded.
public static boolean isWalkthroughLoaded()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-walkthrough-is-loaded) - **REMOVED in version 6.0.0**
---
This method checks if the walkthrough is unique compared to the previous one.
public static boolean isLoadedWalkthroughUnique()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#check-if-loaded-walkthrough-is-unique) - **REMOVED in version 6.0.0**
---
This method fetches banners set for mobile campaigns and caches the valid ones.
public static void fetchBanners()
public static void fetchBanners(@NonNull final DataActionListener<List<TemplateBanner>> successListener,
@NonNull final DataActionListener<ApiError> errorListener)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#fetch-banners)- **REMOVED in version 6.0.0**
---
This method provides valid banners directly from SDK cache.
public static List<TemplateBanner> getBanners()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#get-banners)
---
This method shows a banner immediately.
public static void showBanner(TemplateBanner banner, boolean markPresented)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#show-banner)- **REMOVED in version 6.0.0**
---
This method fetches Push Notifications set for mobile campaigns.
public static IDataApiCall<List<SynerisePushResponse>> getPushes()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/campaigns#get-pushes)
---
---
---
### Promotions
Module responsible for managing promotions.
**Declared In:**
`com.synerise.sdk.promotions.Promotions`
**Declaration:**
```Java
public abstract class Promotions
```
```Kotlin
abstract class Promotions
```
**Properties:**
There are no properties.
**Initializers:**
There are no initializers.
**Methods:**
This method retrieves all available promotions that are defined for a customer.
public static IDataApiCall<PromotionResponse> getPromotions()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#get-all-promotions-of-a-customer)
---
This method retrieves all available promotions that are defined for a customer.
public static IDataApiCall<PromotionResponse> getPromotions(PromotionsApiQuery promotionsApiQuery)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#get-all-promotions-of-a-customer)
---
This method retrieves the promotion with the specified UUID.
public static IDataApiCall<SinglePromotionResponse> getPromotionByUuid(@NonNull String uuid)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#get-promotion-by-uuid)
---
This method retrieves the promotion with the specified code.
public static IDataApiCall<SinglePromotionResponse> getPromotionByCode(@NonNull String code)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#get-promotion-by-code)
---
This method activates the promotion with the specified UUID.
public static IApiCall activatePromotionByUuid(@NonNull String uuid)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#activate-promotion-by-uuid)
---
This method activates the promotion with the specified code.
public static IApiCall activatePromotionByCode(@NonNull String code)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#activate-promotion-by-code)
---
This method deactivates the promotion with the specified UUID.
public static IApiCall deactivatePromotionByUuid(@NonNull String uuid)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#deactivate-promotion-by-uuid)
---
This method deactivates the promotion with the specified code.
public static IApiCall deactivatePromotionByCode(@NonNull String code)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#deactivate-promotion-by-code)
---
This method retrieves an assigned voucher code or assigns a voucher from a pool identified by UUID to the profile.
When the voucher is assigned for the first time, a [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
public static IDataApiCall<AssignVoucherResponse> getOrAssignVoucher(@NonNull String poolUuid)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#get-or-assign-voucher-from-pool)
---
This method assigns a voucher from a pool identified by UUID to the profile.
A [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
public static IDataApiCall<AssignVoucherResponse> assignVoucherCode(@NonNull String poolUuid)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#assign-voucher-code-from-pool)
---
This method retrieves voucher codes for a customer.
public static IDataApiCall<VoucherCodesResponse> getAssignedVoucherCodes()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/promotions#get-voucher-codes-assigned-to-customer)
---
---
---
### Content
Module responsible for managing documents, reccommendations and content widget.
**Declared In:**
`com.synerise.sdk.content.Content`
**Declaration:**
```Java
public abstract class Content
```
```Kotlin
abstract class Content
```
**Properties:**
There are no properties.
**Initializers:**
There are no initializers.
**Methods:**
This method generates the document assigned to a slug.
public static IDataApiCall<Object> getDocument(String slugName)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#get-document) - **REMOVED in version 6.0.0**
---
This method generates the document that is defined for the provided slug.
public static IDataApiCall<Document> generateDocument(String slugName)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#generate-document)
---
This method generates the document that is defined for parameters provided in the query object.
public static IDataApiCall<Document> generateDocument(DocumentApiQuery documentApiQuery)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#generate-document-with-query-parameters)
---
This method generates documents that are defined for parameters provided in the query object.
public static IDataApiCall<List<Object>> getDocuments(DocumentsApiQuery documentsApiQuery)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#get-documents) - **REMOVED in version 6.0.0**
---
This method generates recommendations that are defined for the options provided. The recommendations are generated by using a document with an insert.
For instructions, see ["Displaying AI recommendations > With documents and screen views"](/developers/mobile-sdk/displaying-recommendations/documents).
public static IDataApiCall<RecommendationResponse> getRecommendations(String slugName, RecommendationRequestBody options)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#get-recommendations) - **REMOVED in version 6.0.0**
---
This method generates recommendations that are defined for the options provided. The recommendations are generated by using a document with an insert.
For instructions, see ["Displaying AI recommendations > With documents and screen views"](/developers/mobile-sdk/displaying-recommendations/documents).
public static IDataApiCall<RecommendationResponse> getRecommendationsV2(String slugName, RecommendationRequestBody options)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#get-recommendations-v2)
---
This method generates the customer's highest-priority screen view campaign.
public static IDataApiCall<ScreenViewResponse> getScreenView()
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#get-screen-view) - **REMOVED in version 6.0.0**
---
This method generates a customer's highest-priority screen view campaign from the feed with the provided feed slug.
public static IDataApiCall<ScreenView> generateScreenView(String feedSlug)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#generate-screen-view)
---
This method generates customer's highest-priority screen view campaign that is defined for parameters provided in the query object.
public static IDataApiCall<ScreenView> generateScreenView(ScreenViewApiQuery screenViewApiQuery)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/content#generate-screen-view-with-query-parameters)
# Android
## Class reference - Android
# Basics
## Prerequisites
---
Only for campaigns served by push notifications: [Configure push notifications](/developers/mobile-sdk/configuring-push-notifications).
## Overview
---
Synerise campaigns are served in two ways:
- By Push Notifications, which means that the campaigns are delivered as a push notification:
- Simple push
- Silent push
- By Synerise backend, which means that the campaign is retrieved by SDK through API:
- In-app messages
You can create each campaign type in the Synerise app. [Full documentation is available at this link](/docs/campaign/Mobile).
## Synerise push notification structure
---
Each notification follows this basic structure corresponding to the operating system:
- `issuer` - in Synerise notifications, the issuer is always `Synerise`. If you want to handle notifications with your own methods, remember to change the `issuer` field. If `issuer` is set to `Synerise`, the payload is always handled by the Synerise SDK.
- `message-type` - specifies if the content is static or dynamic.
- `content-type` - specifies the type of content in the payload.
- `content` - the content of the message.
You can also react to Synerise push notifications in your own way, using the payloads presented earlier in this article.
## Checking push campaign type
---
You may need to know whether an incoming push notification comes from Synerise.
| Method | Description |
| --- | --- |
| [`Injector.isSynerisePush`](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-from-synerise) | Returns 'true' if the notification comes from Synerise. It is validated by checking if the `issuer` of the push is `Synerise`. |
| [`Injector.isSyneriseSimplePush`](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-simple-push-campaign) | Checks if the notification payload contains a Simple Push campaign. |
| [`Injector.isSyneriseBanner`](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-banner-campaign) | Checks if the notification payload contains a Banner campaign. |
| [`Injector.isSyneriseSilentCommand`](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-silent-command) | Checks if the notification payload contains a Silent Command campaign. |
| [`Injector.isSilentSdkCommand`](/developers/mobile-sdk/method-reference/android/campaigns#check-if-push-notification-is-a-silent-sdk-command) | Checks if the notification payload contains a Silent SDK Command campaign. |
| Method | Description |
| --- | --- |
| [`Synerise.isSyneriseNotification`](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-from-synerise) | Returns 'true' if the notification comes from Synerise. It is validated by checking if the `issuer` of the push is `Synerise`. |
| [`Synerise.isSyneriseSimplePush`](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-simple-push-campaign) | Checks if the notification payload contains a Simple Push campaign. |
| [`Injector.isSyneriseBanner`](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-banner-campaign) | | [`Synerise.isSyneriseBanner`](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-banner-campaign) | Checks if the notification payload contains a Banner campaign. |
| [`Synerise.isSilentCommand`](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-silent-command) | Checks if the notification payload contains a Silent Command campaign. |
| [`Synerise.isSyneriseSilentSDKCommand`](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-silent-sdk-command) | Checks if the notification payload contains a Silent SDK Command campaign. |
| Method | Description |
| --- | --- |
| [`Synerise.Notificationsl.isSyneriseNotification`](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-from-synerise) | Returns 'true' if the notification comes from Synerise. It is validated by checking if the `issuer` of the push is `Synerise`. |
| [`Synerise.Notificationsl.isSyneriseSimplePush`](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-a-simple-push-campaign) | Checks if the notification payload contains a Simple Push campaign. |
| [`Injector.isSyneriseBanner`](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-a-banner-campaign) | | [`Synerise.Notificationsl.isSyneriseBanner`](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-a-banner-campaign) | Checks if the notification payload contains a Banner campaign. |
| [`Synerise.Notificationsl.isSyneriseSilentCommand`](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-a-silent-command) | Checks if the notification payload contains a Silent Command campaign. |
| [`Synerise.Notificationsl.isSyneriseSilentSDKCommand`](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-a-silent-sdk-command) | Checks if the notification payload contains a Silent SDK Command campaign.|
| Method | Description |
| --- | --- |
| [`Synerise.notifications.isSyneriseNotification`](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-from-synerise) | Returns 'true' if the notification comes from Synerise. It is validated by checking if the `issuer` of the push is `Synerise`. |
| [`Synerise.notifications.isSyneriseSimplePush`](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-simple-push-campaign) | Checks if the notification payload contains a Simple Push campaign. |
| [`Synerise.notifications.isSyneriseBanner`](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-banner-campaign) | Checks if the notification payload contains a Banner campaign. |
| [`Synerise.notifications.isSilentCommand`](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-silent-command) | Checks if the notification payload contains a Silent Command campaign. |
| [`Synerise.notifications.isSyneriseSilentSDKCommand`](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-silent-sdk-command) | Checks if the notification payload contains a Silent SDK Command campaign. |
## Localizations in campaigns
---
This feature is currently available only for iOS SDK, React Native (iOS), and Flutter SDK (iOS).
You may set your localization to support different languages in your application - see ["Localize some strings occurring in the SDK"](/developers/mobile-sdk/settings#localize-some-strings-occurring-in-the-sdk) in the SDK Settings.
**Available keys:**
- **CTA button** in the [in-app alert of the Simple Push campaign](/developers/mobile-sdk/campaigns/simple-push#additional-in-app-alert-when-simple-push-is-received).
- **dismiss button** in the [in-app alert of the Simple Push campaign](/developers/mobile-sdk/campaigns/simple-push#additional-in-app-alert-when-simple-push-is-received).
If you don't want to show any of the Synerise campaigns somewhere in your application or if there are View Controllers that should never be covered by Synerise activity (for example, banners), you can block the Synerise elements.
To do this, add the **SyneriseActivityNotAllowed** protocol in your View Controller declaration.
For example:
```Swift
class SampleViewController: UIViewController, SyneriseActivityNotAllowed {
}
```
*When View Controller implements that protocol and Synerise tries to run an activity, the activity is skipped.*
# SDK lifecycle
---
## Initialization
---
This method initializes Synerise.
This method must be called before any other Synerise SDK method and only once during the application's lifecycle.
**Declared In:**
lib/main/Synerise.js
**Related To:**
[Synerise](/developers/mobile-sdk/class-reference/react-native/lifecycle#synerise)
[SyneriseInitializer](/developers/mobile-sdk/class-reference/react-native/lifecycle#syneriseinitializer)
**Class:**
[PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions)
**Builder Parameters:**
| Parameter | Type | Mandatory | Default | Description |
| --- | --- | --- | --- | --- |
| **withBaseUrl** | string | no | - | Synerise API custom environment base URL |
| **withApiKey** | string | yes | - | Synerise Profile (formerly Client) API Key |
| **withDebugModeEnabled** | **boolean** | no | - | Enables or disables console logs |
| **withCrashHandlingEnabled** | **boolean** | no | - | Enables or disables crash handling |
| **withSettings** | **object** | no | - | Settings that have to be configured before Synerise is initialized |
Before version 1.0.0, the `withApiKey` method was called `withClientApiKey`.
**Return Value:**
No value is returned.
**Example:**
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate)
---
This method sets an object for notification delegate methods.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#initialization)
---
This method initializes Synerise SDK with custom environment settings.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#initialize-with-custom-environment)
---
This method sets the salt string for request validation.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#set-request-validation-salt)
---
This method changes a Profile (formerly Client) API key dynamically.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#change-profile-api-key-dynamically)
---
This method changes a Profile (formerly Client) API key dynamically, with additional parameters.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#change-profile-api-key-dynamically-with-config)
---
This method sets the Synerise SDK host application type.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#set-up-host-application-type)
---
This method sets the Synerise SDK plugin version.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#set-host-application-sdk-plugin-version)
---
This method enables or disables console logs from Synerise SDK.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#enable-debug-mode)
---
This method enables or disables crash handling by Synerise SDK.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#enable-crash-handling)
---
This method sets the notification categories (including Synerise categories) that your app supports.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#set-notification-categories)
---
This method sets identifiers for Background Tasks processing.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#set-notification-categories)
---
This method verifies if a notification was sent by Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-from-synerise)
---
This method verifies if a notification’s sender is Synerise and if the notification is a Simple Push campaign
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-simple-push-campaign)
---
This method verifies if a notification’s sender is Synerise and if the notification is a Banner campaign.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-banner-campaign) **REMOVED in version 5.0.0**
---
This method verifies if a notification's sender is Synerise and if the notification is a Silent Command.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-silent-command)
---
This method verifies if a notification's sender is Synerise and if the notification is a Silent SDK Command.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-a-silent-sdk-command)
---
This method verifies if a notification is encrypted.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-encrypted)
---
This method decrypts the notification payload.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#decrypt-push-notification)
---
This method handles a notification payload and starts activity.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#handle-synerise-push-notification)
---
This method handles a notification payload with a user interaction and starts activity.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#handle-synerise-push-notification-with-action)
---
- Synerise Domain is declared as a global string constant - `SNRSyneriseDomain`
- Synerise Bundle Identifier is declared as a global string constant - `SNRSyneriseBundleIdentifier`
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#client-state-delegate)
---
This method registers a new customer with an email, password, and optional data.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#register-customer-account)
---
This method confirms a customer account with the confirmation token.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#confirm-customer-account-activation)
---
This method activates a customer with email.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#request-customer-account-activation)
---
This method requests a customer's account registration process with the PIN code.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#request-customer-account-activation-by-pin)
---
This method confirms a customer's account registration process with the PIN code.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#confirm-customer-account-activation-by-pin)
---
This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-in-a-customer)
---
This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-in-a-customer-conditionally)
---
This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-identityprovider)
---
This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider)
---
This method authenticates a customer with OAuth.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-oauth-with-registration) - **REMOVED in version 5.0.0**
---
This method authenticates a customer with OAuth.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-oauth-without-registration) - **REMOVED in version 5.0.0**
---
This method authenticates a customer with Facebook.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-facebook-with-registration) - **REMOVED in version 5.0.0**
---
This method authenticates a customer with Facebook.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-facebook-without-registration) - **REMOVED in version 5.0.0**
---
This method authenticates a customer with Sign In With Apple.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-sign-in-with-apple-with-registration) - **REMOVED in version 5.0.0**
---
This method authenticates a customer with Sign In With Apple.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-sign-in-with-apple-without-registration) - **REMOVED in version 5.0.0**
---
This method signs in a customer in with the provided token payload.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-with-token-payload)
---
This method authenticates a customer with Simple Profile Authentication.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-via-simple-profile-authentication)
---
This method checks if a customer is signed in (via Synerise Authentication - RaaS, OAuth, Facebook, Apple).
```Swift
static func isSignedIn() -> Bool
```
```Objective-C
+ (BOOL)isSignedIn
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple)
---
This method checks if a customer is signed in (via Simple Profile Authentication).
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication)
---
This method signs out a customer out.
```Swift
static func signOut()
```
```Objective-C
+ (void)signOut
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-out-customer)
---
This method signs out a customer out with a chosen mode.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-out-customer-with-mode) - **REMOVED in version 5.0.0**
---
This method signs out a customer out with a chosen mode and Determines if the method should sign out all devices
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-out-customer-with-mode-or-from-all-devices)
---
This method refreshes the customer’s current token.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#refresh-customer-token)
---
This method retrieves the customer’s current, active token.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#retrieve-customer-token)
---
This method retrieves the customer’s current UUID.
```Swift
static func getUUID() -> String
```
```Objective-C
+ (NSString *)getUUID
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#get-current-customer-uuid)
---
Retrieves the current UUID or generates a new one from a seed.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#get-customer-uuid-for-use-in-authentication)
---
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
```Swift
static func regenerateUUID()
```
```Objective-C
+ (BOOL)regenerateUUID
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#regenerate-customer)
---
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#regenerate-customer-with-identifier)
---
This method destroys the session completely.
```Swift
static func destroySession()
```
```Objective-C
+ (void)destroySession
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#destroy-current-session)
---
This method gets a customer’s account information.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#get-customer-account-information)
---
This method retrieves events for an authenticated customer.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#get-customers-events)
---
This method updates a customer’s account’s basic information (without identification data: uuid, customId, email).
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#update-customer-account-basic-information)
---
This method updates a customer’s account information.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#update-customer-account-information)
---
This method requests a customer’s password reset with email.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#request-password-reset-for-customer-account)
---
This method confirm a customer’s password reset with the new password and token provided by password reset request.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#confirm-password-reset-for-customer-account)
---
This method changes a customer’s password.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#change-customers-account-password)
---
This method requests a customer's email change.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#request-email-change-for-customer-account)
---
This method confirms an email change.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#confirm-email-change-for-customer-account)
---
Requests a customer's phone update. A confirmation code is sent to the phone number.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#request-phone-update-on-customer-account)
---
This method confirms a phone number update. This action requires the new phone number and confirmation code as parameters.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#confirm-phone-update-on-customer-account)
---
This method deletes a customer's account.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#delete-customer-account-by-identity-provider)
---
This method deletes a customer's account.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#delete-customer-account) - **DEPRECATED in version 3.6.19**
---
This method passes the Firebase Token to Synerise for notifications and doesn't update the agreement of the profile.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#register-for-push-notifications-without-agreement)
---
This method passes the Firebase Token to Synerise for notifications.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#register-for-push-notifications)
---
---
### Tracker
The module for sending event tracking data to Synerise backend. Tracking is performed by creating pre-defined or custom event objects and sending these to Synerise. It also includes automatic event interception by the Auto-Tracking feature.
**Declared In:**
Headers/SNRTracker.h
**Related To:**
[Event](/developers/mobile-sdk/class-reference/ios/events#event)
[TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams)
[TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder)
**Inherits From:**
[NSObject](https://developer.apple.com/documentation/objectivec/nsobject)
**Declaration:**
[Click for more details](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#tracker-delegate)
---
This method sets a custom identifier in the parameters of every event.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/tracking#set-custom-identifier-for-events)
---
This method sets a custom email in the parameters of every event.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/tracking#set-custom-email-for-events)
---
This method sends an event.
```Swift
static func send(_: Event)
```
```Objective-C
+ (void)send:(SNREvent *)event
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/tracking#send-event)
---
This method forces sending the events from the queue to the server.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/tracking#flush-events-from-tracker)
---
---
### Injector
The module for handling Synerise UI activities such as walkthrough, banner, simple push, and so on.
**Declared In:**
Headers/SNRInjector.h
**Inherits From:**
[NSObject](https://developer.apple.com/documentation/objectivec/nsobject)
**Declaration:**
**Properties:**
| Property | Type | Optional | Description |
|---|---|---|---|
| inAppContext | [String: Any] | No | The global context used for personalizing in-app message content. This property is shared between overlay and inline in-app messages |
**Methods:**
This method sets an object for in-app messages delegate methods.
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#injector-in-app-message-delegate)
---
Closes an in-app message and sends an `inApp.discard` event.
Usage examples:
- Closing a top bar or bottom bar when the user taps outside the in-app area.
- Automatically dismissing messages when navigating away from a screen.
- Controlling in-app visibility based on app logic for a smoother user experience.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#close-in-app-message)
---
This method fetches a walkthrough.
```Swift
static func getWalkthrough()
```
```Objective-C
+ (void)getWalkthrough
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#get-walkthrough) - **REMOVED in version 5.0.0**
---
This method shows a walkthrough when it is loaded.
```Swift
static func showWalkthrough()
```
```Objective-C
+ (void)showWalkthrough
```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#show-walkthrough) - **REMOVED in version 5.0.0**
---
This method checks if a walkthrough is loaded.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-walkthrough-is-loaded) - **REMOVED in version 5.0.0**
---
This method checks if the walkthrough is unique compared to the previous one.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-loaded-walkthrough-is-unique) - **REMOVED in version 5.0.0**
---
This method fetches Push Notifications set for mobile campaigns.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#get-pushes) - **REMOVED in version 5.0.0**
---
This method provides valid banners directly from SDK cache.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#get-banners) - **REMOVED in version 4.6.0**
---
This method fetches banners set for mobile campaigns and caches the valid ones.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#fetch-banners) - **REMOVED in version 4.6.0**
---
This method shows a banner immediately.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#show-banner) - **REMOVED in version 4.6.0**
---
---
### Promotions
The module for handling promotions and vouchers from Synerise SDK.
**Declared In:**
Headers/SNRPromotions.h
**Related To:**
[PromotionsApiQuery](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionsapiquery)
[PromotionIdentifier](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionidentifier)
[PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse)
[Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion)
[AssignVoucherResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherresponse)
[VoucherCodesResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#vouchercodesresponse)
**Inherits From:**
[NSObject](https://developer.apple.com/documentation/objectivec/nsobject)
**Declaration:**
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-all-promotions-of-a-customer)
---
This method retrieves promotions that match the parameters defined in an API query.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-promotions-with-query-parameters)
---
This method retrieves the promotion with the specified UUID.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-promotion-by-uuid)
---
This method retrieves the promotion with the specified code.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-promotion-by-code)
---
This method activates the promotion with the specified UUID.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#activate-promotion-by-uuid)
---
This method activates the promotion with the specified code.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#activate-promotion-by-code)
---
This method activates promotions with a code or with UUID in a batch.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#activate-promotions-in-a-batch)
---
This method deactivates the promotion with the specified UUID.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#deactivate-promotion-by-uuid)
---
This method deactivates the promotion with the specified code.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#deactivate-promotion-by-code)
---
This method deactivates promotions with a code or with UUID in a batch.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#deactivate-promotions-in-a-batch)
---
This method retrieves an assigned voucher code or assigns a voucher from a pool identified by UUID to the profile.
When the voucher is assigned for the first time, a [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-or-assign-voucher-from-pool)
---
This method assigns a voucher from a pool identified by UUID to the profile.
A [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#assign-voucher-code-from-pool)
---
This method retrieves voucher codes for a customer.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-voucher-codes-assigned-to-customer)
---
---
### Content
The module for handling content from Synerise backend such as documents, recommendations, and so on.
**Declared In:**
Headers/SNRContent.h
**Related To:**
[Document](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#document)
[DocumentApiQuery](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#documentapiquery)
[DocumentsApiQuery](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#documentsapiquery)
[RecommendationResponse](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendationresponse)
[Recommendation](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendation)
[ScreenView](/developers/mobile-sdk/class-reference/ios/miscellaneous#screenview)
[ScreenViewApiQuery](/developers/mobile-sdk/class-reference/ios/miscellaneous#screenviewapiquery)
**Inherits From:**
[NSObject](https://developer.apple.com/documentation/objectivec/nsobject)
**Declaration:**
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#get-document) - **REMOVED in version 5.0.0**
---
This method generates the document that is defined for the provided slug.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#generate-document)
---
This method generates the document that is defined for parameters provided in the query object.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#generate-document-with-query-parameters)
---
This method generates documents that are defined for parameters provided in the query object.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#get-documents) - **REMOVED in version 5.0.0**
---
This method generates recommendations that are defined for the options provided. The recommendations are generated by using a document with an insert.
For instructions, see ["Displaying AI recommendations > With documents and screen views"](/developers/mobile-sdk/displaying-recommendations/documents).
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#get-recommendations) - **REMOVED in version 5.0.0**
---
This method generates recommendations that are defined for the options provided. The recommendations are generated by using a document with an insert.
For instructions, see ["Displaying AI recommendations > With documents and screen views"](/developers/mobile-sdk/displaying-recommendations/documents).
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#get-recommendations-v2)
---
This method generates the customer's highest-priority screen view campaign.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#get-screen-view) - **REMOVED in version 5.0.0**
---
This method generates a customer's highest-priority screen view campaign from the feed with the provided feed slug.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#generate-screen-view)
---
This method generates customer's highest-priority screen view campaign that is defined for parameters provided in the query object.
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#generate-screen-view-with-query-parameters)
# Android
## Android listeners
### OnRegisterForPushListener {id=on-register-for-push-listener}
##### onRegisterForPushRequired(PushRegistrationOrigin origin) {id=on-register-for-push-listener-on-register-for-push-required-with-origin}
This method is called when Synerise needs registration for push notifications.
See [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/android) for more details.
```Kotlin
fun onRegisterForPushRequired(origin: PushRegistrationOrigin)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **origin** | [PushRegistrationOrigin](/developers/mobile-sdk/class-reference/android/campaigns#pushregistrationorigin) | Information about the cause of the registration |
---
---
##### onRegisterForPushRequired() {id=on-register-for-push-listener-on-register-for-push-required}
This method is called when Synerise needs registration for push notifications.
See [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/android) for more details.
```Java
- void onRegisterForPushRequired();
```
```Kotlin
fun onRegisterForPushRequired()
```
---
---
### OnNotificationListener {id=on-notification-listener}
A listener to handle events from Synerise notifications.
See [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/android#callback-methods) for more details.
**OnNotificationListener** is available from 4.9.0 SDK version.
##### onNotificationReceived(NotificationInfo notificationInfo) {id=on-notification-listener-on-notification-receive}
This method is called when a Synerise notification is received.
```Java
- public void onNotificationReceived(NotificationInfo notificationInfo)
```
```Kotlin
fun onNotificationReceived(notificationInfo: NotificationInfo)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/android/campaigns#notificationinfo) | Object providing info about the notification. |
##### onNotificationDismissed(NotificationInfo notificationInfo) {id=on-notification-listener-on-notification-dismissed}
This method is called when a Synerise notification is dismissed.
```Java
- public void onNotificationDismissed(NotificationInfo notificationInfo)
```
```Kotlin
fun onNotificationDismissed(notificationInfo: NotificationInfo)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/android/campaigns#notificationinfo) | Object providing info about the notification. |
##### onNotificationClicked(NotificationInfo notificationInfo) {id=on-notification-listener-on-notification-clicked}
This method is called when a Synerise notification is clicked.
```Java
- public void onNotificationClicked(NotificationInfo notificationInfo)
```
```Kotlin
fun onNotificationClicked(notificationInfo: NotificationInfo)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/android/campaigns#notificationinfo) | Object providing information about the notification. |
##### onActionButtonClicked(NotificationInfo notificationInfo, String actionButton) {id=on-notification-listener-on-action-button-clicked}
This method is called when an action button is clicked in a Synerise notification.
```Java
- public void onActionButtonClicked(NotificationInfo notificationInfo, String actionButton)
```
```Kotlin
fun onActionButtonClicked(notificationInfo: NotificationInfo, actionButton: String)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/android/campaigns#notificationinfo) | Object providing information about the notification. |
| **actionButton** | String | Text on the clicked action button. |
---
---
### OnClientStateChangeListener {id=on-client-state-change-listener}
A listener to handle customer's sign-in state changes.
To set your object with listener methods, you must use [this method](/developers/mobile-sdk/method-reference/android/client-authentication#set-client-state-change-listener).
##### onClientSignedIn() {id=on-client-state-change-listener-on-client-signed-in}
This method is called when the customer signs in.
```Java
- public void onClientSignedIn()
```
```Kotlin
fun onClientSignedIn()
```
##### onClientSignedOut(ClientSessionEndReason reason) {id=on-client-state-change-listener-on-client-signed-out}
This method is called when the customer signs out.
```Java
- public void onClientSignedOut(ClientSessionEndReason reason)
```
```Kotlin
fun onClientSignedOut(reason:ClientSessionEndReason)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **reason** | [ClientSessionEndReason](/developers/mobile-sdk/class-reference/android/client#clientsessionendreason) | Specifies the reason for signing out. |
---
---
### OnInjectorListener {id=on-injector-listener}
##### onOpenUrl(SyneriseSource source, String url) {id=on-injector-listener-on-open-url}
A listener to handle events from [campaigns](/developers/mobile-sdk/campaigns).
Fired when a customer interacts with the URL action.
This method returns `true` if activity is closed after executing an action; in other case, it returns `false`.
```Kotlin
fun onOpenUrl(source:SyneriseSource, url:String):Boolean
```
| Parameter | Type | Description |
| --- | --- | --- |
| **source** | SyneriseSource | Interaction source |
| **url** | String | URL value from the action of the activity |
##### onOpenUrl(InjectorSource source, String url) {id=on-injector-listener-on-open-url-deprecated}
A listener to handle events from [campaigns](/developers/mobile-sdk/campaigns).
Fired when a customer interacts with the URL action.
This method returns `true` if activity is closed after executing an action; in other case, it returns `false`.
```Kotlin
fun onOpenUrl(source:InjectorSource, url:String):Boolean
```
| Parameter | Type | Description |
| --- | --- | --- |
| **source** | InjectorSource | Interaction source |
| **url** | String | URL value from the action of the activity |
##### onDeepLink(SyneriseSource source, String deepLink) {id=on-injector-listener-on-deeplink}
Fired when a customer interacts with the DEEP_LINKING action.
The method returns `true` if activity is closed after executing the action; in other case, it returns `false`.
```Kotlin
fun onDeepLink(source:SyneriseSource, deepLink:String):Boolean
```
| Parameter | Type | Description |
| --- | --- | --- |
| **source** | SyneriseSource | Interaction source |
| **deepLink** | String | Deep link value from the action of the activity |
##### onDeepLink(InjectorSource source, String deepLink) {id=on-injector-listener-on-deeplink}
Fired when a customer interacts with the DEEP_LINKING action.
The method returns `true` if activity is closed after executing the action; in other case, it returns `false`.
```Kotlin
fun onDeepLink(source:InjectorSource, deepLink:String):Boolean
```
| Parameter | Type | Description |
| --- | --- | --- |
| **source** | InjectorSource | Interaction source |
| **deepLink** | String | Deep link value from the action of the activity |
---
---
### OnInAppListener {id=on-in-app-listener}
A listener to handle the states of [in-app message](/developers/mobile-sdk/campaigns/in-app-message).
**OnInAppListener** is available from 4.7.0 SDK version.
To set your object with listener methods, you must use [this method](/developers/mobile-sdk/method-reference/android/campaigns#set-in-app-listener).
##### shouldShow(InAppMessageData inAppMessageData) {id=on-in-app-listener-should-show}
This method is called after an in-app message is loaded and Synerise SDK asks for permission to show it.
| Parameter | Type | Description |
| --- | --- | --- |
| **inAppMessageData** | [InAppMessageData](/developers/mobile-sdk/class-reference/android/campaigns#inappmessagedata) | In-app message data. |
##### onContextFromAppRequired(InAppMessageData inAppMessageData) {id=on-in-app-listener-on-context-from-app-required}
This method is called when an individual context (for example a profile ID, an item SKU) for an in-app message is needed.
| Parameter | Type | Description |
| --- | --- | --- |
| **inAppMessageData** | [InAppMessageData](/developers/mobile-sdk/class-reference/android/campaigns#inappmessagedata) | In-app message data. |
##### onHandledOpenUrl(InAppMessageData inAppMessageData) {id=on-in-app-listener-on-handled-open-url}
This method is called when the [`SRInApp.openUrl(url)` method](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#open-url) is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **inAppMessageData** | [InAppMessageData](/developers/mobile-sdk/class-reference/android/campaigns#inappmessagedata) | In-app message data. |
##### onHandledOpenDeepLink(InAppMessageData inAppMessageData) {id=on-in-app-listener-on-handled-open-deeplink}
This method is called when the [`SRInApp.openDeeplink(url)` method](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#open-deeplink) is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **inAppMessageData** | [InAppMessageData](/developers/mobile-sdk/class-reference/android/campaigns#inappmessagedata) | In-app message data. |
##### onCustomAction(String identifier, HashMap params, InAppMessageData inAppMessageData) {id=on-in-app-listener-on-custom-action}
This method is called when the [`SRInApp.handleCustomAction(name, params)` method](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#trigger-a-custom-action) is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **inAppMessageData** | [InAppMessageData](/developers/mobile-sdk/class-reference/android/campaigns#inappmessagedata) | In-app message data. |
| **identifier** | String | Identifier of the custom action. |
| **params** | HashMap | Custom action parameters. |
---
---
### OnInlineInAppListener {id=on-inline-in-app-listener}
A listener to handle global events for [inline in-app messages](/developers/mobile-sdk/campaigns/in-app-message/inline-in-app).
To set your object with listener methods, you must use [this method](/developers/mobile-sdk/method-reference/android/campaigns#set-inline-in-app-listener).
##### onInlineInAppAvailable(InlineInAppView view, InlineInAppMessageData data) {id=on-inline-in-app-listener-on-inline-in-app-available}
This method is called when the SDK creates a ready-to-display component after an event-based trigger for a placement with no existing host view.
| Parameter | Type | Description |
| --- | --- | --- |
| **view** | InlineInAppView | The ready-to-display inline in-app view. |
| **data** | InlineInAppMessageData | Inline in-app message data. |
##### onContextFromAppRequired(InAppMessageData data) {id=on-inline-in-app-listener-on-context-from-app-required}
This method is called when a per-message context is needed for rendering. This method is called on a background thread.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InAppMessageData | In-app message data. |
##### onOpenedUrl(InlineInAppMessageData data, String url) {id=on-inline-in-app-listener-on-opened-url}
This method is called when the `SRInApp.openUrl(url)` method is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **url** | String | The URL to open. |
##### onOpenedDeepLink(InlineInAppMessageData data, String deepLink) {id=on-inline-in-app-listener-on-opened-deep-link}
This method is called when the `SRInApp.openDeeplink(url)` method is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **deepLink** | String | The deep link value. |
##### onCustomAction(InlineInAppMessageData data, String name, Map params) {id=on-inline-in-app-listener-on-custom-action}
This method is called when the `SRInApp.handleCustomAction(name, params)` method is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **name** | String | Name of the custom action. |
| **params** | Map | Custom action parameters. |
##### onCustomMethod(String name, HashMap params, InlineInAppMessageData data, InAppCustomMethodCompletion completion) {id=on-inline-in-app-listener-on-custom-method}
This method is called when the `SRInApp.customMethod(name, params)` method is used in an in-app message. Resolve the completion exactly once with success or failure.
| Parameter | Type | Description |
| --- | --- | --- |
| **name** | String | Name of the custom method. |
| **params** | HashMap | Custom method parameters. |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **completion** | InAppCustomMethodCompletion | Completion to resolve with `success()` or `failure()`. |
---
---
### OnInlineInAppViewListener {id=on-inline-in-app-view-listener}
A per-component listener to handle the lifecycle of an [inline in-app message](/developers/mobile-sdk/campaigns/in-app-message/inline-in-app) view.
##### onProcessingStarted() {id=on-inline-in-app-view-listener-on-processing-started}
This method is called when the SDK starts processing a campaign for this component.
```Java
void onProcessingStarted()
```
```Kotlin
onProcessingStarted()
```
##### onLoaded(InlineInAppMessageData data) {id=on-inline-in-app-view-listener-on-loaded}
This method is called when the inline in-app message content is loaded for the first time.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
##### onUpdated(InlineInAppMessageData data) {id=on-inline-in-app-view-listener-on-updated}
This method is called when the inline in-app message content is updated with a new campaign.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **error** | String | Error description. |
##### onSizeChanged(InlineInAppMessageData data, InlineInAppSize size) {id=on-inline-in-app-view-listener-on-size-changed}
This method is called when the in-app message content requests a size change via the `SRInApp.setComponentSize(width, height)` JS method. The measured size is delivered as an `InlineInAppSize`, exposing it in physical pixels, density-independent pixels (dp), and as a fraction of the device screen.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **size** | InlineInAppSize | The requested size. Exposes `getWidthPx()`/`getHeightPx()` (physical pixels), `getWidthDp()`/`getHeightDp()` (density-independent pixels), and `getWidthScreenRatio()`/`getHeightScreenRatio()` (0..1 fraction of the screen). |
##### onRemove(InlineInAppMessageData data) {id=on-inline-in-app-view-listener-on-remove}
This method is called when the in-app message content requests removal from the view hierarchy via the `SRInApp.close()` or `SRInApp.closeAndTrigger()` JS method.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
---
---
### OnLocationUpdateListener {id=on-location-update-listener}
A listener to handle events about location.
##### onLocationUpdateRequired() {id=on-location-update-listener-on-location-update-required}
This method is called when the Tracker module requests a location update.
```Java
- void onLocationUpdateRequired()
```
```Kotlin
fun onLocationUpdateRequired()
```
---
---
### OnContentWidgetListener {id=on-content-widget-listener}
A listener to handle [Content Widget](/developers/mobile-sdk/displaying-recommendations/content-widget) actions.
##### onLoad(ContentWidget contentWidget) {id=on-content-widget-listener-on-load}
This method is called after a widget is loaded.
```Kotlin
fun onLoad(contentWidget:ContentWidget)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **contentWidget` | [ContentWidget](/developers/mobile-sdk/class-reference/android/content-widget#contentwidget) | The widget instance that called the listener method |
##### onLoadingError(ContentWidget contentWidget, ApiError apiError) {id=on-content-widget-listener-on-loading-error}
This method is called when an error occurs while loading a widget.
```Kotlin
fun onLoadingError(contentWidget:ContentWidget, apiError:ApiError)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **contentWidget** | [ContentWidget](/developers/mobile-sdk/class-reference/android/content-widget#contentwidget) | The widget instance that called the listener method |
| **apiError** | [ApiError](/developers/mobile-sdk/class-reference/android/miscellaneous#apierror) | The error that occurred |
##### onClickActionReceive(ContentWidget contentWidget, BaseModel model) {id=on-content-widget-listener-on-click-action-receive}
This method is called when the customer clicks a widget’s item.
```Kotlin
fun onClickActionReceive(contentWidget:ContentWidget, model:BaseModel)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **contentWidget** | [ContentWidget](/developers/mobile-sdk/class-reference/android/content-widget#contentwidget) | The widget instance that called the listener method |
| **model** | BaseModel | The model's object that was clicked |
##### onLoading(ContentWidget contentWidget, boolean isLoading) {id=on-content-widget-listener-on-loading}
This method is called when the widget’s loading state changes.
```Kotlin
fun onLoading(contentWidget:ContentWidget, isLoading:Boolean)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **contentWidget** | [ContentWidget](/developers/mobile-sdk/class-reference/android/content-widget#contentwidget) | The widget instance that called the listener method |
| **isLoading** | Boolean | Widget's loading state |
##### onSizeChange(ContentWidget contentWidget, ViewGroup.LayoutParams size) {id=on-content-widget-listener-on-size-change}
This method is called when the widget’s size changes.
```Kotlin
fun onSizeChange(contentWidget:ContentWidget, size:ViewGroup.LayoutParams)
```
| Parameter | Type | Description |
| --- | --- | --- |
| **contentWidget** | [ContentWidget](/developers/mobile-sdk/class-reference/android/content-widget#contentwidget) | The widget instance that called the listener method |
| **size** | ViewGroup.LayoutParams | Widget's new size |
# Android
## Configuring push notifications (Android)
### Prerequisites
---
Google Firebase Cloud Messaging is necessary to handle [Mobile Campaigns](/docs/campaign/Mobile) sent from Synerise.
1. Follow the instructions in [this article](https://firebase.google.com/docs/storage/android/start).
2. Integrate the Firebase project with Synerise. See [this article](/docs/settings/tool/firebase).
Documentation on how to prepare your first push notification is available in our [user guide](/docs/campaign/Mobile).
### Set up Firebase Cloud Messaging for Synerise SDK
---
1. Register your service in the AndroidManifest:
2. In your application, implement registration for Firebase notifications:
```java
public class App extends MultiDexApplication implements OnRegisterForPushListener {
private static final String TAG = App.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
Synerise.Builder.with(this, syneriseClientApiKey, appId)
.notificationIcon(R.drawable.ic_notification_icon)
.pushRegistrationRequired(this)
...
.build();
}
@Override
public void onRegisterForPushRequired() {
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(instanceIdResult -> {
String refreshedToken = instanceIdResult.getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
IApiCall call = Client.registerForPush(refreshedToken, true);
call.execute(() -> Log.d(TAG, "Register for Push succeed: " + refreshedToken),
apiError -> Log.w(TAG, "Register for push failed: " + refreshedToken));
});
}
}
```
```kotlin
class App:MultiDexApplication(), OnRegisterForPushListener {
fun onCreate() {
super.onCreate()
Synerise.Builder.with(this, syneriseClientApiKey, appId)
.notificationIcon(R.drawable.ic_notification_icon)
.pushRegistrationRequired(this)
build()
}
fun onRegisterForPushRequired() {
FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener({ instanceIdResult->
val refreshedToken = instanceIdResult.getToken()
Log.d(TAG, "Refreshed token: " + refreshedToken)
val call = Client.registerForPush(refreshedToken, true)
call.execute({ Log.d(TAG, "Register for Push succeed: " + refreshedToken) },
{ apiError-> Log.w(TAG, "Register for push failed: " + refreshedToken) }) })
}
companion object {
private val TAG = App::class.java!!.getSimpleName()
}
}
```
The second parameter of the registration method is the agreement for mobile push campaigns. In the Profile's card in Synerise, you can find it in the **Subscriptions** section (if you have the required access permission). Learn more about the [Client.registerForPush(token, mobilePushAgreement) method in the method reference](/developers/mobile-sdk/method-reference/android/campaigns#register-for-push-notifications).
3. Add registerForPush method inside onNewToken callback. This should be done in your class which extends FirebaseMessagingService
```kotlin
fun onNewToken(refreshedToken:String) {
super.onNewToken(refreshedToken)
Log.d(TAG, "Refreshed token: " + refreshedToken)
if (refreshedToken != null)
{
val call = Client.registerForPush(refreshedToken, true)
call.execute({ Log.d(TAG, "Register for Push succeed: " + refreshedToken) },
{ apiError-> Log.w(TAG, "Register for push failed: " + refreshedToken) })
}
}
```
4. Pass the incoming push notification payload to the `Injector` in your `FirebaseMessagingService` implementation:
```java
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
boolean isSynerisePush = Injector.handlePushPayload(remoteMessage.getData());
}
}
```
```kotlin
class MyFirebaseMessagingService:FirebaseMessagingService() {
fun onMessageReceived(remoteMessage:RemoteMessage) {
super.onMessageReceived(remoteMessage)
val isSynerisePush = Injector.handlePushPayload(remoteMessage.getData())
}
}
```
Overriding `onMessageReceived(RemoteMessage)` stops simple notifications from being displayed while the app is the active screen.
5. In order to configure a notification icon and notification icon color, you need to set the following two parameters in `AndroidManifest.xml`, in the `application` section:
The default values are: `android icon` and `white color`.
Check [the repository of our sample app](https://github.com/Synerise/android-sdk) for an example usage of building your non-Synerise notification.
### Keep Firebase token always up-to-date
---
You must always keep the Firebase token updated.
- Whenever the user changes the notification consent in the system or the application, you should call the `registerForPush` method ([Android](/developers/mobile-sdk/method-reference/android/campaigns#register-for-push-notifications); [iOS](/developers/mobile-sdk/method-reference/ios/campaigns#register-for-push-notifications), [Flutter](/developers/mobile-sdk/method-reference/flutter/campaigns), [React Native](/developers/mobile-sdk/method-reference/react-native/campaigns)).
- In many cases in the application lifecycle, such as authorization, destroyed sessions, user context change, periodic jobs ([Work Manager](/developers/mobile-sdk/installation-and-configuration/android#work-manager)), and so on, the SDK invokes the [snr_registerForPushNotificationsIsNeeded(origin)](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener-on-register-for-push-required-with-origin) method or [snr_registerForPushNotificationsIsNeeded()](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener-on-register-for-push-required) method.
[Work Manager](/developers/mobile-sdk/installation-and-configuration/android#work-manager) allows you to keep the Firebase token updated even if the host application is not launched for a long time. It launches your app in the background approximately every 20 days and refreshes the token so it stays up to date.
#### Assign notifications to channels
Starting with Android 8.0 (API level 26), all notifications must be assigned to a channel. Otherwise, they are not displayed.
You can implement notifications in one of the following ways:
- If you already have a channel defined in your application, use the `notificationDefaultChannelId(String)` and `NotificationHighPriorityChannelId(String)` methods of Builder during SDK initialization.
- You cannot configure more than two notification channels.
- If you want the SDK to set the channel names to default (same as the application name), initialize the SDK without the methods mentioned above.
### Callback methods
---
[NotificationListener](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-notification-listener) is available from SDK 4.9.0 version.
If you want to receive callbacks to inform the application about notification's state, implement `OnNotificationListener` using the `Injector.setOnNotificationListener` method.
For details, see [this article](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-notification-listener).
See sample code from the application below:
```java
Injector.setOnNotificationListener(new OnNotificationListener() {
@Override
public void onNotificationReceived(NotificationInfo notificationInfo) {
}
@Override
public void onNotificationClicked(NotificationInfo notificationInfo) {
}
@Override
public void onNotificationDismissed(NotificationInfo notificationInfo) {
}
@Override
public void onActionButtonClicked(NotificationInfo notificationInfo, String actionButton) {
}
});
```
```kotlin
Injector.setOnNotificationListener(
object callback: OnNotificationListener() {
override fun onNotificationReceived(notificationInfo: NotificationInfo) {
}
override fun onNotificationClicked(notificationInfo: NotificationInfo) {
}
override fun onNotificationDismissed(notificationInfo: NotificationInfo) {
}
override fun onActionButtonClicked(
notificationInfo: NotificationInfo,
actionButton: String) {
}
})
```
### Configure notification encryption
---
To enable encrypted push notifications, you must change the configuration of your workspace in the Synerise Platform. For details, read [Google Firebase](/docs/settings/tool/firebase).
In the mobile application, you must set `encryption` to `true` in the notification settings.
The SDK performs the encryption as a part of the `Synerise.Notifications.handleNotification` method.
If you use only the `"Synerise"` issuer in push notifications, no more actions are required.
If you need custom integration of encrypted push notifications, implement the following solution:
```java
Map data = remoteMessage.getData();
if (Injector.isPushEncrypted(data)) {
data = Injector.decryptPushPayload(data);
}
// your operations on push notification
```
```kotlin
val data = remoteMessage.getData()
if (Injector.isPushEncrypted(data)) {
data = Injector.decryptPushPayload(data)
}
// your operations on push notification
```
The `decryptPushPayload` method returns raw data when the payload is not encrypted. If the crypter fails, the method returns null.
For more information, read [the description of the decryption method](/developers/mobile-sdk/method-reference/android/campaigns#decrypt-push-notification).
### Handling actions from push notifications
---
- [Read more about types of actions in campaigns](/developers/mobile-sdk/campaigns/action-handling#types-of-actions-in-campaigns)
- [Read more about handling actions from push notifications](/developers/mobile-sdk/campaigns/action-handling)
# SDK lifecycle
## Set Synerise delegate
---
This method sets an object for Synerise delegate methods.
**Declared In:**
Headers/SNRSynerise.h
**Related To:**
[SyneriseDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate)
**Class:**
Synerise
**Declaration:**
**Discussion:**
Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate).
## Initialization
---
This method initializes Synerise.
This method must be called before any other Synerise SDK method and only once during the application's lifecycle.
**Properties:**
| Property | Type | Description |
| --- | --- | --- |
| **Initializer** | [SyneriseInitializer](/developers/mobile-sdk/class-reference/react-native/lifecycle#syneriseinitializer) | Returns the [SyneriseInitializer](/developers/mobile-sdk/class-reference/react-native/lifecycle#syneriseinitializer) object used for initialization |
| **Settings** | [SettingsModule](/developers/mobile-sdk/class-reference/react-native/modules#settings) | Returns the Settings module when Synerise is initialized |
| **Client** | [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) | Returns the Client module when Synerise is initialized |
| **Tracker** | [TrackerModule](/developers/mobile-sdk/class-reference/react-native/modules#tracker) | Returns the Tracker module when Synerise is initialized |
| **Notifications** | [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) | Returns the Notifications module when Synerise is initialized|
| **Injector** | [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) | Returns the Injector module when Synerise is initialized |
| **Promotions** | [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) | Returns the Promotions module when Synerise is initialized |
| **Content** | [ContentModule](/developers/mobile-sdk/class-reference/react-native/modules#content) | Returns the Content module when Synerise is initialized |
**Methods:**
This method sets the callback function that is invoked when the Synerise SDK is initialized.
public static onReady(callback: () => void)
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#initialization)
---
This method sets the callback function that is invoked when an error occurs while initializing the Synerise SDK.
public static onError(callback: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#initialization)
---
This method checks if Synerise is initialized.
public static isInitialized(): boolean
---
This method changes the Profile API Key (formerly Client API Key) dynamically.
public static changeApiKey(ApiKey: string, config?: InitializationConfig | undefined)
---
---
---
### SyneriseInitializer
Class responsible for initialization of the SDK.
**Declared In:**
lib/main/Synerise.js
**Declaration:**
class SyneriseInitializer
**Methods:**
This method sets Profile API Key (formerly Client API Key) for the SDK initialization.
public withApiKey(ApiKey: string)
Before version 1.0.0, this method was called `withClientApiKey`.
---
This method sets the Synerise API base URL for SDK initialization in a custom environment.
public withBaseUrl(baseUrl: string)
---
This method sets the salt string for request validation.
public withRequestValidationSalt(requestValidationSalt: string)
---
This method enables or disables console logs from Synerise SDK.
public withDebugModeEnabled(debugModeEnabled: boolean)
---
This method enables or disables crash handling by Synerise SDK.
public withCrashHandlingEnabled(crashHandlingEnabled: boolean)
---
This method sets the required settings prior to the Synerise initialization.
**Parameters:**
| Parameter | Type | Mandatory | Default | Description |
| --- | --- | --- | --- | --- |
| **string** | String | yes | - | Synerise Profile salt string for request validation |
**Return Value:**
No value is returned.
# Profile identification
## Anonymous customers
---
When you initialize the SDK, on the first start a UUID is generated and a JWT token is retrieved for an *anonymous customer*. The customer in this scenario is fully anonymous within the system and does not contain any personal information.
Such a token allows some basic operations such as tracking events of anonymous customers, sending in-app messages, push notifications, display documents and more. However, better profile identification and management with extra features is provided when a customer is logged in.
## Recognized customers
---
When an anonymous profile provides the unique identifier, the anonymous profile in the database is updated with new data. It becomes a known customer profile, which means that any activity before the customer was recognized is still present in the profile’s history.
You can operate on personal information without fully authenticating a customer.
You may have already imported customer data into Synerise and you have personal information in the system. The data can be linked.
In such cases, you need to authenticate through your own backend systems. Before you can do that, you must merge the UUIDs from the SDK with a specific customer:
1. Retrieve the customer UUID generated by Synerise SDK.
2. Process the UUID in your own backend. If you use 3rd party authorization, you may need to pass this UUID into other systems.
3. Authorize the customer and match their identifier (loyalty card number, email address, or another type of identifier used in your system) with the customer UUID from Synerise.
4. Provide the customer UUID back to Synerise with all the additional information collected through the authorization process.
Sending this data directly from the application itself is highly discouraged and may cause authorization issues.
We recommend this customer recognition process to advanced clients. If you are a new Synerise clients and would like to run this kind of integration, you can contact us through [this form](https://hgintelligence.atlassian.net/servicedesk/customer/portal/1).
## Authenticated customers
---
Synerise offers a means to fully authenticate customers and create customer sessions with JWT tokens that have access to all the features provided by Synerise.
Three authentication methods are supported:
- [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication)
- [Synerise Authentication](/developers/mobile-sdk/user-identification-and-authorization/synerise-authentication)
- [OAuth](/developers/mobile-sdk/user-identification-and-authorization/oauth)
This is the recommended authentication method.
- [Facebook Login](/developers/mobile-sdk/user-identification-and-authorization/authenticate-external-providers#facebook-login)
- [Sign in with Apple](/developers/mobile-sdk/user-identification-and-authorization/authenticate-external-providers#sign-in-with-apple)
Available only for iOS and React Native (iOS).
# SDK Lifecycle
## InitializationConfig
Class for additional initialization parameters.
**Declared In:**
lib/main/initialization_config.dart
**Declaration:**
class InitializationConfig
**Properties**
| Property | Type | Description |
| --- | --- | --- |
| **requestValidationSalt** | String | [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) salt |
---
---
## Synerise
Main SDK class responsible for managing all Synerise modules and core features.
**Declared In:**
lib/synerise.dart
**Related To:**
[SyneriseInitializer](/developers/mobile-sdk/class-reference/flutter/lifecycle#syneriseinitializer)
[SettingsImpl](/developers/mobile-sdk/class-reference/flutter/modules#settings)
[NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications)
[ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
[TrackerImpl](/developers/mobile-sdk/class-reference/flutter/modules#tracker)
[InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector)
[ContentImpl](/developers/mobile-sdk/class-reference/flutter/modules#content)
**Declaration:**
class Synerise
**Properties:**
| Property | Type | Description |
| --- | --- | --- |
| **settings** | [SettingsImpl](/developers/mobile-sdk/class-reference/flutter/modules#settings) | Returns the Settings module |
| **notifications** | [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) | Returns the Notifications module |
| **client** | [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client) | Returns the Client module |
| **tracker** | [TrackerImpl](/developers/mobile-sdk/class-reference/flutter/modules#tracker) | Returns the Tracker module |
| **injector** | [InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector) | Returns the Injector module |
| **content** | [ContentImpl](/developers/mobile-sdk/class-reference/flutter/modules#content) | Returns the Content module |
**Methods:**
This method initializes Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/lifecycle#initialization)
---
This method changes a Profile (formerly Client) API key dynamically.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/lifecycle#change-profile-api-key-dynamically)
---
---
---
## SyneriseInitializer
Class responsible for initialization of the SDK.
**Declared In:**
lib/main/synerise_initializer.dart
**Declaration:**
class SyneriseInitializer
**Methods:**
This method sets Profile API Key (formerly Client API Key) for the SDK initialization.
SyneriseInitializer withApiKey(String apiKey)
Before version 2.0.0, this method was called `withClientApiKey`.
---
This method sets the Synerise API base URL for SDK initialization in a custom environment.
SyneriseInitializer withBaseUrl(String baseUrl)
---
This method sets the salt string for request validation.
---
This method chooses the type of mobile services to use:
- `gms` for Google Mobile Services (default)
- `hms` for Huawei Mobile Services (can only be used on Huawei devices)
# Android
## Method reference - Android
# Android
## Installation and configuration (Android)
In this article, you will find out how to install, configure, and initialize the Synerise SDK in an Android mobile application. While performing the actions from this guide, keep the presented order.
The [Settings](/developers/mobile-sdk/settings#pre-initialization-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](/developers/mobile-sdk/overview).
### Requirements
---
You need:
* Access to a [workspace](/docs/settings/workspace)
* A Profile [API Key](/docs/settings/tool/api#adding-api-keys)
When creating the API key, use allowlisting or denylisting to only allow the events you intend to use.
* Minimum Android SDK version: 24
* Supported targetSDKVersion: 34
#### 3rd Party Frameworks
- [RxJava](https://github.com/ReactiveX/RxJava)
- [RxAndroid](https://github.com/ReactiveX/RxAndroid)
- [OkHttp](https://github.com/square/okhttp)
- [Retrofit](https://github.com/square/retrofit)
- [OkHttp](https://github.com/square/okhttp)
- [Picasso](https://github.com/square/picasso)
- [Fresco](https://github.com/facebook/fresco)
- [ConstraintLayout](https://github.com/androidx/constraintlayout)
- [Joda-Time](https://github.com/JodaOrg/joda-time)
### Installation
---
1. Set maven path in your `root/build.gradle` file:
We guarantee stability only on Android Gradle plugin 3.4.2 or lower.
3. Import dependency in your `app/build.gradle` file and apply the plugin:
apply plugin: 'com.android.application'
...
dependencies {
...
// Synerise Android SDK;
implementation 'com.synerise.sdk:synerise-mobile-sdk:ANDROID_SDK_VERSION'
// Replace ANDROID_SDK_VERSION with the version, for example 5.4.0;
// Check latest version at https://github.com/Synerise/android-sdk/blob/master/CHANGELOG.md
}
4. *For Android Studio versions older than 3.5*: Go to **File > Settings > Build, Execution, Deployment > Instant Run** and make sure that Instant Run is disabled.
### Configuration
---
For your convenience, [Synerise.Builder](/developers/mobile-sdk/class-reference/android/lifecycle#synerise-builder) makes it possible to configure SDK behavior depending on your needs.
The `Synerise.Builder.with(..)` method is mandatory.
The basic callbacks you need:
- [.pushRegistrationRequired(OnRegisterForPushListener)](/developers/mobile-sdk/class-reference/android/lifecycle#synerise-builder) - Synerise SDK may request registering a customer for push notifications. This callback is called after a customer signs in, signs up, or deletes an account.
- [.baseUrl(String)](/developers/mobile-sdk/class-reference/android/lifecycle#synerise-builder) - This callback lets you provide your custom base URL to use your own domain for connecting to the Synerise API.
If you use Synerise hosted on:
- Google Cloud ([app.geb.synerise.com](https://app.geb.synerise.com)), use `baseUrl(https://api.geb.snrapi.com)`
- Microsoft Azure USA ([app.azu.synerise.com](https://app.azu.synerise.com)), use `baseUrl(https://api.azu.snrapi.com)`
- `.mesaggingServiceType(MessagingServiceType)` - This callback sets the messaging provider: Huawei Mobile Services (HMS) or Google Mobile Services (GMS). When publishing the app to appGallery, we recommend using HMS.
Click to expand the full list of callbacks
Builds the Synerise SDK with the provided data. The `Synerise.Builder.build()` method can be called only once during the entire application lifecycle, so you must call this method in your `Application` class.
When true, enables full network traffic logs. It is not recommended to use debug mode in a release version of your app. Debug mode is disabled by default.
`Synerise.settings.injector.automatic = boolean;`
When true, enables automatic mode in the injector.
Sets the maximum time (in ms) since the last event queue was sent before attempting to automatically send another queue. Default value: 5000 ms. Minimum value: 50 ms.
Sets the minimum number of events in queue required to send them. Default value: 10. You can set the value between 1 and 100.
### Initialization
---
Synerise SDK must be initialized in the [Application class](https://developer.android.com/reference/android/app/Application). This is because Synerise SDK performs some operations while the application is running in the background.
1. Initialize Synerise Android SDK by using the `with` method and provide:
- `Application name`
- `Application instance`
- [API Key](/docs/settings/tool/api)
1. To get the Profile (client) API key, go to **Synerise > Settings > API keys**.
2. On the list of the keys, select the one you created as a part of [requirements](#requirements).
3. In the **General** section, click **Show**.
4. Copy the API key.
2. Add the key in your `Application` sub-class:
public class YourApp extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
...
}
You can find more information about MultiDex at [this link](https://developer.android.com/studio/build/multidex.html).
#### AndroidManifest Merger {id=troubleshooting-androidmanifest-merger}
Sometimes, AndroidManifest Merger errors may occur. In that case, paste the following code in your AndroidManifest application tag.
<application
...
tools:replace="android:theme">
Also, if your app did not ask for location permission, remove it from your app with:
### Work Manager
Work Manager is a mechanism to schedule and run code in the background to keep your app up to date. Synerise supports using Work Manager since SDK version **5.21.0**.
#### Benefits
Currently, the SDK uses background tasks only to refresh the registration token for push notifications every 20 days. In these situations, the SDK invokes the [onRegisterForPushRequired(origin:)](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener-on-register-for-push-required-with-origin) callback method or [onRegisterForPushRequired()](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener-on-register-for-push-required) callback method.
#### Setting up
Work Manager is configured out of the box without any special configuration.
### Proguard configuration
The Synerise Android SDK obfuscates code on its own. We highly recommend keeping the entire SDK. Rules:
```plaintext
# keep entire Synerise SDK
-keep class com.synerise.sdk.** { *; }
-keepclassmembers class com.synerise.sdk.** { *; }
-keepclassmembers class com.synerise.sdk.** {
public ();
}
```
# Android
## Content Widget (Android)
Content widget is a feature in the Software Development Kit that allows you to embed an easily customizable view with [recommendations](/docs/ai-hub/recommendations-v2) in your application.
Two view layouts are available:
- Horizontal slider - a single row view that slides horizontally on the screen.
- Grid view - can be displayed as full- or half-screen grid layout within your app.
Both views offer a number of configuration options that allow you to style the view consistently in the app. Additionally, the Content widget automatically tracks 4 events:
- `recommendation.seen` or `recommendation.view` (depending on configuration) sent when a recommended item is visible to the customer.
Recommendation.seen event
- `recommendation.click` sent when a customer clicks the recommended item.
Recommendation.click event
- `product.like` sent when a customer clicks a selectable button in the recommendation. (The button must be added)
Event sent when a user clicks the "like" button on an item
- `product.dislike` sent when a customer clicks a selectable button in the recommendation a second time. (The button must be added)
Product.dislike event
Currently, the widget can only be used for displaying AI recommendations.
### Prerequisites
---
To use the content widget feature, you must:
- Obtain a customer token from [Customer Authentication](/developers/mobile-sdk/user-identification-and-authorization/overview#authenticated-customers).
- [Create an AI Recommendation](/docs/ai-hub/recommendations-v2).
- [Create a document](/docs/assets/documents).
Such a document should contain the following content:
- In the notepad, save the document's slug and the ID of the recommendation for later use.
It's a good practice to name slugs based on the area of the app that you want to place the content in, for example `product-details`, `menu`, and so on.
### Basic implementation
---
Configure the `ContentWidgetOptions` and `ContentWidgetAppearance` settings first.
| Class | Description |
| --- | --- |
| `ContentWidgetOptions` | Contains options for business logic, such as the slug, product identifier, and so on. [Read more](#widget-options).|
| `ContentWidgetAppearance` | Contains the UI configuration. [Read more](#widget-options). |
The example below is the most basic implementation.
```java
String productId = "10214";
String slug = "similar";
ContentWidgetOptions options = new ContentWidgetRecommendationsOptions(this, slug, new OnRecommendationModelMapper() {
@Override
public ContentWidgetRecommendationDataModel onRecommendationMapping(Recommendation recommendation) {
// Mapping provided by
HashMap data = recommendation.getFeed();
String imageLink = (String) data.get("imageLink");
String productName = (String) data.get("title");
String price = null;
String salePrice = null;
try {
JSONObject json = new JSONObject(data.get("price").toString());
price = json.getString("value");
if (data.containsKey("salePrice")) {
JSONObject jsonSalePrice = new JSONObject(data.get("salePrice").toString());
salePrice = jsonSalePrice.getString("value");
}
} catch (JSONException e) {
e.printStackTrace();
}
return new ContentWidgetRecommendationDataModel(productName, imageLink, price, salePrice, null);
}
});
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
ContentWidgetItemLayout itemLayoutDetails = new ContentWidgetItemLayout();
ContentWidgetHorizontalSliderLayout layout = new ContentWidgetHorizontalSliderLayout();
ContentWidgetAppearance contentWidgetAppearance = new ContentWidgetAppearance(layout, itemLayoutDetails);
ContentWidget widget = new ContentWidget(options, contentWidgetAppearance);
View view = widget.getView(); // our widget
insertPoint.addView(view); // your view which will receive widget
```
```kotlin
val productId = "10214"
val slug = "similar"
val options = ContentWidgetOptions(this, slug)
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
val itemLayoutDetails = ContentWidgetItemLayout()
val layout = ContentWidgetHorizontalSliderLayout()
val contentWidgetAppearance = ContentWidgetAppearance(layout, itemLayoutDetails)
val widget = ContentWidget(options, contentWidgetAppearance)
val view = widget.getView() // our widget
insertPoint.addView(view) // your view which will receive widget
```
### Widget options
---
The [ContentWidgetRecommendationOptions](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetoptions) class is responsible for defining the business logic options of the widget, for example:
- document slug
- product identifier (which is stored inside class instance in attributes HashMap)
- recommendation model mapper
The table explains the parameters that can be configured in `ContentWidgetRecommendationOptions`.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| activity | `Activity` | - | Activity to which you insert the widget (must be included) |
| slug | `String` | - | Slug of a document |
| attributes | `Hashmap` | - | Custom attributes for generating data |
| mapper | `OnRecommendationModelMapper` | - | Mapper responsible for mapping data from feed to contentWidgetRecommendation model |
| recommendationEventType | `RecommendationEventType` | - | Recommendation event type.
RECOMMENDATION_VIEW_EVENT sends all products in one event. We highly recommend using this type of event in content widget.
RECOMMENDATION_SEEN_EVENT sends each event as a separate event.
|
#### Example
```java
String productId = "10214";
String slug = "similar";
ContentWidgetOptions options = new ContentWidgetRecommendationsOptions(this, slug, new OnRecommendationModelMapper() {
@Override
public ContentWidgetRecommendationDataModel onRecommendationMapping(Recommendation recommendation) {
// here you should implement your mapping to SyneriseModel
HashMap data = recommendation.getFeed();
String imageLink = (String) data.get("imageLink");
String productName = (String) data.get("title");
String price = null;
String salePrice = null;
try {
JSONObject json = new JSONObject(data.get("price").toString());
price = json.getString("value");
if (data.containsKey("salePrice")) {
JSONObject jsonSalePrice = new JSONObject(data.get("salePrice").toString());
salePrice = jsonSalePrice.getString("value");
}
} catch (JSONException e) {
e.printStackTrace();
}
return new ContentWidgetRecommendationDataModel(productName, imageLink, price, salePrice, null);
}
});
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
```
```kotlin
var productId = "10214"
var slug = "similar"
var options: ContentWidgetOptions = ContentWidgetRecommendationsOptions(this, slug, object : OnRecommendationModelMapper() {
fun onRecommendationMapping(recommendation: Recommendation): ContentWidgetRecommendationDataModel? {
// here you should implement your mapping to SyneriseModel
val data = recommendation.getFeed()
val imageLink = data["imageLink"] as String?
val productName = data["title"] as String?
var price: String? = null
var salePrice: String? = null
try {
val json = JSONObject(data["price"].toString())
price = json.getString("value")
if (data.containsKey("salePrice")) {
val jsonSalePrice = JSONObject(data["salePrice"].toString())
salePrice = jsonSalePrice.getString("value")
}
} catch (e: JSONException) {
e.printStackTrace()
}
return ContentWidgetRecommendationDataModel(productName, imageLink, price, salePrice, null)
}
})
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
```
The recommendation response depends on your item feed.
In order to map your item feed, override `onRecommendationMapping` and inside it return [ContentWidgetRecommendationDataModel](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetrecommendationdatamodel).
The configuration of the data frames is available in [AI engine configuration](https://app.synerise.com/spa/modules/ai-v2/config). It is defined separately for each item feed.
### Appearance configuration
---
The [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetappearance) class is responsible for defining the appearance of the widget.
The class consists of parameters that define the widget's appearance, however, two of them are the most important:
- **Main layout class**: defines the way of distributing elements in the widget. Currently, two layouts are provided:
- `ContentWidgetHorizontalSliderLayout`
- `ContentWidgetGridLayout`
- **Item layout class**: defines appearance and parameters for the item in the widget. Currently, there is only one layout provided: `ContentWidgetBaseItemLayout`.
The table explains the parameters that can be configured in [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetappearance).
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| layout | [ContentWidgetBaseLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetbaselayout) | - | Class that inherits from `ContentWidgetBaseLayout`, contains the UI details of the widget's layout |
| itemLayout | [ContentWidgetBaseItemLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetbaseitemlayout) | - | Class that inherits from `ContentWidgetBaseItemLayout`, contains the UI details of a single item in a widget |
### Layouts
#### Horizontal slider
---
This layout is intended to present recommendations in a fixed-hight horizontal scrollable slider.
Each item in the slider is called a *card*.
Click to see a screen with example widget with horizontal slider
##### Parameters
The table below contains the parameters that can be configured in [ContentWidgetHorizontalSliderLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetsliderlayout).
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| cardViewSize | `ViewGroup.LayoutParams` | 0 | Size of a single item (cardView). You can provide this parameter in dp (recommended) or px. |
| cardViewHorizontalSpacing | `Int` | 0 | Horizontal spacing between items. You can provide this parameter in dp (recommended) or px. |
| cardViewBackgroundColor | `Int` | #fff | Background color of a cardView |
`CardViewSize` can be set either by attribution or by a setter.
#### Grid view
---
This layout presents recommendations in a vertical scrollable grid, with elements organized into columns and rows. You can create a full- or half-screen widget.
Click to see a screen with example widget with grid layout
##### Constructor
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| preferredWidth | `Float` | - | Preferred width of your widget. You can pass the width in dp (recommended) or px |
```kotlin
var screenWidthDp = displayMetrics.widthPixels
var layout = ContentWidgetGridLayout(screenWidthDp)
```
##### Parameters
The table contains the parameters that can be configured in [ContentWidgetGridLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetgridlayout).
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| cardViewSize | `ViewGroup.LayoutParams` | 0 | Size of a single item (cardView) |
| cardViewVerticalSpacing | `Int` | 0 | Vertical spacing between items in dp or px |
| cardViewHorizontalSpacing | `Int` | 0 | Horizontal spacing between items in dp or px |
| cardViewBackgroundColor | `Int` | #fff | Background color of a cardView |
| includeEdgeSpacing | `Boolean` | false | When `true`, edge spacing is enabled |
CardViewSize and preferredWidth can be set by attribution or by a setter.
#### Basic item layout
---
This is the basic layout for items. It contains: the image, the title, and the price from the uploaded data.
##### Parameters
The table below contains parameters that can be configured in `ContentWidgetItemLayout`.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| imageHeightToCardHeightRatio | `Double` | 0.6 | Image height. A ratio of `0.6` means that the image height equals 60% of the entire height of an item |
| imageWidthToCardWidthRatio | `Double` | 1 | Image width. `1` means that the image width is equal to the width of the item |
| imageScaleType | `ImageView.ScaleType` | ImageView.ScaleType.CENTER_INSIDE | Scaling type of the image |
| imageMargin | `Int` | 0 | General margin of the image |
| itemLabelStyle | `Typeface` | - | Typeface of the label |
| itemLabelSize | `Int` | 12 | Size of the label |
| itemLabelColor | `Int` | #000 | Label text color |
| itemLabelMarginLeft | `Int` | 0 | Left margin of the label text |
| itemLabelMarginRight | `Int` | 0 | Right margin of the label text |
| itemLabelMarginBottom | `Int` | 0 | Bottom margin of the label text |
| itemLabelMarginTop | `Int` | 0 | Top margin of the label text |
| cardViewCornerRadius | `Float` | 0 | Corner radius of the cardView |
| cardViewElevation | `Float` | 0 | Elevation of the cardView |
| itemTitleStyle | `Typeface` | - | Typeface of the product title |
| itemTitleSize | `Int` | 12 | Size of the title |
| itemTitleColor | `Int` | #000 | Color of the title text |
| itemTitleMarginLeft | `Int` | 0 | Left margin of the title text |
| itemTitleMarginRight | `Int` | 0 | Right margin of the title text |
| itemTitleMarginBottom | `Int` | 0 | Bottom margin of the title text |
| itemTitleMarginTop | `Int` | 0 | Top margin of the title text |
| itemPriceStyle | `Typeface` | - | Typeface of the price |
| itemPriceSize | `Int` | 12 | Size of the price text |
| itemPriceColor | `Int` | #000 | Color of the price text |
| itemPriceMarginLeft | `Int` | 0 | Left margin of the price text |
| itemPriceMarginRight | `Int` | 0 | Right margin of the price text |
| itemPriceMarginTop | `Int` | 0 | Top margin of the price text |
| itemPriceMarginBottom | `Int` | 0 | Bottom margin of the price text |
| itemSalePriceStyle | `Typeface` | - | Typeface of the sale price |
| itemSalePriceSize | `Int` | 12 | Size of the sale price |
| itemSalePriceColor | `Int` | #000 | Color of the sale price text |
| itemSalePriceGravity | `Int` | Gravity.LEFT | Gravity of the sale price text |
| itemSalePriceMarginLeft | `Int` | 0 | Left margin of the sale price text |
| itemSalePriceMarginRight | `Int` | 0 | Right margin of the sale price text |
| itemSalePriceMarginTop | `Int` | 0 | Top margin of the sale price text |
| itemSalePriceMarginBottom | `Int` | 0 | Bottom margin of the sale price text |
| itemSalePriceOrientation | `Int` | LinearLayout.HORIZONTAL | Orientation of the sale price text |
| isItemSalePriceVisible | `boolean` | false | Flag determining whether to show the sale price or not |
| itemDiscountPercentageLabelStyle | `Typeface` | - | Typeface of discount percentage label |
| itemDiscountPercentageLabelColor | `Int` | #000 | Color of discount percentage label |
| itemDiscountPercentageLabelSize | `Int` | 12 | Size of the discount percentage label text |
| itemDiscountPercentageLabelMarginLeft | `Int` | 0 | Left margin of the discount percentage label text |
| itemDiscountPercentageLabelMarginRight | `Int` | 0 | Right margin of the discount percentage label text |
| itemDiscountPercentageLabelMarginTop | `Int` | 0 | Top margin of the discount percentage label text |
| itemDiscountPercentageLabelMarginBottom | `Int` | 0 | Bottom margin of the discount percentage label text |
| isItemDiscountPercentageLabelVisible | `boolean` | false | Flag determining whether to show the discount percentage label or not |
| itemActionButton | `ImageButtonCustomAction` | - | Object which stores all information about the ActionButton |
| itemBadge | `ContentWidgetBadge` | - | Object which stores all information about the Badge |
| imageButtonCustomActionGravity | `Int` | Gravity.TOP | Gravity of the actionButton |
- You can combine the `Gravity.*` parameters. For example, to align an item to top and right, use:
```Gravity.TOP | Gravity.RIGHT```
- All text elements are centered horizontally.
ItemTitleMargins, ItemPriceMargins, ItemLabelMargins, ItemSalePriceMargins, and ItemDiscountLabelMargins can be set using setters, as shown below.
```java
public void setItemTitleMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
```
```kotlin
fun setItemTitleMargins(marginLeft:Int, marginRight:Int, marginTop:Int, marginBottom:Int)
```
## Interaction with the widget
### Public interface
---
`load()` - Starts fetching data and creates a view structure of the widget.
`getView()` - Gets the root view of the whole widget view structure.
`onContentWidgetListener` is used to inform developers about the state of a widget. Read more below.
### Listener
---
- `onLoading(ContentWidget contentWidget, boolean isLoading)` - Called when the widget loading state changes.
- `onLoad(ContentWidget contentWidget)` - Called after the widget is loaded.
- `onLoadingError(ContentWidget contentWidget, ApiError apiError)` - Called when an error occurs while loading.
- `onSizeChange(ContentWidget contentWidget, ViewGroup.LayoutParams size)` - Called when the widget size changes.
- `onClickActionReceive(ContentWidget contentWidget, BaseModel model)` - Called when the customer clicks a widget item.
## Image button custom action
`ImageButtonCustomAction` is used to add `imageButton` to your widget. You can add a `singleStateButton` or a `selectableButton`.
### Parameters
The following table contains the parameters that can be configured in `ImageButtonCustomAction`.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| predefinedAction | `PredefinedActionType` | null | PredefinedAction determines which event is sent on click |
| marginLeft | `Int` | 0 | Left margin of the image button |
| marginRight | `Int` | 0 | Right margin of the image button |
| marginTop | `Int` | - | Top margin of the image button |
| marginBottom | `Int` | 0 | Bottom margin of the image button |
ImageButtonCustomAction margins can be set using setters, as shown below.
```java
public void setImageButtonCustomActionMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
```
```kotlin
fun setImageButtonCustomActionMargins(marginLeft:Int, marginRight:Int, marginTop:Int, marginBottom:Int)
```
The following table contains the parameters that can be configured in `ContentWidgetBadge`.
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| textStyle | `Typeface` | - | Typeface of the text badge |
| textSize | `Int` | 12 | Size of the badge text |
| rule | `Int` | RelativeLayout.ALIGN_LEFT | Rule deremining position of a badge. Can be ALIGN_LEFT or ALIGN_RIGHT |
| paddingLeft | `Int` | 0 | Left padding of the badge text |
| paddingRight | `Int` | 0 | Right padding of the badge text |
| paddingTop | `Int` | 0 | Top padding of the badge text |
| paddingBottom | `Int` | 0 | Bottom padding of the badge text |
| marginLeft | `Int` | 0 | Left margin of the badge |
| marginRight | `Int` | 0 | Right margin of the badge |
| marginTop | `Int` | - | Top margin of the badge |
| marginBottom | `Int` | 0 | Bottom margin of the badge |
ContentWidgetBadge margins and paddings can be set using setters, as shown below.
```java
public void setMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
```
```kotlin
fun setMargins(marginLeft:Int, marginRight:Int, marginTop:Int, marginBottom:Int)
```
```java
public void setPaddings(int paddingLeft, int paddingRight, int paddingTop, int paddingBottom)
```
```kotlin
fun setPaddings(paddingLeft:Int, paddingRight:Int, paddingTop:Int, paddingBottom:Int)
```
### setStateDrawables
This method is responsible for passing icons to the image button.
**Method name:** imageButtonCustomAction.setStateDrawables(dislikeIcon, likeIcon)
#### Declaration
```java
public void setStateDrawables(@NonNull Drawable defaultStateDrawable, @Nullable Drawable selectedStateDrawable)
```
```kotlin
fun setStateDrawables(@NonNull defaultStateDrawable:Drawable, @Nullable selectedStateDrawable:Drawable)
```
#### Parameters
| Parameter | Type | Mandatory | Default | Description |
| --- | --- | --- | --- | --- |
| defaultStateDrawable | `Drawable` | yes | --- | Icon that appears in default and false state |
| selectedStateDrawable | `Drawable` | no | --- | Icon that appears in the selected state |
#### Return Value
Void type
#### Example
```Kotlin
val likeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart)
val unlikeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart_outline)
favouriteIcon.setStateDrawables(unlikeHeart, likeHeart)
```
If you want a `singleStateButton`, pass `null` instead of `selectedStateDrawable`.
### Public interface
Set a listener by using `setOnItemActionListener`.
`OnActionItemStateListener` is used to inform developers about the state of an ImageButton.
### Listener
- `onReceiveClickAction(BaseModel model, boolean isSelected, ImageButton imageButton)` - called when the customer clicks the image button in the widget.
- `onStateCheck(BaseModel model)` - called before showing the view, when `selectableImageButton` needs information about the button state.
### Example
The example shows how to implement the "like" button.
```kotlin
val favouriteIcon = ImageButtonCustomAction()
val likeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart)
val unlikeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart_outline)
favouriteIcon.setStateDrawables(unlikeHeart!!, likeHeart)
favouriteIcon.setImageButtonCustomActionMargins(0, 0, 0, 0)
favouriteIcon.predefinedAction = PredefinedActionType.SEND_LIKE_EVENT
favouriteIcon.setOnItemActionListener(object : OnActionItemStateListener {
override fun onReceiveClickAction(model: BaseModel, isSelected: Boolean, imageButton: ImageButton) {
val recommendation = model as Recommendation
ViewUtils.pulse(imageButton)
}
override fun onStateCheck(model: BaseModel): Boolean {
return false
}
})
itemLayoutDetails.setItemAction(favouriteIcon)
```
## Sample implementations
### Horizontal slider
Slider layout with a fixed height.
```java
public void loadWidget() {
String productId = "10214";
String slug = "similar";
ContentWidgetOptions options = new ContentWidgetRecommendationsOptions(this, slug, new OnRecommendationModelMapper() {
@Override
public ContentWidgetRecommendationDataModel onRecommendationMapping(Recommendation recommendation) {
HashMap data = recommendation.getFeed();
String imageLink = (String) data.get("imageLink");
String productName = (String) data.get("title");
String price = null;
String salePrice = null;
try {
JSONObject json = new JSONObject(data.get("price").toString());
price = json.getString("value");
if (data.containsKey("salePrice")) {
JSONObject jsonSalePrice = new JSONObject(data.get("salePrice").toString());
salePrice = jsonSalePrice.getString("value");
}
} catch (JSONException e) {
e.printStackTrace();
}
ContentWidgetBadgeDataModel badgeDataModel = new ContentWidgetBadgeDataModel("Example badge", Color.BLACK, Color.RED);
ContentWidgetRecommendationDataModel dataModel = new ContentWidgetRecommendationDataModel(productName, imageLink, price, salePrice, "PLN");
dataModel.setBadgeDataModel(badgeDataModel);
dataModel.setLabel("Black Week");
return dataModel;
}});
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
ContentWidgetBasicProductItemLayout itemLayoutDetails = new ContentWidgetBasicProductItemLayout();
ContentWidgetHorizontalSliderLayout layout = new ContentWidgetHorizontalSliderLayout();
//CardView parameters
if (!cardViewWidth.getEditText().getText().toString().matches("") && !cardViewHeight.getEditText().getText().toString().matches(""))
layout.setCardViewSize(Integer.parseInt(cardViewWidth.getEditText().getText().toString()), Integer.parseInt(cardViewHeight.getEditText().getText().toString()));
if (!cardViewElevation.getEditText().getText().toString().matches(""))
itemLayoutDetails.cardViewElevation = Integer.parseInt(cardViewElevation.getEditText().getText().toString());
if (!cornerRadius.getEditText().getText().toString().matches(""))
itemLayoutDetails.cardViewCornerRadius = Integer.parseInt(cornerRadius.getEditText().getText().toString());
if (!horizontalSpacing.getEditText().getText().toString().matches(""))
layout.cardViewHorizontalSpacing = Integer.parseInt(horizontalSpacing.getEditText().getText().toString());
layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent);
//Image size as ratio to cardview size
if (!imageHeightRatio.getEditText().getText().toString().matches(""))
itemLayoutDetails.imageHeightToCardHeightRatio = Float.parseFloat(imageHeightRatio.getEditText().getText().toString());
if (!imageWidthRatio.getEditText().getText().toString().matches(""))
itemLayoutDetails.imageWidthToCardWidthRatio = Float.parseFloat(imageWidthRatio.getEditText().getText().toString());
itemLayoutDetails.imageScaleType = ImageView.ScaleType.CENTER_CROP;
itemLayoutDetails.imageMargin = 0; //have to be set when you set cardViewElevation
//TextView product label
itemLayoutDetails.itemLabelSize = 12;
itemLayoutDetails.itemLabelColor = Color.GREEN;
itemLayoutDetails.setItemLabelMargins(0,0,2,0);
//TextView product name
itemLayoutDetails.itemTitleStyle = Typeface.create("sans-serif-condensed", Typeface.NORMAL);
itemLayoutDetails.itemTitleSize = 12;
itemLayoutDetails.itemTitleColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal);
itemLayoutDetails.setItemTitleMargins(10, 0, 0, 0);
//TextView Product price
itemLayoutDetails.itemPriceStyle = Typeface.create("sans-serif-light", Typeface.BOLD);
itemLayoutDetails.itemPriceSize = 13;
itemLayoutDetails.itemPriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal);
itemLayoutDetails.setItemPriceMargins(10, 0, 3, 0);
//TextView Product Sale price
itemLayoutDetails.isItemSalePriceVisible = true;
itemLayoutDetails.itemSalePriceStyle = Typeface.create("sans-serif", Typeface.BOLD);
itemLayoutDetails.itemSalePriceSize = 13;
itemLayoutDetails.itemSalePriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.red);
itemLayoutDetails.itemSalePriceOrientation = LinearLayout.HORIZONTAL;
itemLayoutDetails.setItemSalePriceMargins(4, 0, 3, 0);
// CrossedOut Price color
itemLayoutDetails.itemRegularPriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.com_facebook_blue);
itemLayoutDetails.priceDecimalSeparator = ',';
itemLayoutDetails.priceGroupSeparator = ' ';
// DiscountLabel
itemLayoutDetails.itemDiscountPercentageLabelSize = 13;
itemLayoutDetails.isItemDiscountPercentageLabelVisible = true;
itemLayoutDetails.itemDiscountPercentageLabelColor = Color.BLUE;
itemLayoutDetails.itemDiscountPercentageLabelStyle = Typeface.create("sans-serif", Typeface.BOLD);
itemLayoutDetails.setItemDiscountLabelMargins(4, 0, 3, 0);
// Badge
ContentWidgetBadge badge = new ContentWidgetBadge();
badge.textSize = 12;
badge.rule = RelativeLayout.ALIGN_LEFT; // left or right
badge.setMargins(0,0,0,20);
badge.setPaddings(10, 10, 0, 0);
//ImageButton
ImageButtonCustomAction favouriteIcon = new ImageButtonCustomAction();
Drawable likeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart);
Drawable unlikeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart_outline);
favouriteIcon.setStateDrawables(unlikeHeart, likeHeart);
favouriteIcon.setImageButtonCustomActionMargins(0, 0, 0, 0);
favouriteIcon.predefinedAction = PredefinedActionType.SEND_LIKE_EVENT;
favouriteIcon.setOnItemActionListener(new OnActionItemStateListener() {
@Override
public void onReceiveClickAction(BaseModel model, boolean isSelected, ImageButton imageButton) {
Recommendation recommendationModel = (Recommendation) model;
ViewUtils.pulse(imageButton);
}
@Override
public boolean onStateCheck(BaseModel model) {
return false;
}
});
itemLayoutDetails.setBadge(badge);
itemLayoutDetails.setItemAction(favouriteIcon);
ContentWidgetAppearance contentWidgetAppearance = new ContentWidgetAppearance(layout, itemLayoutDetails);
ContentWidget widget = new ContentWidget(options, contentWidgetAppearance);
widget.setOnContentWidgetListener(new OnContentWidgetListener() {
@Override
public void onLoading(ContentWidget contentWidget, boolean isLoading) {
}
@Override
public void onLoadingError(ContentWidget contentWidget, ApiError apiError) {
Toast.makeText(getApplicationContext(), apiError.toString(),Toast.LENGTH_LONG).show();
}
@Override
public void onLoad(ContentWidget contentWidget) {
insertPoint.removeAllViews();
View view = widget.getView(); // our widget
insertPoint.addView(view); // your view which will receive widget
}
@Override
public void onClickActionReceive(ContentWidget contentWidget, BaseModel model) {
Recommendation recommendationModel = (Recommendation) model;
String itemId = recommendationModel.getItemId();
startActivity(WidgetRecommendedProductDetailsActivity.createIntent(getApplicationContext(), itemId));
}
@Override
public void onSizeChange(ContentWidget contentWidget, ViewGroup.LayoutParams size) {
ViewGroup.LayoutParams params = insertPoint.getLayoutParams();
params.height = size.height;
insertPoint.setLayoutParams(params);
}
});
}
```
```kotlin
fun loadWidget() {
val productId = "10214"
val slug = "similar"
var options: ContentWidgetOptions = ContentWidgetRecommendationsOptions(this, slug, object : OnRecommendationModelMapper() {
fun onRecommendationMapping(recommendation: Recommendation): ContentWidgetRecommendationDataModel? {
// here you should implement your mapping to SyneriseModel
val data = recommendation.getFeed()
val imageLink = data["imageLink"] as String?
val productName = data["title"] as String?
var price: String? = null
var salePrice: String? = null
try {
val json = JSONObject(data["price"].toString())
price = json.getString("value")
if (data.containsKey("salePrice")) {
val jsonSalePrice = JSONObject(data["salePrice"].toString())
salePrice = jsonSalePrice.getString("value")
}
} catch (e: JSONException) {
e.printStackTrace()
}
val badgeDataModel = ContentWidgetBadgeDataModel("Example badge", Color.BLACK, Color.RED)
val dataModel = ContentWidgetRecommendationDataModel(productName, imageLink, price, salePrice, "PLN")
dataModel.setBadgeDataModel(badgeDataModel);
dataModel.setLabel("Black Week");
return dataModel
}
})
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
val itemLayoutDetails = ContentWidgetItemLayout()
val layout = ContentWidgetHorizontalSliderLayout()
layout.setCardViewSize(250, 350)
itemLayoutDetails.cardViewElevation = 5
itemLayoutDetails.cardViewCornerRadius = 10
layout.cardViewHorizontalSpacing = 20
layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent)
//Image size as ratio to cardview size
itemLayoutDetails.imageHeightToCardHeightRatio = 0.6
itemLayoutDetails.imageWidthToCardWidthRatio = 1
itemLayoutDetails.imageMargin = 5 //have to be set when you set cardViewElevation
itemLayoutDetails.imageScaleType = ImageView.ScaleType.CENTER_CROP;
//TextView product label
itemLayoutDetails.itemLabelSize = 12;
itemLayoutDetails.itemLabelColor = Color.GREEN;
itemLayoutDetails.setItemLabelMargins(0,0,2,0);
//TextView product name
itemLayoutDetails.itemTitleStyle = Typeface.create("sans-serif-condensed", Typeface.NORMAL)
itemLayoutDetails.itemTitleSize = 12
itemLayoutDetails.itemTitleColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal)
itemLayoutDetails.itemTitleGravity = Gravity.LEFT
itemLayoutDetails.setItemTitleMargins(10, 0, 0, 0)
//TextView Product price
itemLayoutDetails.itemPriceStyle = Typeface.create("sans-serif-light", Typeface.BOLD)
itemLayoutDetails.itemPriceSize = 12
itemLayoutDetails.itemPriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal)
itemLayoutDetails.itemPriceGravity = Gravity.LEFT
itemLayoutDetails.setItemPriceMargins(10, 0, 3, 0)
//TextView Product Sale Price
itemLayoutDetails.itemSalePriceStyle = Typeface.create("sans-serif", Typeface.BOLD)
itemLayoutDetails.itemSalePriceSize = 13
itemLayoutDetails.itemSalePriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.red)
itemLayoutDetails.itemSalePriceOrientation = LinearLayout.HORIZONTAL
itemLayoutDetails.isItemSalePriceVisible = true
itemLayoutDetails.setItemSalePriceMargins(5, 0, 3, 0)
// CrossedOut Price color
itemLayoutDetails.itemRegularPriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.com_facebook_blue);
itemLayoutDetails.priceDecimalSeparator = ',';
itemLayoutDetails.priceGroupSeparator = ' ';
// DiscountLabel
itemLayoutDetails.itemDiscountPercentageLabelSize = 13;
itemLayoutDetails.isItemDiscountPercentageLabelVisible = true;
itemLayoutDetails.itemDiscountPercentageLabelColor = Color.BLUE;
itemLayoutDetails.itemDiscountPercentageLabelStyle = Typeface.create("sans-serif", Typeface.BOLD);
itemLayoutDetails.setItemDiscountLabelMargins(4, 0, 3, 0);
// Badge
val badge = ContentWidgetBadge();
badge.textSize = 12;
badge.rule = RelativeLayout.ALIGN_LEFT; // left or right
badge.setMargins(0,0,0,20);
badge.setPaddings(10, 10, 0, 0);
//ImageButton
val favouriteIcon = ImageButtonCustomAction()
val likeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart)
val unlikeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart_outline)
favouriteIcon.setStateDrawables(unlikeHeart, likeHeart)
favouriteIcon.setImageButtonCustomActionMargins(0, 0, 0, 0)
favouriteIcon.predefinedAction = PredefinedActionType.SEND_LIKE_EVENT
favouriteIcon.setOnItemActionListener(object:OnActionItemStateListener() {
fun onReceiveClickAction(model:BaseModel, isSelected:Boolean, imageButton:ImageButton) {
val recommendation = model as Recommendation
ViewUtils.pulse(imageButton)
}
fun onStateCheck(model:BaseModel):Boolean {
// Here you should set buttonState based on a product and a customer.
return false
}
})
itemLayoutDetails.setBadge(badge);
itemLayoutDetails.setItemAction(favouriteIcon)
val contentWidgetAppearance = ContentWidgetAppearance(layout, itemLayoutDetails)
val widget = ContentWidget(options, contentWidgetAppearance)
widget.setOnContentWidgetListener(object:OnContentWidgetListener() {
fun onLoading(contentWidget:ContentWidget, isLoading:Boolean) {
}
fun onLoadingError(contentWidget:ContentWidget, apiError:ApiError) {
Toast.makeText(getApplicationContext(), apiError.toString(), Toast.LENGTH_LONG).show()
}
fun onLoad(contentWidget:ContentWidget) {
insertPoint.removeAllViews()
val view = widget.getView() // our widget
insertPoint.addView(view) // your view which will receive widget
}
fun onClickActionReceive(contentWidget:ContentWidget, model:BaseModel) {
val recommendation = model as Recommendation
startActivity(WidgetRecommendedProductDetailsActivity.createIntent(getApplicationContext(), recommendation.getProductRetailerPartNo()))
}
fun onSizeChange(contentWidget:ContentWidget, size:ViewGroup.LayoutParams) {
val params = insertPoint.getLayoutParams()
params.height = size.height
insertPoint.setLayoutParams(params)
}
})
}
```
### Grid view
---
If you want to avoid double scroll view, set the height as shown in the `widgetSizeDidChange` callback.
```java
private void loadFullScreenWidget() {
String slug = "similar";
String productId = "10214";
ContentWidgetOptions options = new ContentWidgetRecommendationsOptions(this, slug, new OnRecommendationModelMapper() {
@Override
public ContentWidgetRecommendationDataModel onRecommendationMapping(Recommendation recommendation) {
HashMap data = recommendation.getFeed();
String imageLink = (String) data.get("imageLink");
String productName = (String) data.get("title");
String price = null;
String salePrice = null;
try {
JSONObject json = new JSONObject(data.get("price").toString());
price = json.getString("value");
if (data.containsKey("salePrice")) {
JSONObject jsonSalePrice = new JSONObject(data.get("salePrice").toString());
salePrice = jsonSalePrice.getString("value");
}
} catch (JSONException e) {
e.printStackTrace();
}
return new ContentWidgetRecommendationDataModel(productName, imageLink, price, salePrice, null);
}});
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
ContentWidgetItemLayout itemLayoutDetails = new ContentWidgetItemLayout();
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
float screenWidthDp = displayMetrics.widthPixels;
ContentWidgetGridLayout layout = new ContentWidgetGridLayout(screenWidthDp);
//CardView parameters
layout.setCardViewSize(250, 350);
itemLayoutDetails.cardViewElevation = 5;
itemLayoutDetails.cardViewCornerRadius = 5;
layout.cardViewHorizontalSpacing = 10;
layout.cardViewVerticalSpacing = 10;
layout.includeEdgeSpacing = false;
layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent);
//Image size as ratio to cardview size
itemLayoutDetails.imageHeightToCardHeightRatio = 0.7;
itemLayoutDetails.imageWidthToCardWidthRatio = 1;
itemLayoutDetails.imageMargin = 5; //have to be set when you set cardViewElevation
//TextView product name
itemLayoutDetails.itemTitleStyle = Typeface.create("sans-serif-condensed", Typeface.NORMAL);
itemLayoutDetails.itemTitleSize = 12;
itemLayoutDetails.itemTitleColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal);
itemLayoutDetails.itemTitleGravity = Gravity.LEFT;
itemLayoutDetails.setItemTitleMargins(10, 0, 10, 0);
//TextView Product price
itemLayoutDetails.itemPriceStyle = Typeface.create("sans-serif-light", Typeface.BOLD);
itemLayoutDetails.itemPriceSize = 12;
itemLayoutDetails.itemPriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal);
itemLayoutDetails.itemPriceGravity = Gravity.LEFT;
itemLayoutDetails.setItemPriceMargins(10, 0, 10, 0);
//TextView Product Sale Price
itemLayoutDetails.itemSalePriceStyle = Typeface.create("sans-serif", Typeface.BOLD)
itemLayoutDetails.itemSalePriceSize = 13
itemLayoutDetails.itemSalePriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.red)
itemLayoutDetails.itemSalePriceOrientation = LinearLayout.HORIZONTAL
itemLayoutDetails.isItemSalePriceVisible = true
itemLayoutDetails.setItemSalePriceMargins(5, 0, 3, 0)
//ImageButton
val favouriteIcon = ImageButtonCustomAction()
val likeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart)
val unlikeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart_outline)
favouriteIcon.setStateDrawables(unlikeHeart, likeHeart)
favouriteIcon.setImageButtonCustomActionMargins(0, 0, 0, 0)
favouriteIcon.predefinedAction = PredefinedActionType.SEND_LIKE_EVENT
favouriteIcon.setOnItemActionListener(object:OnActionItemStateListener() {
fun onReceiveClickAction(model:BaseModel, isSelected:Boolean, imageButton:ImageButton) {
val recommendation = model as Recommendation
ViewUtils.pulse(imageButton)
}
fun onStateCheck(model:BaseModel):Boolean {
// Here you should set buttonState based on a product and a customer.
return false
}
})
itemLayoutDetails.setItemAction(favouriteIcon)
ContentWidgetAppearance contentWidgetAppearance = new ContentWidgetAppearance(layout, itemLayoutDetails);
ContentWidget widget = new ContentWidget(options, contentWidgetAppearance);
widget.setOnContentWidgetListener(new OnContentWidgetListener() {
@Override
public void onLoading(ContentWidget contentWidget, boolean isLoading) {
}
@Override
public void onLoadingError(ContentWidget contentWidget, ApiError apiError) {
Toast.makeText(getApplicationContext(), apiError.toString(),Toast.LENGTH_LONG).show();
}
@Override
public void onLoad(ContentWidget contentWidget) {
insertPoint.removeAllViews();
View view = widget.getView();
insertPoint.addView(view);
}
@Override
public void onClickActionReceive(ContentWidget contentWidget, BaseModel model) {
Recommendation recommendation = (Recommendation)model;
startActivity(WidgetRecommendedProductDetailsActivity.createIntent(getApplicationContext(), recommendation.getProductRetailerPartNo()));
}
@Override
public void onSizeChange(ContentWidget contentWidget, ViewGroup.LayoutParams size) {
ViewGroup.LayoutParams params = insertPoint.getLayoutParams();
params.height = size.height;
insertPoint.setLayoutParams(params);
}
});
}
```
```kotlin
private fun loadFullScreenWidget() {
val slug = "similar"
val productId = "10214"
var options: ContentWidgetOptions = ContentWidgetRecommendationsOptions(this, slug, object : OnRecommendationModelMapper() {
fun onRecommendationMapping(recommendation: Recommendation): ContentWidgetRecommendationDataModel? {
// here you should implement your mapping to SyneriseModel
val data = recommendation.getFeed()
val imageLink = data["imageLink"] as String?
val productName = data["title"] as String?
var price: String? = null
var salePrice: String? = null
try {
val json = JSONObject(data["price"].toString())
price = json.getString("value")
if (data.containsKey("salePrice")) {
val jsonSalePrice = JSONObject(data["salePrice"].toString())
salePrice = jsonSalePrice.getString("value")
}
} catch (e: JSONException) {
e.printStackTrace()
}
return ContentWidgetRecommendationDataModel(productName, imageLink, price, salePrice, null)
}
})
options.attributes.put(ContentWidgetOptions.ContentWidgetOptionsAttributeKeyProductId, productId);
val itemLayoutDetails = ContentWidgetItemLayout()
val displayMetrics = DisplayMetrics()
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics)
val screenWidthDp = displayMetrics.widthPixels
val layout = ContentWidgetGridLayout(screenWidthDp)
//CardView parameters
layout.setCardViewSize(250, 350)
itemLayoutDetails.cardViewElevation = 5
itemLayoutDetails.cardViewCornerRadius = 5
layout.cardViewHorizontalSpacing = 10
layout.cardViewVerticalSpacing = 10
layout.includeEdgeSpacing = false
layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent)
//Image size as ratio to cardview size
itemLayoutDetails.imageHeightToCardHeightRatio = 0.7
itemLayoutDetails.imageWidthToCardWidthRatio = 1
itemLayoutDetails.imageMargin = 5 //have to be set when you set cardViewElevation
//TextView product name
itemLayoutDetails.itemTitleStyle = Typeface.create("sans-serif-condensed", Typeface.NORMAL)
itemLayoutDetails.itemTitleSize = 12
itemLayoutDetails.itemTitleColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal)
itemLayoutDetails.itemTitleGravity = Gravity.LEFT
itemLayoutDetails.setItemTitleMargins(10, 0, 10, 0)
//TextView Product price
itemLayoutDetails.itemPriceStyle = Typeface.create("sans-serif-light", Typeface.BOLD)
itemLayoutDetails.itemPriceSize = 12
itemLayoutDetails.itemPriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.charcoal)
itemLayoutDetails.itemPriceGravity = Gravity.LEFT
itemLayoutDetails.setItemPriceMargins(10, 0, 10, 0)
//TextView Product Sale Price
itemLayoutDetails.itemSalePriceStyle = Typeface.create("sans-serif", Typeface.BOLD)
itemLayoutDetails.itemSalePriceSize = 13
itemLayoutDetails.itemSalePriceColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.red)
itemLayoutDetails.itemSalePriceOrientation = LinearLayout.HORIZONTAL
itemLayoutDetails.isItemSalePriceVisible = true
itemLayoutDetails.setItemSalePriceMargins(5, 0, 3, 0)
//ImageButton
val favouriteIcon = ImageButtonCustomAction()
val likeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart)
val unlikeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart_outline)
favouriteIcon.setStateDrawables(unlikeHeart, likeHeart)
favouriteIcon.setImageButtonCustomActionMargins(0, 0, 0, 0)
favouriteIcon.predefinedAction = PredefinedActionType.SEND_LIKE_EVENT
favouriteIcon.setOnItemActionListener(object:OnActionItemStateListener() {
fun onReceiveClickAction(model:BaseModel, isSelected:Boolean, imageButton:ImageButton) {
val recommendation = model as Recommendation
ViewUtils.pulse(imageButton)
}
fun onStateCheck(model:BaseModel):Boolean {
// Here you should set buttonState based on a product and a customer.
return false
}
})
itemLayoutDetails.setItemAction(favouriteIcon)
val contentWidgetAppearance = ContentWidgetAppearance(layout, itemLayoutDetails)
val widget = ContentWidget(options, contentWidgetAppearance)
widget.setOnContentWidgetListener(object:OnContentWidgetListener() {
fun onLoading(contentWidget:ContentWidget, isLoading:Boolean) {
}
fun onLoadingError(contentWidget:ContentWidget, apiError:ApiError) {
Toast.makeText(getApplicationContext(), apiError.toString(), Toast.LENGTH_LONG).show()
}
fun onLoad(contentWidget:ContentWidget) {
insertPoint.removeAllViews()
val view = widget.getView()
insertPoint.addView(view)
}
fun onClickActionReceive(contentWidget:ContentWidget, model:BaseModel) {
val recommendation = model as Recommendation
startActivity(WidgetRecommendedProductDetailsActivity.createIntent(getApplicationContext(), recommendation.getProductRetailerPartNo()))
}
fun onSizeChange(contentWidget:ContentWidget, size:ViewGroup.LayoutParams) {
val params = insertPoint.getLayoutParams()
params.height = size.height
insertPoint.setLayoutParams(params)
}
})
}
```
### More information
---
You can find more information under the following links:
- [Sample App on GitHub](https://github.com/Synerise/android-sdk)
- [Horizontal slider implementation in the Sample App on GitHub](https://github.com/Synerise/android-sdk/blob/master/sample/src/main/java/com/synerise/sdk/sample/ui/dev/content/WidgetHorizontalSliderActivity.java)
- [Grid implementation in the Sample App on GitHub](https://github.com/Synerise/android-sdk/blob/master/sample/src/main/java/com/synerise/sdk/sample/ui/dev/content/WidgetGridViewActivity.java)
```
# Profile management
**Upcoming breaking change (effective July 6, 2026):** Synerise is introducing changes to how user identifiers and UUIDs are handled. These changes may affect profiles with accented or diacritical characters in identifiers, profiles with leading or trailing whitespace in identifiers, and profiles with duplicate UUIDs. For details and recommended actions, see [Upcoming changes to handling identifiers](/docs/settings/configuration/identifier-standardization).
When the customer is authenticated with a JWT token in your application, You can retrieve or update customer details by using the SDK methods. These methods can be used only by recognized profiles, except [updating a customer account's basic information](#update-a-customer-accounts-basic-information), which can be used for anonymous profile too.
You must synchronize your data with Synerise backend after deleting an account on your side.
## Profile management methods
### Get a customer account details
You can use this method to retrieve all information about a customer from Synerise. You can then present that information in the app.
| OS | Method |
|--------------|--------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.getAccount()](/developers/mobile-sdk/method-reference/android/client-account#get-customer-account-information) |
| iOS | [Client.getAccount(success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#get-customer-account-information) |
| React Native | [Synerise.Client.getAccount(onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#get-customer-account-information) |
| Flutter | [Synerise.client.getAccount()](/developers/mobile-sdk/method-reference/flutter/client-account#get-customer-account-information) |
### Update a customer account's basic information
You can use this method to let customers update their own basic information, except for updating identifiers: `uuid`, `customId`, `email`.
| OS | Method |
|--------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.updateAccountBasicInformation(accountInformation)](/developers/mobile-sdk/method-reference/android/client-account#update-customer-account-basic-information) |
| iOS | [Client.updateAccountBasicInformation(context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#update-customer-account-basic-information) |
| React Native | [Synerise.Client.updateAccountBasicInformation(context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#update-customer-account-basic-information) |
| Flutter | [Synerise.client.updateAccountBasicInformation(context)](/developers/mobile-sdk/method-reference/flutter/client-account#update-customer-account-basic-information) |
This method can be used by recognized and anonymous profiles.
### Update a customer account's details
You can use this method to let customers update their own information, including updating identifiers: `uuid`, `customId`, `email`.
| OS | Method |
|--------------|--------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.updateAccount(accountInformation)](/developers/mobile-sdk/method-reference/android/client-account#update-customer-account-information) |
| iOS | [Client.updateAccount(context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#update-customer-account-information) |
| React Native | [Synerise.Client.updateAccount(context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#update-customer-account-information) |
| Flutter | [Synerise.client.updateAccount(context)](/developers/mobile-sdk/method-reference/flutter/client-account#update-customer-account-information) |
This method can be used only by recognized profiles.
### Change a customer's password
Separately from customer information updates, a customer may want to change their password. The default password policy is:
- Minimum 6 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one digit
- At least one non-alphanumeric character
Passwords are PBKDF2-encrypted.
You can define the password policy in the Synerise platform (`app.synerise.com`). You can find more information about it [here](/docs/settings/tool/iam-for-apps/synerise#password-policy).
This method allows a customer to change their password, but they must provide their current password first.
| OS | Method |
|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.changePassword(oldPassword, password)](/developers/mobile-sdk/method-reference/android/client-account#change-customers-account-password) |
| iOS | [Client.changePassword(password:oldPassword:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#change-customers-account-password) |
| React Native | [Synerise.Client.changePassword()](/developers/mobile-sdk/method-reference/react-native/client-account#change-customers-account-password) |
| Flutter | [Synerise.client.changePassword(oldPassword, password)](/developers/mobile-sdk/method-reference/flutter/client-account#change-customers-account-password) |
### Request and confirm email change
These methods allow customers request and confirm the change of their email address.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | - [Client.requestEmailChange(email, password, externalToken, authId)](/developers/mobile-sdk/method-reference/android/client-account#request-email-change-for-customer-account) - [Client.confirmEmailChange(token, newsletterAgreement)](/developers/mobile-sdk/method-reference/android/client-account#confirm-email-change-for-customer-account) |
| iOS | - [Client.requestEmailChange(email:password:externalToken:authID:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#request-email-change-for-customer-account) - [Client.confirmEmailChange(token:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#confirm-email-change-for-customer-account) |
| React Native | - [Synerise.Client.requestEmailChange(email, password, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#request-email-change-for-customer-account) - [Synerise.Client.confirmEmailChange(token, newsletterAgreement, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#confirm-email-change-for-customer-account) |
| Flutter | n/a |
### Request and confirm phone number change
These methods allow customers to request and confirm the change of their phone number.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | - [requestPhoneUpdate(phone:success:failure:)](/developers/mobile-sdk/method-reference/android/client-account#request-phone-update-on-customer-account) - [Client.confirmPhoneUpdate(phone, confirmationCode, smsAgreement)](/developers/mobile-sdk/method-reference/android/client-account#confirm-phone-update-on-customer-account) |
| iOS | - [Client.requestPhoneUpdate(phone:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#request-phone-update-on-customer-account) - [Client.confirmPhoneUpdate(phone:confirmationCode:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#confirm-phone-update-on-customer-account) |
| React Native | - [Synerise.Client.requestPhoneUpdate(phone, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#request-phone-update-on-customer-account) - [Synerise.Client.confirmPhoneUpdate(phone, confirmationCode, smsAgreement, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#confirm-phone-update-on-customer-account) |
| Flutter | n/a |
### Remove a customer
To allow a customer to remove their account, implement the following method:
| OS | Method |
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.deleteAccount(clientAuthFactor, clientIdentityProvider, authId)](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account-by-identity-provider) |
| iOS | [Client.deleteAccount(clientAuthFactor:clientIdentityProvider:authID:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-account#delete-customer-account-by-identity-provider) |
| React Native | [Synerise.Client.deleteAccountByIdentityProvider(clientAuthFactor, clientIdentityProvider, authID, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-account#delete-customer-account-by-identity-provider) |
| Flutter | [Synerise.client.deleteAccount(clientAuthFactor, identityProvider, authId)](/developers/mobile-sdk/method-reference/flutter/client-account#delete-customer-account) |
# Action handling
## Types of actions in campaigns
---
Campaigns can have three action types:
- **OPEN APP** - This option opens your app after clicking the notification. If the app is already in the foreground, clicking the notification doesn't have any effect.
- **OPEN URL** - This option opens a URL. Depending on your implementation, the link is opened in the browser by default or in your custom implementation, such as a webview in your application.
- **DEEP LINKING** - This option lets you transfer users to a specific view in your app by system methods or by your custom implementation.
## Handling actions from campaigns {id=handling-actions-from-campaigns}
---
You can handle actions from campaigns by using dedicated listeners and delegates:
- [OnInjectorListener](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-injector-listener) for [handling actions in Android](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-android)
- [SyneriseDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate) for [handling actions in iOS](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-ios)
- [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-listener) for [handling actions in React Native](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-react-native)
- [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-listener) for [handling actions in Flutter](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-flutter)
If you don't implement listener/delegate for handling actions in your customized way:
- The SDK runs the default browser with the requested URL address for **OPEN URL**.
- The SDK tries to handle the deep link in the host app by a system method for **DEEP LINKING**.
On iOS, deep links require special attention. The default SDK behaviour uses the [UIApplication.shared.canOpenURL(_:)](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl) method. That method verifies a whitelist of deep links in `LSApplicationQueriesSchemes` key in the `\*.plist` file. Read more in [Apple documentation](https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/plist/info/LSApplicationQueriesSchemes).
### Android {id=handling-actions-from-campaigns-in-android}
You can handle actions from each type of campaign in your own customized way by using [OnInjectorListener](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-injector-listener) methods.
The [OnInAppListener](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-in-app-listener) monitors when a [JS method is used in an in-app message](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#javascript-methods-in-in-app-messages).
In extended methods for handling **OPEN URL** and **DEEP LINKING**, the following parameters are available:
- URL value from the action of the activity.
- Deep link value from the action of the activity.
- [`SyneriseSource`](/developers/mobile-sdk/class-reference/android/campaigns#synerisesource): enum that defines the kind of activity from the action that was sent.
#### Configuration {id=configuration-for-handling-actions-from-campaigns-in-android}
1. Make your activity available for deep linking by including the following parameters in your AndroidManifest:
For the configuration above, the sample **deep link** parameter is `syne://test?param=value`, where:
- `syne` and `test` are the scheme and host provided in the intent filter.
- `parameter` is the parameter name.
- `value` is the parameter value.
Your action name must be the same as your URI scheme and host.
2. **Optional**: Define an activity to be called after closing the activity that was initiated by deep linking. Provide an additional intent category:
If your deep link doesn't contain the `://` characters after the scheme, it is treated as a regular string key and set to the Intent's action.
This means that you can set an action name (in your AndroidManifest activity's intent filter) to any string and then match it with the provided deep link.
InjectorActionHandler.setOnInjectorListener(new OnInjectorListener() {
@Override
public boolean onOpenUrl(SyneriseSource source, String url) {
//your implementation of OPEN URL action
return false;
}
@Override
public boolean onDeepLink(SyneriseSource source, String deepLink) {
//your implementation of DEEP LINKING action
return false;
}
});
If you don't configure a custom action, the SDK applies the default behavior, as described [earlier](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns).
### iOS {id=handling-actions-from-campaigns-in-ios}
You can handle actions from each type of campaign in your own customized way by using [SyneriseDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate) methods.
The [InjectorInAppMessageDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#injector-in-app-message-delegate) monitors when a [JS method is used in an in-app message](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#javascript-methods-in-in-app-messages).
In extended methods for handling **OPEN URL** and **DEEP LINKING**, the following parameters are available:
- URL value from the action of the activity.
- Deep link value from the action of the activity.
- [`SyneriseSource`](/developers/mobile-sdk/class-reference/ios/campaigns#synerisesource): enum that defines the kind of activity from the action that was sent.
This enum replaces the deprecated [`SyneriseActivity` enum](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivity).
- `SyneriseActivityCompletionHandler`: block/closure that defines whether an activity should be hidden or not and what code should be invoked after.
#### Sample implementation of OPEN URL action {id=handling-open-url-action-in-ios}
This way you can, for example, check the type of activity or use your own webview to show the web page.
#### Sample implementation of DEEP LINKING action {id=handling-deeplink-action-in-ios}
This way you can, for example, check the type of activity and handle your deep link in a custom way.
#### System method to handle deep links
The code below presents a system method sample implementation to handle deep links. See [Apple Developer - UIApplication.open(_:options:completionHandler:)](https://developer.apple.com/documentation/uikit/uiapplication/1648685-open) method for more details.
If you don't configure a custom action, the SDK applies the default behavior, as described [earlier](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns).
### React Native {id=handling-actions-from-campaigns-in-react-native}
You can specify your custom action when a customer interacts with your simple push, banner, walkthrough, or in-app message.
You can handle actions from each type of campaign in your own customized way by using [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-listener) methods.
In listener methods for handling **OPEN URL** and **DEEP LINKING**, the following parameters are available:
- URL value from the action of the activity.
- Deep link value from the action of the activity.
- [`SyneriseSource`](/developers/mobile-sdk/class-reference/react-native/campaigns#synerisesource): enum that defines the kind of activity from the action that was sent.
```JavaScript
Synerise.Injector.setListener({
onOpenUrl: function(url, source) {
//your implementation of OPEN URL action
Linking.openURL(url);
},
onDeepLink: function(deepLink, source) {
//your implementation of DEEP LINKING action
}
//...
//other listener's methods
});
```
If you don't configure a custom action, the SDK applies the default behavior, as described [earlier](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns).
### Flutter {id=handling-actions-from-campaigns-in-flutter}
You can specify your custom action when a customer interacts with your simple push, banner, walkthrough, or in-app message.
You can handle actions from each type of campaign in your own customized way by using [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-listener) methods.
In listener methods for handling **OPEN URL** and **DEEP LINKING**, the following parameters are available:
- URL value from the action of the activity.
- Deep link value from the action of the activity.
- [`SyneriseSource`](/developers/mobile-sdk/class-reference/flutter/campaigns#synerisesource): enum that defines the kind of activity from the action that was sent.
```Dart
Synerise.injector.listener((listener) {
listener.onOpenUrl = (url, source) {
//your implementation of OPEN URL action
};
listener.onDeepLink = (deepLink, source) {
//your implementation of DEEP LINKING action
};
//...
//other listener's methods
});
```
If you don't configure a custom action, the SDK applies the default behavior, as described [earlier](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns).
## Universal linking
---
Universal links help your users follow links to content in your app or to your website. When they open a universal link, their mobile OS checks whether any installed app is registered for that domain. If there is no configured application URL for a given path, the user stays on the website.
In order to send universal links from Synerise, you must use the **OPEN URL** action in your campaign configuration on Synerise UI.
### Android {id=universal-linking-in-android}
In order to implement universal links, you need to configure them in the `AndroidManifest.xml` file in your application.
Add data to your activity in order to connect a URL with a screen.
<activity
android:name=".ui.dev.tracker.TrackerViewActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="synerise.com"
android:pathPrefix="/tracker"
android:scheme="https" />
<!-- note that the leading "/" is required for pathPrefix-->
</intent-filter>
</activity>
### iOS {id=universal-linking-in-ios}
To implement universal links:
1. On your app identifier, enable `Associated Domains`
2. In your Xcode project, enable `Associated Domain` (in capabilities).
3. Configure your website to host the `apple-app-site-association` file.
```Swift
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
let url = userActivity.webpageURL!
print(url.absoluteString)
// handle url and run app action that you want
}
return true
}
```
```Objective-C
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler{
if ([userActivity.activityType isEqualToString: NSUserActivityTypeBrowsingWeb]) {
NSURL *url = userActivity.webpageURL;
NSLog(@"URL: %@", url.absoluteString);
// handle url and run app action that you want
}
return YES;
}
```
For more details, see [Apple Developer - Universal Links for Developers](https://developer.apple.com/ios/universal-links/).
## Handling actions from campaigns (older SDK versions) {id=handling-actions-from-campaigns-in-older-sdk-versions}
---
### Android (version 5.12.0 and lower) {id=legacy-handling-actions-from-campaigns-in-android}
You can handle actions in your own customized way by using:
- [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-injector-listener) methods for simple push.
- [InAppMessageListener](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-in-app-listener) methods for in-app messages.
You cannot handle actions in your own customized way for simple push. It works as default, so **OPEN URL** opens the browser and **DEEP LINKING** opens an activity associated with this deep link.
#### Configuration {id=legacy-configuration-for-handling-actions-from-campaigns-in-android}
1. Make your activity available for deep linking by including the following parameters in your AndroidManifest:
For the configuration above, the sample **deep link** parameter is `syne://test?param=value`, where:
- `syne` and `test` are the scheme and host provided in the intent filter.
- `parameter` is the parameter name.
- `value` is the parameter value.
Your action name must be the same as your URI scheme and host.
2. **Optional**: Define an activity to be called after closing the activity that was initiated by deep linking. Provide an additional intent category:
If your deep link doesn't contain the `://` characters after the scheme, it is treated as a regular string key and set to the Intent's action.
This means that you can set an action name (in your AndroidManifest activity's intent filter) to any string and then match it with the provided deep link.
#### Simple Push {id=legacy-handling-simple-push-actions-in-android}
The SDK handle those actions by default, so **OPEN URL** opens the browser and **DEEP LINKING** opens an activity associated with this deep link.
#### In-app messages {id=legacy-handling-in-app-message-actions-in-android}
The SDK allows you to handle those actions. By default, an **OPEN URL** opens the browser and **DEEP LINKING** opens an activity associated with this deep link.
You can specify your custom action when a customer interacts with your in-app messages.
The callbacks presented below work only with in-app message.
If you want to implement your own behavior, refer to the following code:
```Java
public static OnInAppListener NULL = new OnInAppListener() {
@Override
public void onHandledOpenUrl(InAppMessageData inAppMessageData) {
//your implementation of OPEN URL action
}
@Override
public void onHandledOpenDeepLink(InAppMessageData inAppMessageData) {
//your implementation of DEEP LINKING action
}
};
```
```Kotlin
var inAppCallbacks: OnInAppListener = object : OnInAppListener() {
override fun onHandledOpenUrl(inAppMessageData: InAppMessageData) {
//your implementation of OPEN URL action
}
override fun onHandledOpenDeepLink(inAppMessageData: InAppMessageData) {
//your implementation of DEEP LINKING action
}
}
```
- `onHandledOpenUrl(InAppMessageData)` - callback is fired when a customer interacts with the **OPEN URL** action. Returns **true** if the activity is closed after the action is executed, **false** otherwise.
- `onHandledOpenDeepLink(InAppMessageData)` - callback is fired when a customer interacts with the **DEEP LINKING** action. Returns **true** if the activity is closed after the action is executed, **false** otherwise.
### React Native (version 0.17.0 and lower) {id=legacy-handling-actions-from-campaigns-in-react-native}
React Native SDK (version 0.17.0 and lower) cannot handle actions by default, you must implement it.
You can handle actions in your own customized way by using:
- [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-listener) methods for simple push, banner and walkthrough
- [InjectorInAppMessageListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-in-app-message-listener) methods for in-app messages.
#### Simple Push, Banner and Walkthrough {id=legacy-handling-simple-push-banner-walkthrough-actions-in-react-native}
You can specify your custom action when a customer interacts with your simple push, banner, or walkthrough.
On Android, you cannot handle actions in your own customized way for simple push. It works as default so **OPEN URL** opens the browser and **DEEP LINKING** opens an activity.
```JavaScript
Synerise.Injector.setListener({
onOpenUrl: function(url) {
//your implementation of OPEN URL action
Linking.openURL(url);
},
onDeepLink: function(deepLink) {
//your implementation of DEEP LINKING action
}
//...
//other listener's methods
});
```
#### In-app messages {id=legacy-handling-in-app-message-actions-in-react-native}
You can specify your custom action when a customer interacts with your in-app messages.
```JavaScript
Synerise.Injector.setInAppMessageListener({
onOpenUrl: function(data, url) {
//your implementation of OPEN URL action
},
onDeepLink: function(data, deepLink) {
//your implementation of DEEP LINKING action
},
//...
//other listener's methods
});
```
### Flutter (version 0.7.4 and lower) {id=legacy-handling-actions-from-campaigns-in-flutter}
Flutter SDK (version 0.7.4 and lower) cannot handle actions by default, you must implement it.
You can handle actions in your own customized way by using:
- [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-listener) methods for simple push, banner and walkthrough
- [InjectorInAppMessageListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-in-app-message-listener) methods for in-app messages.
#### Simple Push, Banner and Walkthrough {id=legacy-handling-simple-push-banner-walkthrough-actions-in-flutter}
You can specify your custom action when a customer interacts with your simple push, banner, or walkthrough.
On Android, you cannot handle actions in your own customized way for simple push. It works as default so **OPEN URL** opens the browser and **DEEP LINKING** opens an activity.
```Dart
Synerise.injector.listener((listener) {
listener.onOpenUrl = (url) {
//your implementation of OPEN URL action
};
listener.onDeepLink = (deepLink) {
//your implementation of DEEP LINKING action
};
//...
//other listener's methods
});
```
#### In-app messages {id=legacy-handling-in-app-message-actions-in-flutter}
You can specify your custom action when a customer interacts with your in-app messages.
```Dart
Synerise.injector.inAppMessageListener((listener) {
listener.onOpenUrl = (data, url) {
//your implementation of OPEN URL action
};
listener.onDeepLink = (data, deepLink) {
//your implementation of DEEP LINKING action
};
//...
//other listener's methods
});
```
# Session management
## UUID regeneration mechanism
The UUID is regenerated when:
* the application is reinstalled and UUID cannot be recovered
* one of the UUID regeneration methods is invoked:
- [Regenerate customer](#regenerate-customer)
- [Regenerate customer with identifier](#regenerate-customer-with-identifier)
* the destroy session method is invoked - [Destroy customer session](#destroy-customer-session)
* the SDK is reinitialized by changing the **Profile API Key** with one of these methods:
- [Change Profile API Key dynamically](/developers/mobile-sdk/method-reference/android/lifecycle#change-profile-api-key-dynamically) for Android SDK
- [Change Profile API Key dynamically](/developers/mobile-sdk/method-reference/ios/lifecycle#change-profile-api-key-dynamically) for iOS SDK
- [Change Profile API Key dynamically](/developers/mobile-sdk/method-reference/react-native/lifecycle#change-profile-api-key-dynamically) for React Native SDK
- [Change Profile API Key dynamically](/developers/mobile-sdk/method-reference/flutter/lifecycle#change-profile-api-key-dynamically) for Flutter SDK
* the customer is authenticated by [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) with your own UUID set
* the customer is authenticated by one of the following options and the **authId/authID** parameter is used:
- [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication#authentication-methods)
- [Registration as a Service](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication#authentication-methods)
- [OAuth](/developers/mobile-sdk/user-identification-and-authorization/oauth#authentication-methods)
- [External Providers](/developers/mobile-sdk/user-identification-and-authorization/authenticate-external-providers)
the **authId/authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer)
* the customer is signed out with **SESSION_DESTROY** mode
* the customer is removed by the [removal methods](/developers/mobile-sdk/user-identification-and-authorization/identification-and-user-management#remove-a-customer)
## Session management methods
### Refresh customer token
This method refreshes the customer’s current token.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.refreshToken()](/developers/mobile-sdk/method-reference/android/client-session#refresh-customer-token) |
| iOS | [Client.refreshToken()](/developers/mobile-sdk/method-reference/ios/client-session#refresh-customer-token) |
| React Native | [Synerise.Client.refreshToken()](/developers/mobile-sdk/method-reference/react-native/client-session#refresh-customer-token) |
| Flutter | [Synerise.client.refreshToken()](/developers/mobile-sdk/method-reference/flutter/client-session#refresh-customer-token) |
### Retrieve customer token
This method retrieves the customer’s current, active token. Authentication required.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.retrieveToken()](/developers/mobile-sdk/method-reference/android/client-session#retrieve-customer-token) |
| iOS | [Client.retrieveToken()](/developers/mobile-sdk/method-reference/ios/client-session#retrieve-customer-token) |
| React Native | [Synerise.Client.retrieveToken()](/developers/mobile-sdk/method-reference/react-native/client-session#retrieve-customer-token) |
| Flutter | [Synerise.client.retrieveToken()](/developers/mobile-sdk/method-reference/flutter/client-session#retrieve-customer-token) |
### Get current customer UUID
This method retrieves the customer’s current UUID.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.getUuid()](/developers/mobile-sdk/method-reference/android/client-session#get-current-customer-uuid) |
| iOS | [Client.getUUID()](/developers/mobile-sdk/method-reference/ios/client-session#get-current-customer-uuid) |
| React Native | [Synerise.Client.getUUID()](/developers/mobile-sdk/method-reference/react-native/client-session#get-current-customer-uuid) |
| Flutter | [Synerise.client.getUUID()](/developers/mobile-sdk/method-reference/flutter/client-session#get-current-customer-uuid) |
### Regenerate customer
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier. This operation works only if the customer is anonymous.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.regenerateUuid()](/developers/mobile-sdk/method-reference/android/client-session#regenerate-customer) |
| iOS | [Client.regenerateUUID()](/developers/mobile-sdk/method-reference/ios/client-session#regenerate-customer) |
| React Native | [Synerise.Client.regenerateUUID()](/developers/mobile-sdk/method-reference/react-native/client-session#regenerate-customer) |
| Flutter | [Synerise.client.regenerateUUID()](/developers/mobile-sdk/method-reference/flutter/client-session#regenerate-customer) |
### Regenerate customer with identifier
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier. The optional clientIdentifier parameter is a seed for UUID generation.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.regenerateUuid(clientIdentifier)](/developers/mobile-sdk/method-reference/android/client-session#regenerate-customer-with-identifier) |
| iOS | [Client.regenerateUUID](/developers/mobile-sdk/method-reference/ios/client-session#regenerate-customer-with-identifier) |
| React Native | [Synerise.Client.regenerateUUIDWithClientIdentifier()](/developers/mobile-sdk/method-reference/react-native/client-session#regenerate-customer-with-identifier) |
| Flutter | n/a |
### Destroy customer session
This method clears all session data and creates a new anonymous session with a new profile UUID.
| OS | Method |
|--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.destroySession()](/developers/mobile-sdk/method-reference/android/client-session#destroy-current-session) |
| iOS | [Client.destroySession()](/developers/mobile-sdk/method-reference/ios/client-session#destroy-current-session) |
| React Native | [Synerise.Client.destroySession()](/developers/mobile-sdk/method-reference/react-native/client-session#destroy-current-session) |
| Flutter | [Synerise.client.destroySession()](/developers/mobile-sdk/method-reference/flutter/client-session#destroy-current-session) |
# Simple Profile Authentication
**Upcoming breaking change (effective July 6, 2026):** Synerise is introducing changes to how user identifiers and UUIDs are handled. These changes may affect profiles with accented or diacritical characters in identifiers, profiles with leading or trailing whitespace in identifiers, and profiles with duplicate UUIDs. For details and recommended actions, see [Upcoming changes to handling identifiers](/docs/settings/configuration/identifier-standardization).
Simple Profile Authentication is an approach to authenticate customers once they provide their email address or custom ID. It allows for synchronization of data between Synerise and your database, ensuring consistency and an accurate profiling of customers. However, once you create a customer's profile using this authentication method, it cannot be deleted.
When configuring Simple Profile Authentication, you can enable an authentication salt. It's a randomized string that your application must send with the authentication request. This provides an additional layer of security by reducing the risk of requests being made from outside the application. We strongly recommend using this option.
The implementation of this authentication method is straightforward, requiring the usage of a single method. Unlike other authentication standards, it does not involve intercommunication between your application's backend and Synerise's backend. Instead, customer data is transmitted through a device for validation and authorization.
Additionally, in the Synerise platform (`app.synerise.com`) you can define the following settings:
- [Assignment of loyalty card](/docs/settings/tool/iam-for-apps/general#loyalty-card-assignment)
- [JWT longevity](/docs/settings/tool/iam-for-apps/general#jwt-lifetime)
Simple Profile Authentication proves particularly useful in scenarios when:
- you have a large customer base
- you don't require [OAuth](/developers/mobile-sdk/user-identification-and-authorization/oauth), which in most cases is recommended
Currently this authentication is available only for:
- Android (from `5.7.1` version)
- iOS (from `4.14.0` version)
- React Native (from `0.15.0` version)
- Flutter(from `0.7.0` version)
## Integration process
---
1. In the Synerise platform (`app.synerise.com`), go to **Settings > API keys** and create or update the Profile key.
1. In the **Permissions** section, enable the following permissions:
- `SAUTH_SIMPLE_AUTH_CREATE` (the **Auth** group)
- `API_PERSONAL_INFORMATION_CLIENT_READ`
- `SAUTH_LOGOUT_CLIENT_CREATE`
2. In the **Simple Profile Authentication** section:
1. Enable the **Simple Profile Authentication** toggle.
2. If you want to use a salt when authenticating, enable the **Authentication salt** toggle.
**Result**: A randomized salt is generated. It will need to be included in your mobile application (described further in this article).
We recommend enabling the salt. This improves the security of your requests by adding a layer of client/server authentication.
Simple Profile Authentication with salt enabled (recommended)
3. In the **Profile modification allowlist** section, allow modification of the following profile attributes:
- `UUID`
- `email` or `customId` (choose the identifier you will use in [this method](#authentication-methods))
You can learn more about creating API keys in the Synerise platform [here](/docs/settings/tool/api).
1. **If you enabled the Authentication salt**: Insert the salt into the initialization script.
It is your responsibility to ensure the secure storage of the salt in your application. We highly recommend keeping the salt encrypted.
You can find the Synerise initialization scripts in the articles below:
- [Android](/developers/mobile-sdk/installation-and-configuration/android#initialization)
- [iOS](/developers/mobile-sdk/installation-and-configuration/ios#initialization)
- [React Native](/developers/mobile-sdk/installation-and-configuration/react-native#initialization)
- [Flutter](/developers/mobile-sdk/installation-and-configuration/flutter#initialization)
2. As a sign-in method, implement [this method](#authentication-methods). In the customer's data object, `authId` (unique identifier of a customer in your data base), `email` or `customId` parameters are required. As a result of this method, the `client.simpleAuthLogin` event is generated on the activity list of a customer in the Synerise platform in **Behavioral Data Hub**.
Click here to see the event body
A customer logged in with this method is assigned with a Simple Profile Authentication token (a JWT) whose [longevity you can define in the Synerise platform](/docs/settings/tool/iam-for-apps/general#jwt-lifetime).
1. To check if a customer is signed in through Simple Profile Authentication, use [this method](#check-if-a-customer-is-signed-in).
To check if a customer is signed in with other authentication types, use [this method](/developers/mobile-sdk/user-identification-and-authorization/synerise-authentication#check-if-a-customer-is-signed-in)
## Authentication use cases
---
| Use case | Outcome |
|------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| An anonymous customer signs in to a new account | 1. Before signing in, a user is only assigned with UUID and clientId. 2. When signed in, they receive authID, and email and custom ID are assigned. The customer can update their data. |
| An anonymous customer signs in to an existing account | 1. Before signing in, a user is only assigned with UUID and clientId. 2. A customer signs in to their account on the interface with their credentials (authID) 3. A customer is [merged](/developers/api/clients/merging-profiles). 4. A customer is signed in and can update their data. |
| Signed-in customer signs in to a new account | 1. A customer is already recognized. 2. A customer provides new sign-in credentials and the customer is signed in to a new account (a new account is created). This customer receives authID, and email and custom ID are assigned. The customer can update their data. |
| Signed-in customer signs in to an existing account | 1. A customer is already recognized. 2. A customer re-signs in to other existing account on the interface with credentials (authID). 3. A customer is signs in and can update their data. |
## Troubleshooting
---
- If the `authID` value is not unique, there is a risk of generating the same UUID for various customers which results in an error. This is because the UUID is generated based on the `authID` value
- An error may occur when `email` or `customId` is not unique and there is an attempt to update a customer with other's customer `email` or `customId`.
## Best practices
---
- Check if a customer is signed in with [this method](#check-if-a-customer-is-signed-in).
- Use the [Simple Profile Authentication method](#authentication-methods) only for logging in and updating a customer's data.
- Provide a sign-out feature with [this method](#customer-sign-out).
## Authentication methods
---
This method authenticates a customer with Simple Profile Authentication.
| OS | Method |
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.simpleAuthentication(clientData, authId)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-via-simple-profile-authentication) |
| iOS | [Client.simpleAuthentication(data:authID:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-via-simple-profile-authentication) |
| React Native | [Synerise.Client.simpleAuthentication(data, authID, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-via-simple-profile-authentication) |
| Flutter | [Synerise.client.simpleAuthentication(clientData, authId)](/developers/mobile-sdk/method-reference/flutter/client-authentication#authenticate-customer-via-simple-profile-authentication) |
**authId/authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
## Other methods
---
### Check if a customer is signed in
This method checks if a customer is signed in through Simple Profile Authentication.
This method returns `false` if a customer is authenticated through [RaaS](/developers/mobile-sdk/user-identification-and-authorization/synerise-authentication), [oAuth](/developers/mobile-sdk/user-identification-and-authorization/oauth), [Facebook or Apple](/developers/mobile-sdk/user-identification-and-authorization/authenticate-external-providers).
| OS | Method |
|--------------|-------------------------------------------------------------------------------------------------------------------------------------------|
| Android | [Client.isSignedInViaSimpleAuthentication()](/developers/mobile-sdk/method-reference/android/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication) |
| iOS | [Client.isSignedInViaSimpleAuthentication()](/developers/mobile-sdk/method-reference/ios/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication) |
| React Native | [Synerise.Client.isSignedInViaSimpleAuthentication()](/developers/mobile-sdk/method-reference/react-native/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication) |
| Flutter | [Synerise.client.isSignedInViaSimpleAuthentication()](/developers/mobile-sdk/method-reference/flutter/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication) |
### Customer sign out
This method signs out the customer. The method terminates the JWT token and ends the customer session.
| OS | Method |
|--------------|-----------------------------------------------------------------------------------------------------------------------|
| Android | - [Client.signOut()](/developers/mobile-sdk/method-reference/android/client-authentication#sign-out-customer) - [Client.signOut(mode, signOutFromAllDevices)](/developers/mobile-sdk/method-reference/android/client-authentication#sign-out-customer-with-mode-or-from-all-devices) |
| iOS | - [Client.signOut()](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-out-customer) - [Client.signOut(mode:fromAllDevices:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-out-customer-with-mode-or-from-all-devices) |
| React Native | - [Synerise.Client.signOut()](/developers/mobile-sdk/method-reference/react-native/client-authentication#sign-out-a-customer) - [Synerise.Client.signOutWithMode(mode, fromAllDevices, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#sign-out-customer-with-mode-or-from-all-devices) |
| Flutter | [Synerise.client.signOut()](/developers/mobile-sdk/method-reference/flutter/client-authentication#sign-out-a-customer) |
## What's next
---
When the customer's is signed in, you can implement [profile management methods](/developers/mobile-sdk/user-identification-and-authorization/identification-and-user-management#profile-management-methods) and [session management methods](/developers/mobile-sdk/user-identification-and-authorization/session-management).
# iOS
## Configuring push notifications (iOS)
### Prerequisites
---
- Configure handling push notifications in your application. See [Apple Developer - Notifications](https://developer.apple.com/notifications/).
- Google Firebase Cloud Messaging is necessary to handle [Mobile Campaigns](/docs/campaign/Mobile) sent from Synerise.
1. Follow the instructions in [Firebase - Get Started on iOS](https://firebase.google.com/docs/storage/ios/start).
2. Integrate the Firebase with Synerise. See [Integration](/docs/settings/tool/firebase) section.
### Set up Firebase Cloud Messaging for Synerise SDK
---
Extend the Firebase Messaging Delegate so our SDK can receive the Firebase token that is required to deliver push notifications from Synerise:
```Swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
if #available(iOS 10, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
guard let fcmToken = Messaging.messaging().fcmToken else {
return
}
let mobilePushAgreement = true // true or false, should depend on device permissions and customer's agreement in the application
Client.registerForPush(registrationToken:fcmToken, mobilePushAgreement:mobilePushAgreement, success: { (success) in
// success
}) { (error) in
// failure
}
}
} else {
let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
}
// MARK: - MessagingDelegate
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
if let registrationToken = fcmToken {
let mobilePushAgreement = true // true or false, should depend on device permissions and customer's agreement in the application
Client.registerForPush(registrationToken:registrationToken, mobilePushAgreement:mobilePushAgreement, success: { (success) in
// success
}) { (error) in
// failure
}
}
}
```
```Objective-C
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[FIRApp configure];
[FIRMessaging messaging].delegate = self;
if (@available(iOS 10, *)) {
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
UNAuthorizationOptions authOptions = (UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge);
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:authOptions completionHandler:^(BOOL granted, NSError *error) {
if (granted == YES) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
NSString *fcmToken = [FIRMessaging messaging].FCMToken;
if (fcmToken == nil) {
return;
}
BOOL mobilePushAgreement = YES; // YES or NO, should depend on device permissions and customer's agreement in the application
[SNRClient registerForPush:fcmToken mobilePushAgreement:mobilePushAgreement success:^(BOOL isSuccess) {
// success
} failure:^(NSError *error) {
// failure
}];
}];
} else {
UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
#pragma mark - FIRMessagingDelegate
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
if (fcmToken != nil) {
BOOL mobilePushAgreement = YES; // YES or NO, should depend on device permissions and customer's agreement in the application
[SNRClient registerForPush:fcmToken mobilePushAgreement:mobilePushAgreement success:^(BOOL isSuccess) {
// success
} failure:^(NSError *error) {
// failure
}];
}
}
```
The second parameter of the registration method is the agreement for mobile push campaigns. In the Profile's card in Synerise, you can find it in the **Subscriptions** section (if you have the required access permission). Learn more about the [Client.registerForPush(registrationToken:mobilePushAgreement:success:failure:) method in the method reference](/developers/mobile-sdk/method-reference/ios/campaigns#register-for-push-notifications).
### Keep Firebase token always up-to-date
---
You must always keep the Firebase token updated. In many cases in the application lifecycle, such as authorization, destroyed sessions, user context change, periodic jobs ([Background Tasks](/developers/mobile-sdk/installation-and-configuration/ios#background-tasks)), and so on, the registration needs to be updated. In these situations, the SDK invokes the [snr_registerForPushNotificationsIsNeeded(origin:)](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed-by-origin) method or [snr_registerForPushNotificationsIsNeeded()](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed) method.
[Background Tasks](/developers/mobile-sdk/installation-and-configuration/ios#background-tasks)) allows you to keep the Firebase token updated even if the host application is not launched for a long time. It launches your app in the background approximately every 20 days and refreshes the token so it stays up to date.
```Swift
// MARK: - SyneriseDelegate
func snr_registerForPushNotificationsIsNeeded(origin: PushNotificationsRegistrationOrigin) -> Void {
guard let fcmToken = Messaging.messaging().fcmToken else {
return
}
let mobilePushAgreement = true // true or false, depending to customer's agreement in the application
Client.registerForPush(registrationToken:fcmToken, mobilePushAgreement:mobilePushAgreement, success: { (success) in
// success
}) { (error) in
// failure
}
}
```
```Objective-C
#pragma mark - SNRSyneriseDelegate
- (void)SNR_registerForPushNotificationsIsNeededByOrigin:(SNRPushNotificationsRegistrationOrigin)origin {
NSString *fcmToken = [FIRMessaging messaging].FCMToken;
if (fcmToken == nil) {
return;
}
BOOL mobilePushAgreement = YES; // YES or NO, depending to customer's agreement in the application
[SNRClient registerForPush:fcmToken mobilePushAgreement:mobilePushAgreement success:^(BOOL isSuccess) {
// success
} failure:^(NSError *error) {
// failure
}];
}
```
### Configure Notification Encryption
---
To enable encrypted push notifications, you must change the configuration of your workspace in the Synerise portal. See [Google Firebase](/docs/settings/tool/firebase).
iOS 10 or higher version is required for this feature.
Set your Keychain Group Identifier (see [this section](/developers/mobile-sdk/settings#set-up-keychain-group-identifier)) and enable `Synerise.settings.notifications.encryption` in SDK settings:
**Next:** Configure [Synerise Notification Service Extension](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension).
### Synerise Notification Service Extension {id=synerise-notification-service-extension}
---
**Synerise Notification Service Extension** is an object that adds the notification functionality to the SDK. It works by implementing the [`UNNotificationServiceExtension`](https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension) that cooperates with the host application.
The Synerise Notification Service Extension facilitates some operations by automating them. This means a one-time implementation provides new functionalities, changes, and fixes, along with new versions of the SDK.
It implements the following operations:
- Decrypting **Simple Push** communication data (if encryption is enabled).
- Tracking events from **Simple Push** communication (e.g. `push.view`).
- Tracking `push.dismiss` when the notification is cleared from the notification center.
- Adding action buttons to **Simple Push** communication (if the communication contains any).
- Improving the appearance of **Simple Push** communication (Rich Media - Single Image) with an image thumbnail.
From version 4.24.0, the SDK started tracking `push.dismiss` events when clearing from the notification center. You can enable tracking this event by setting **kSNRNotificationServiceExtensionOptionsPushDismissProcessing** to true ([see implementation below](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension-implementation)). If you enable this option, it can cause a noticeable amount of generated events.
#### Configuration {id=synerise-notification-service-extension-configuration}
1. Configure **App Group Identifier** (see [this section](/developers/mobile-sdk/settings#set-up-app-group-identifier)).
2. Configure **Keychain Group Identifier** (see [this section](/developers/mobile-sdk/settings#set-up-keychain-group-identifier)).
3. Add the **Notification Service Extension** to your iOS project ([Apple Developer - UNNotificationServiceExtension](https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension)).
4. Configure the SDK both in the host application and in the notification service extension.
- Configuring **App Group Identifier** and **Keychain Group Identifier** both in the host application and in the notification service extension is required for proper functioning of all **Notification Service Extension** features.
- Your host application and the **Notification Service Extension** must have the same **iOS Deployment Target** version (newer than iOS 10).
- If you want to enable processing the campaign by **Notification Service Extension**, select the [Mutable-Content](/developers/mobile-sdk/configuring-push-notifications/ios#mutable-content-parameter) option.
```Swift
import UserNotifications
import SyneriseSDK
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = self.bestAttemptContent {
Synerise.settings.sdk.appGroupIdentifier = "YOUR_APP_GROUP_IDENTIFIER"
Synerise.settings.sdk.keychainGroupIdentifier = "YOUR_KEYCHAIN_GROUP_IDENTIFIER"
NotificationServiceExtension.setDelegate(self)
NotificationServiceExtension.setNotificationDelegate(self)
#if DEBUG
NotificationServiceExtension.setDebugModeEnabled(true)
#endif
NotificationServiceExtension.setDecryptionFallbackNotificationTitleAndBody(title: "(Encrypted))", body: "(Encrypted)")
NotificationServiceExtension.didReceiveNotificationExtensionRequest(request, withMutableNotificationContent: bestAttemptContent, options: [
kSNRNotificationServiceExtensionOptionsPushDismissProcessing: true
])
contentHandler(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
if let contentHandler = self.contentHandler, let bestAttemptContent = self.bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
extension NotificationService: NotificationServiceExtensionDelegate {
func notificationServiceExtensionDidFailProcessingWithError(_ error: Error) {
#if DEBUG
self.bestAttemptContent?.title = error.localizedDescription
#endif
}
func notificationServiceExtensionDidFailDecryptionWithError(_ error: Error) {
#if DEBUG
self.bestAttemptContent?.title = error.localizedDescription
#endif
}
}
extension NotificationService: NotificationDelegate {
// This method is called when a Synerise notification is received.
func snr_notificationDidReceive(notificationInfo: NotificationInfo) {
//...
}
}
```
```Objective-C
#import "NotificationService.h"
#import
#import
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
SNRSynerise.settings.sdk.appGroupIdentifier = @"YOUR_APP_GROUP_IDENTIFIER";
SNRSynerise.settings.sdk.keychainGroupIdentifier = @"YOUR_KEYCHAIN_GROUP_IDENTIFIER";
[SNRNotificationServiceExtension setDelegate:self];
[SNRNotificationServiceExtension setNotificationDelegate:self];
#ifdef DEBUG
[SNRNotificationServiceExtension setDebugModeEnabled:YES];
#endif
[SNRNotificationServiceExtension setDecryptionFallbackNotificationTitle:@"(Encrypted)" andBody:@"(Encrypted)"];
[SNRNotificationServiceExtension didReceiveNotificationExtensionRequest:request withMutableNotificationContent:self.bestAttemptContent options:@{
kSNRNotificationServiceExtensionOptionsPushDismissProcessing: @(YES) // if true, tracking `push.dismiss` by clearing from the notification center is enabled
}];
self.contentHandler(self.bestAttemptContent);
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
self.contentHandler(self.bestAttemptContent);
}
#pragma mark - SNRNotificationServiceExtensionDelegate
- (void)notificationServiceExtensionDidFailProcessingWithError:(NSError *)error {
#ifdef DEBUG
self.bestAttemptContent.body = error.localizedDescription;
#endif
}
- (void)notificationServiceExtensionDidFailDecryptionWithError:(NSError *)error {
#ifdef DEBUG
self.bestAttemptContent.body = error.localizedDescription;
#endif
}
#pragma mark - SNRNotificationDelegate
// This method is called when a Synerise notification is received.
- (void)SNR_notificationDidReceive:(SNRNotificationInfo *)notificationInfo {
//...
}
@end
```
Examples of Notification Service Extensions:
- [Notification Service Extension in Swift](https://github.com/Synerise/synerise-ios-sdk/tree/master/SampleAppSwift/4.10.0/SyneriseNotificationServiceExtension)
- [Notification Service Extension in Objective-C](https://github.com/Synerise/synerise-ios-sdk/tree/master/SampleAppSwift/4.10.0/SyneriseNotificationServiceExtensionObjC)
#### Debug Mode {id=synerise-notification-service-extension-debug-mode}
You can enable the debug mode for Notification Service Extension logging and testing purposes.
Do not use the debug mode in a release version of your application.
In the debug mode, decryption process is considered successful even if it fails. Your best attempt content (`UNNotificationContent` object) is modified - the notification displays the title and body with the problem that occurred during decryption. It may help you debug and find problems with the configuration.
### Handling incoming push notifications
---
You may disable handling push notifications in the SDK at any time. See [Enable/disable notifications](/developers/mobile-sdk/settings#enabledisable-notifications).
Documentation on how to prepare push notifications in [app.synerise.com](https://app.synerise.com) is available in our [user guide](/docs/campaign/Mobile).
In order to handle Synerise push notifications, you must pass the incoming push payload to the Synerise SDK.
#### Synerise payload
The following code shows how to handle push notifications in the `AppDelegate`:
```Swift
// Support for Push Notifications on iOS 9
// Support for Silent Notifications
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo)
if isSyneriseNotification {
Synerise.handleNotification(userInfo)
completionHandler(.noData)
}
}
func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) {
let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo)
if isSyneriseNotification {
Synerise.handleNotification(userInfo, actionIdentifier: identifier)
completionHandler()
}
}
// Support for Push Notifications on iOS 10 and above
// MARK: - UNUserNotificationCenterDelegate
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo)
if isSyneriseNotification {
Synerise.handleNotification(userInfo, actionIdentifier: response.actionIdentifier)
completionHandler()
}
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo)
if isSyneriseNotification {
Synerise.handleNotification(userInfo)
completionHandler(UNNotificationPresentationOptions.init(rawValue: 0))
}
}
```
```Objective-C
// Support for Push Notifications on iOS 9
// Support for Silent Notifications
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo];
if (isSyneriseNotification) {
[SNRSynerise handleNotification:userInfo];
completionHandler(UIBackgroundFetchResultNoData);
}
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler {
BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo];
if (isSyneriseNotification) {
[SNRSynerise handleNotification:userInfo actionIdentifier:identifier];
completionHandler();
}
}
// Support for Push Notifications on iOS 10 and above
// pragma mark - UNUserNotificationCenterDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler NS_AVAILABLE_IOS(10) {
NSDictionary *userInfo = response.notification.request.content.userInfo;
BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo];
if (isSyneriseNotification) {
[SNRSynerise handleNotification:userInfo actionIdentifier:response.actionIdentifier];
completionHandler();
}
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler NS_AVAILABLE_IOS(10) {
NSDictionary *userInfo = notification.request.content.userInfo;
BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo];
if (isSyneriseNotification) {
[SNRSynerise handleNotification:userInfo];
completionHandler(UNNotificationPresentationOptionNone);
}
}
```
All of these methods must be implemented to ensure proper handling of push notifications.
Displaying the notification banner on top of the screen in foreground state depends on values passed in `completionHandler` in the [UNUserNotificationCenterDelegate.userNotificationCenter(_:willPresent:completionHandler:)](https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate/1649518-usernotificationcenter) method.
#### Custom payload
You may send both custom push notifications and custom campaigns in [Synerise](https://app.synerise.com). The code below of one sample delegate method checks if the notification origin and then handles it.
```Swift
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo)
if isSyneriseNotification {
Synerise.handleNotification(userInfo)
completionHandler(UNNotificationPresentationOptions.init(rawValue: 0))
} else {
// Handle other notification in your own way
}
}
```
```Objective-C
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler NS_AVAILABLE_IOS(10) {
NSDictionary *userInfo = notification.request.content.userInfo;
BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo];
if (isSyneriseNotification) {
[SNRSynerise handleNotification:userInfo];
completionHandler(UNNotificationPresentationOptionNone);
} else {
// Handle other notification in your own way
}
}
```
#### Encrypted payloads
If you handle the Synerise push notification, you do not have to do anything. The SDK decrypts Synerise push notification's payload:
- In [Notification Service Extension](#synerise-notification-service-extension) for push notifications
- In the SDK, after invoking [`Synerise.handleNotification(_:)`](/developers/mobile-sdk/method-reference/ios/campaigns#handle-synerise-push-notification) for silent push notifications
Otherwise, if it is a custom encrypted push notification sent by Synerise, or you need decrypt data from the push notification, there are two methods for dealing with them:
- [`Synerise.isNotificationEncrypted(_:)`](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-encrypted) - checks if the notification payload is encrypted by Synerise.
- [`Synerise.decryptNotification(_:)`](/developers/mobile-sdk/method-reference/ios/campaigns#decrypt-push-notification) - decrypts a notification payload.
```Swift
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo)
if isSyneriseNotification {
let isNotificationEncrypted: Bool = Synerise.isNotificationEncrypted(userInfo)
if isNotificationEncrypted == true {
if let userInfoDecrypted = Synerise.decryptNotification(userInfo) {
// Handle decrypted payload in your own way
}
Synerise.handleNotification(userInfo)
completionHandler(UNNotificationPresentationOptions.init(rawValue: 0))
}
}
```
```Objective-C
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler NS_AVAILABLE_IOS(10) {
NSDictionary *userInfo = notification.request.content.userInfo;
BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo];
if (isSyneriseNotification) {
BOOL isNotificationEncrypted = [SNRSynerise isNotificationEncrypted:userInfo];
if (isNotificationEncrypted == YES) {
NSDictionary *userInfoDecrypted = [SNRSynerise decryptNotification:userInfo];
if (userInfoDecrypted != nil) {
// Handle decrypted payload in your own way
}
[SNRSynerise handleNotification:userInfo];
completionHandler(UNNotificationPresentationOptionNone);
}
}
```
Remember, if you want to send custom push notifications by Synerise (and it is not a silent push notification), you must implement the code in your [Notification Service Extension](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension):
```Swift
import UserNotifications
import SyneriseSDK
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = self.bestAttemptContent {
var userInfo = notification.request.content.userInfo
let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo)
if isSyneriseNotification == true {
//...
} else {
let isNotificationEncrypted: Bool = Synerise.isNotificationEncrypted(userInfo)
if isNotificationEncrypted == true {
if let userInfoDecrypted = Synerise.decryptNotification(userInfo) {
bestAttemptContent.title = userInfoDecrypted["aps"]?["alert"]?["title"]
bestAttemptContent.body = userInfoDecrypted["aps"]?["alert"]?["body"]
bestAttemptContent.userInfo = userInfoDecrypted;
} else {
bestAttemptContent.title = "YOUR_FALLBACK_TITLE"
bestAttemptContent.body = "YOUR_FALLBACK_BODY"
}
}
}
contentHandler(bestAttemptContent)
}
}
}
```
#### 'Content-Available' parameter
If you want to receive push notification in the background and foreground states, enable the `Content-Available` option while creating a push notification in Synerise ([Creating mobile push templates](/docs/campaign/Mobile/creating-mobile-push-templates/mobile-push-visual-builder)).
Enabled `Content-Available` option in a visual builder
When you want support this option, you must add the capability to your application. In the **Signing and Capability** tab, in the **Background Modes** capability, select the **Remote notifications** checkbox:
Remote notifications capability in the Xcode
Your application will be notified of the notification delivery when it's in the foreground or background (the app will be woken up). This ensures that the necessary method and code responsible for receiving background notifications are executed. On iOS, it calls your app delegate’s [application(_:didReceiveRemoteNotification:fetchCompletionHandler:)](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application) method. On watchOS, it calls your extension delegate’s [didReceiveRemoteNotification(_:fetchCompletionHandler:)](https://developer.apple.com/documentation/watchkit/wkextensiondelegate/3152235-didreceiveremotenotification) method.
For more details, see [Apple Developer - Pushing Background Updates to Your App](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app).
#### 'Mutable-Content' parameter
If you want your notification to be processed by the Notification Service Extension, enable the `Mutable-Content` option while creating a push notification in Synerise ([Creating mobile push templates](/docs/campaign/Mobile/creating-mobile-push-templates/mobile-push-visual-builder)).
Enabled `Mutable-Content` option in a visual builder
If you want to have full support for **Simple Push** communication, and to make `Mutable-Content` relevant and functional, you must configure [Synerise Notification Service Extension](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension). This extension is required to fully support Simple Push communication for iOS, such as gathering the view events.
For more details, see [Apple Developer - Modifying content in newly delivered notifications](https://developer.apple.com/documentation/usernotifications/modifying-content-in-newly-delivered-notifications).
#### Delegate methods
[NotificationDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#notification-delegate) is available from SDK version 4.10.0.
A [NotificationDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#notification-delegate) handles events from Synerise notifications.
- To handle "receive" events when an application is disabled or in background state: set the delegate in the notification service extension by using the `NotificationServiceExtension.setNotificationDelegate(_:)` method. See [this section](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension-implementation) to get a sample code for the notification service extension.
- **SDK version 4.14.3 or newer:** To handle "receive" events when an application is launched by the notification or in foreground state: set the delegate in the application by using the `Synerise.setNotificationDelegate(_:)` method.
- To handle "dismiss" and "click" events: set the delegate in the application by using the `Synerise.setNotificationDelegate(_:)` method.
See a sample code from the application below:
```Swift
extension SyneriseManager: NotificationDelegate {
// This method is called when a Synerise notification is received.
func snr_notificationDidReceive(notificationInfo: NotificationInfo) {
//...
}
// This method is called when a Synerise notification is dismissed.
func snr_notificationDidDissmis(notificationInfo: NotificationInfo) {
//...
}
// This method is called when a Synerise notification is clicked.
func snr_notificationClicked(notificationInfo: NotificationInfo) {
//...
}
// This method is called when an action button is clicked in a Synerise notification.
func snr_notificationClicked(notificationInfo: NotificationInfo, actionButton: String) {
//...
}
}
```
```Objective-C
#pragma mark - SNRNotificationDelegate
// This method is called when a Synerise notification is received.
- (void)SNR_notificationDidReceive:(SNRNotificationInfo *)notificationInfo {
//...
}
// This method is called when a Synerise notification is dismissed.
- (void)SNR_notificationDidDissmis:(SNRNotificationInfo *)notificationInfo {
//...
}
// This method is called when a Synerise notification is clicked.
- (void)SNR_notificationClicked:(SNRNotificationInfo *)notificationInfo {
//...
}
// This method is called when an action button is clicked in a Synerise notification.
- (void)SNR_notificationActionButtonClicked:(SNRNotificationInfo *)notificationInfo actionButton:(NSString *)actionButton {
//...
}
```
### Handling actions from push notifications
---
- [Read more about types of actions in campaigns](/developers/mobile-sdk/campaigns/action-handling#types-of-actions-in-campaigns)
- [Read more about handling actions from push notifications](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-ios)
### Additional in-app alert from push notifications
---
The iOS SDK can display an additional alert in the application after a push notification is received. See [this article](/developers/mobile-sdk/campaigns/simple-push#additional-in-app-alert-when-simple-push-is-received) to read more about this feature.
Simple Push campaign with in-app alert
### Rich Media in push notifications
---
**Notification Content Extension** is an object that allows rendering your own appearance of a push notification when the notification is expanded (by tapping the notification). It works by implementing the UNNotificationContentExtension that cooperates with the host application.
Synerise SDK does most of the work needed and provides classes for the Notification Content Extensions. When you create an extension, you only need to make it inherit from a suitable Synerise SDK class.
#### Prerequisites {id=rich-media-in-push-notifications-prerequisites}
1. Configure **App Group Identifier** (see [this section](/developers/mobile-sdk/settings#set-up-app-group-identifier)).
2. Configure **Keychain Group Identifier** (see [this section](/developers/mobile-sdk/settings#set-up-keychain-group-identifier)).
#### Configuration {id=rich-media-in-push-notifications-configuration}
To add this feature in your [Simple Push Campaigns](/developers/mobile-sdk/campaigns/simple-push), you must:
1. Add the **Notification Content Extensions** in your iOS project - separately for each type of our Rich Media extensions.
2. Configure the host application and the notification content extensions with the SDK.
- Configuring **App Group Identifier** and **Keychain Group Identifier** both in the host application and in the notification service extension is required for proper functioning of all **Notification Content Extensions** features.
- Your host application and all the **Notification Content Extensions** must have the same **iOS Deployment Target** version (higher than iOS 10).
#### Application implementation {id=rich-media-in-push-notifications-application-implementation}
You must create push notification categories with the right identifiers, correlating with **Content Extensions** that you added before. The identifiers must be taken from the Synerise SDK constants (they are used in the code sample below). This does not affect button names.
```Swift
Synerise.settings.sdk.appGroupIdentifier = "YOUR_APP_GROUP_IDENTIFIER"
Synerise.settings.sdk.keychainGroupIdentifier = "YOUR_KEYCHAIN_GROUP_IDENTIFIER"
let singleMediaCategory = UNNotificationCategory(identifier: SNRSingleMediaContentExtensionViewControllerCategoryIdentifier, actions: [], intentIdentifiers: [], options: [])
let carouselPrevious = UNNotificationAction(identifier: SNRCarouselContentExtensionViewControllerPreviousItemIdentifier, title: "Previous", options: [])
let carouselAction = UNNotificationAction(identifier: SNRCarouselContentExtensionViewControllerChooseItemIdentifier, title: "Go!", options: UNNotificationActionOptions.foreground)
let carouselNext = UNNotificationAction(identifier: SNRCarouselContentExtensionViewControllerNextItemIdentifier, title: "Next", options: [])
let carouselCategory = UNNotificationCategory(identifier: SNRCarouselContentExtensionViewControllerCategoryIdentifier, actions: [carouselPrevious, carouselAction, carouselNext], intentIdentifiers: [], options: [])
// Use this method when you use SDK 4.21.0 or higher
Synerise.setNotificationCategories([singleMediaCategory, carouselCategory])
// or
// Use this method when you use SDK lower than 4.21.0
UNUserNotificationCenter.current().setNotificationCategories([singleMediaCategory, carouselCategory])
```
| Method | Description |
| --- | --- |
| [`Synerise.setNotificationCategories(_:)`](/developers/mobile-sdk/method-reference/ios/campaigns#set-notification-categories) | Sets the notification categories (including Synerise categories) that your app supports. Use this method when you use SDK 4.21.0 or higher. |
| [`UNUserNotificationCenter.current().setNotificationCategories(_:)`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/setnotificationcategories(_:)) | Sets the notification categories by using the standard iOS SDK method. Use this method when you use SDK lower than 4.21.0. |
#### Single Media implementation {id=rich-media-in-push-notifications-single-media-implementation}
##### Properties {id=rich-media-in-push-notifications-single-media-properties}
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| contentViewIsScrollable | `Bool` | true | This parameter specifies if vertical scroll is enabled. If false, content is adjusted to the screen height. |
| imageContentMode | `UIViewContentMode` | `UIViewContentModeScaleAspectFill` | This parameter sets the rendering mode of an image |
##### Info.plist {id=rich-media-in-push-notifications-single-media-info-plist}
The configuration for your **Content Extension** in `\*.plist` file must be:
- correlated with Synerise SDK constants for notification category
*NSExtension->NSExtensionAttributes->UNNotificationExtensionCategory->0* must be **synerise.notifications.category.single-media**.
- configured without a storyboard (by, default a storyboard is set).
*NSExtensionMainStoryboard* key and its values must be removed from `\*.plist` file.
- correlated with the principal class
*NSextensionPrincipalClass* key must have value with the name of the main class for the notification extension you have created. For **Content Extension** written in Swift, the prefix `$(PRODUCT_MODULE_NAME).` is required. For Objective-C, it is not.
Example `\*.plist` file for single media:
Sample *.plist configuration in Single Image Notification Content Extension
##### Example {id=rich-media-in-push-notifications-single-media-example}
Examples of Single Media Notification Content Extension:
- [Single Media Notification Content Extension in Swift](https://github.com/Synerise/synerise-ios-sdk/tree/master/SampleAppSwift/4.10.0/SyneriseSingleMediaNotificationContentExtension)
- [Single Media Notification Content Extension in Objective-C](https://github.com/Synerise/synerise-ios-sdk/tree/master/SampleAppSwift/4.10.0/SyneriseSingleMediaNotificationContentExtensionObjC)
#### Carousel implementation {id=rich-media-in-push-notifications-carousel-implementation}
##### Properties {id=rich-media-in-push-notifications-carousel-properties}
| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| imageContentMode | `UIViewContentMode` | `UIViewContentModeScaleAspectFill` | This parameter sets the rendering mode of images |
##### Info.plist {id=rich-media-in-push-notifications-carousel-info-plist}
The configuration for your **Content Extension** in `\*.plist` file must be:
- correlated with Synerise SDK constants for notification category.
*NSExtension->NSExtensionAttributes->UNNotificationExtensionCategory->0* must be **synerise.notifications.category.carousel**.
- configured without storyboard (it is set by default).
*NSExtensionMainStoryboard* key and its values must be removed from `\*.plist` file.
- correlated with the principal class.
*NSextensionPrincipalClass* key must have value with name of your main class for the notification extension you have created. For **Content Extension** written in Swift, the prefix `$(PRODUCT_MODULE_NAME).` is required. For Objective-C, it is not.
See proper `\*.plist` file example for single media below:
Sample *.plist configuration in Carousel Notification Content Extension
##### Example {id=rich-media-in-push-notifications-carousel-example}
Examples of Carousel Notification Content Extension:
- [Carousel Notification Content Extension in Swift](https://github.com/Synerise/synerise-ios-sdk/tree/master/SampleAppSwift/4.10.0/SyneriseCarouselNotificationContentExtension)
- [Carousel Notification Content Extension in Objective-C](https://github.com/Synerise/synerise-ios-sdk/tree/master/SampleAppSwift/4.10.0/SyneriseCarouselNotificationContentExtensionObjC)
# Client
### ClientIdentityProvider
**Declared In:**
Headers/SNRClientIdentityProvider.h
**Declaration:**
```Swift
enum ClientIdentityProvider: Int {
synerise,
oauth,
simpleAuth,
facebook,
apple,
google
}
```
---
---
### ClientEventsApiQuery
The object to set parameters easily for fetching client events from API.
**Declared In:**
Headers/SNRClientEventsApiQuery.h
**Inherits From:**
[NSObject](https://developer.apple.com/documentation/objectivec/nsobject)
**Declaration:**
**Properties:**
Property | Type | Optional | Default | Description |
| --- | --- | --- | --- | --- |
| **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) | yes | nil | Object that stores all agreements of a customer |
| **attributes** | [AnyHashable: Any] | yes | [] | Additional custom attributes of a customer |
**Initializers:**
```Swift
init()
```
```Objective-C
- (instancetype)init
```
# Simple push
## Overview
---
Simple push is a standard push notification interacting with your operating system. If an app is not active (was closed or running in the background) in the moment of receiving simple push, it appears in the notification center. When a customer clicks the notification, they are taken to the application and a simple push is presented.
If an app is active, the simple push is presented right away.
Read more about creating and testing simple push [here](/docs/campaign/Mobile/creating-mobile-push).
Additionaly, iOS and React Native (iOS) simple push campaigns support two types of Rich Media extensions:
- [Single Media](#single-media)
- [Image Carousel](#image-carousel)
Add support for Rich Media Push Notifications in your application. See [Rich Media in Push Notifications](/developers/mobile-sdk/configuring-push-notifications/ios#rich-media-in-push-notifications) section.
## Configuration
---
Simple push campaign is served by push notifications. See:
- [Configuring push notifications - Android](/developers/mobile-sdk/configuring-push-notifications/android)
- [Configuring push notifications - iOS](/developers/mobile-sdk/configuring-push-notifications/ios)
- [Configuring push notifications - React Native](/developers/mobile-sdk/configuring-push-notifications/react-native)
- [Configuring push notifications - Flutter](/developers/mobile-sdk/configuring-push-notifications/flutter)
Additionally, check possible available configuration options in the [Settings](/developers/mobile-sdk/settings#notifications).
## Events generated by simple push
---
For information about events generated by simple push, see the [event reference](/docs/assets/events/event-reference/mobile-push).
## Handling actions from simple push
---
Handling main actions from campaigns depends on campaign type and operating system and it is described [here](/developers/mobile-sdk/campaigns/action-handling).
## Additional in-app alert when simple push is received
---
This feature is available only in iOS SDK, React Native SDK (iOS) and Flutter SDK (iOS).
The iOS SDK displays an additional alert in the application after a simple push campaign is received and it is configured with [OPEN_URL](/developers/mobile-sdk/campaigns/action-handling#types-of-actions-in-campaigns) or [DEEP_LINKING](/developers/mobile-sdk/campaigns/action-handling#types-of-actions-in-campaigns) action. This alert is displayed in the middle of the screen with content from the native notification payload. This is the default behavior.
You can disable it in the SDK Settings - [Enable/disable notification alerts](/developers/mobile-sdk/settings#enabledisable-notification-in-app-alerts).
Simple Push campaign with in-app alert
## Payload
---
{
"data": {
"issuer": "Synerise",
"message-type": "static-content",
"content-type": "simple-push",
"content": {
"notification": {
"title": "Finish your purchase",
"body": "You have in your basket Road Bike RS-500 with discount for \"New Users\". Comeback to the basket and complete your purchase.",
"icon": "https://upload.snrcdn.net/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/7eba69de2d4dab3a9388b9d72abd91eb.png",
"action": {
"type": "OPEN_APP"
}
},
"buttons": [
{
"identifier": "check",
"text": "Check",
"action": {
"type": "OPEN_URL",
"item": "http://www.synerise.com"
}
},
{
"identifier": "view_similar",
"text": "View similar",
"action": {
"type": "OPEN_URL",
"item": "http://www.synerise.com"
}
}
],
"campaign": {
"hash_id": "196211cc-af48-4064-8860-aad986449322",
"variant_id": 3175648,
"type": "Mobile push",
"title": "SimplePush For Docs"
}
}
}
}
The example presents a simple push campaign with a main action, image, and two clickable buttons connected to actions. All user interactions are tracked by Synerise Android SDK.
The look of your push notifications may vary depending on Android versions.
The example presents a simple push campaign with a main action and two clickable buttons connected to actions. All user interactions are tracked by Synerise iOS SDK.
Simple push campaign presented on iOS 14
The look of your push notifications may vary depending on iOS versions.
## Single Media
---
This feature is available only in iOS SDK.
It is a simple push campaign with an image that can be seen after expanding the notification.
### Payload {id=single-media-payload}
The example presents a simple push campaign with a main action, single image, and two clickable buttons connected to actions. All user interactions are tracked by Synerise iOS SDK.
Simple push campaign presented on iOS 14
The look of your push notifications may vary depending on iOS versions.
## Image Carousel
---
This feature is available only in iOS SDK.
It is a simple push campaign with images that can be seen and swiped after expanding the notification.
### Payload {id=image-carousel-payload}
{
"aps":
{
"alert":
{
"title": "Complete your purchase",
"body": "Your basket contains Road Bike RS-500 with a discount for \"New Users\". Come and complete your purchase!"
},
"sound": "default",
"badge": "5",
"category": "synerise.notifications.category.carousel"
},
"issuer": "Synerise",
"message-type": "dynamic-content",
"content-type": "simple-push",
"content":
{
"campaign":
{
"variant_id": 3175648,
"hash_id": "196211cc-af48-4064-8860-aad986449322",
"type": "Simple Push",
"title": "Simple Push campaign for docs"
},
"notification":
{
"action":
{
"type": "OPEN_URL",
"item": "https://www.synerise.com"
}
},
"rich-media":
{
"type": "carousel",
"carousel":
{
"orientation": "PORTRAIT",
"items":
[
{
"caption": "Check!",
"subcaption": "Road Bike RS-500",
"image": "https://upload.snrcdn.net/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/7eba69de2d4dab3a9388b9d72abd91eb.png",
"url": "https://www.synerise.com"
},
{
"caption": "Check!",
"subcaption": "Road Bike RS-500",
"image": "https://upload.snrcdn.net/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/7eba69de2d4dab3a9388b9d72abd91eb.png",
"url": "https://www.synerise.com"
}
]
}
}
}
}
Click to see an example push with image carousel
The example presents a simple push campaign with a main action and carousel of images with connected actions. All user interactions are tracked by Synerise iOS SDK.
The look of your push notifications may vary depending on iOS versions.
Simple Push campaign presented on iOS 14
# iOS
## iOS delegates
### SyneriseDelegate {id=synerise-delegate}
A delegate to handle the SDK lifecycle events.
To set your object as delegate, you must use [this method](/developers/mobile-sdk/method-reference/ios/lifecycle#set-synerise-delegate).
If optional methods for handling URL and deeplink are not implemented, SDK has a default behavior.
##### snr_initialized() {id=synerise-delegate-initialized}
This method is called when the Synerise SDK is initialized.
```Swift
func snr_initialized() -> Void
```
```Objective-C
- (void)SNR_initialized
```
##### snr_initializationError(error: Error) {id=synerise-delegate-initialization-error}
This method is called when an error occurs while initializing the Synerise SDK.
| Parameter | Type | Description |
| --- | --- | --- |
| **error** | NSError | The error that occurred. |
##### snr_registerForPushNotificationsIsNeeded() {id=synerise-delegate-register-for-push-notifications-is-needed}
This method is called when Synerise needs registration for push notifications.
See [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/ios) for more details.
After invoking this method, you must invoke the [Client.registerForPush(registrationToken:mobilePushAgreement:success:failure:)](/developers/mobile-sdk/method-reference/ios/campaigns#register-for-push-notifications) method again.
This method is invoked when the **snr_registerForPushNotificationsIsNeeded(origin:)** method is not implemented.
##### snr_registerForPushNotificationsIsNeeded(origin: PushNotificationsRegistrationOrigin) {id=synerise-delegate-register-for-push-notifications-is-needed-by-origin}
This method is called when Synerise needs registration for push notifications.
See [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/ios) for more details.
After invoking this method, you must invoke the [Client.registerForPush(registrationToken:mobilePushAgreement:success:failure:)](/developers/mobile-sdk/method-reference/ios/campaigns#register-for-push-notifications) method again.
| Parameter | Type | Description |
| --- | --- | --- |
| **origin** | [PushNotificationsRegistrationOrigin](/developers/mobile-sdk/class-reference/ios/campaigns#pushnotificationsregistrationorigin) | Origin of the push notifications registration from the SDK. |
##### snr_handledAction(url: URL) {id=snr-handled-url-action}
This method is called when Synerise handles URL action from campaign activities.
This method is invoked when the **snr_handledAction(url:source:)** method is not implemented.
| Parameter | Type | Description |
| --- | --- | --- |
| **url** | NSURL | URL value from the action of the activity. |
##### snr_handledAction(url: URL, source: SyneriseSource) {id=snr-handled-url-action-advanced-with-parameters}
This method is called when Synerise handles URL action from campaign activities.
| Parameter | Type | Description |
| --- | --- | --- |
| **url** | NSURL | URL value from the action of the activity. |
| **activity** | [SyneriseActivity](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivity) | Identifies Synerise campaign activity ([SyneriseActivity](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivity)). |
| **completionHandler** | [SyneriseActivityAction](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivityaction) | A block/closure that should be invoked with [SyneriseActivityAction](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivityaction) parameters and a completion block to execute. |
##### snr_handledAction(deepLink: String) {id=snr-handled-deeplink-action}
This method is called when Synerise handles deeplink action from campaign activities.
This method is invoked when the **snr_handledAction(deepLink:source:)** method is not implemented.
| Parameter | Type | Description |
| --- | --- | --- |
| **deepLink** | String | Deep link value from the action of the activity. |
##### snr_handledAction(deepLink: String, source: SyneriseSource) {id=snr-handled-deeplink-action-advanced-with-parameters}
This method is called when Synerise handles deeplink action from campaign activities.
| Parameter | Type | Description |
| --- | --- | --- |
| **deeplink** | String | Deep link value from the action of the activity. |
| **source** | [SyneriseSource](/developers/mobile-sdk/class-reference/ios/campaigns#synerisesource) | Identifies Synerise campaign source ([SyneriseActivity](/developers/mobile-sdk/class-reference/ios/campaigns#synerisesource)). |
##### snr_handledAction(deepLink: String, activity: SyneriseActivity, completionHandler: SyneriseActivityCompletionHandler) {id=snr-handled-deeplink-action-advanced-with-parameters-deprecated}
This method is called when Synerise handles deeplink action from campaign activities.
| Parameter | Type | Description |
| --- | --- | --- |
| **deeplink** | String | Deep link value from the action of the activity. |
| **activity** | [SyneriseActivity](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivity) | Identifies Synerise campaign activity ([SyneriseActivity](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivity)). |
| **completionHandler** | [SyneriseActivityAction](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivityaction) | A block/closure that should be invoked with parameters: [SyneriseActivityAction](/developers/mobile-sdk/class-reference/ios/campaigns#syneriseactivityaction) and completion block to execute. |
---
---
### NotificationDelegate {id=notification-delegate}
A delegate to handle events from Synerise notifications.
See [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/ios#delegate-methods) for more details.
**NotificationDelegate** is available from 4.10.0 SDK version. All methods are optional.
To set your object as delegate, you must use [this method](/developers/mobile-sdk/method-reference/ios/campaigns#set-notification-delegate).
##### snr_notificationDidReceive(notificationInfo: NotificationInfo) {id=notification-delegate-notification-did-receive}
This method is called when a Synerise notification is received.
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/ios/campaigns#notificationinfo) | Object providing information about the notification. |
##### snr_notificationDidDismiss(notificationInfo: NotificationInfo) {id=notification-delegate-notification-did-dismiss}
This method is called when a Synerise notification is dismissed.
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/ios/campaigns#notificationinfo) | Object providing information about the notification. |
##### snr_notificationClicked(notificationInfo: NotificationInfo) {id=notification-delegate-notification-clicked}
This method is called when a Synerise notification is clicked.
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/ios/campaigns#notificationinfo) | Object providing information about the notification. |
##### snr_notificationClicked(notificationInfo: NotificationInfo, actionButton: String) {id=notification-delegate-notification-clicked-with-button}
This method is called when an action button is clicked in a Synerise notification.
| Parameter | Type | Description |
| --- | --- | --- |
| **notificationInfo** | [NotificationInfo](/developers/mobile-sdk/class-reference/ios/campaigns#notificationinfo) | Object providing information about the notification. |
| **actionButton** | String | Text on the clicked action button. |
---
---
### ClientStateDelegate {id=client-state-delegate}
A delegate to handle customer's sign-in state changes.
To set your object as delegate, you must use [this method](/developers/mobile-sdk/method-reference/ios/client-authentication#set-client-state-delegate).
##### snr_clientIsSignedIn() {id=client-state-delegate-client-is-signed-in}
This method is called when a customer signs in.
```Swift
func snr_clientIsSignedIn()
```
```Objective-C
- (void)SNR_clientIsSignedIn
```
##### snr_clientIsSignedOut(reason: ClientSessionEndReason) {id=client-state-delegate-client-is-signed-out}
This method is called when a customer signs out.
| Parameter | Type | Description |
| --- | --- | --- |
| **reason** | [ClientSessionEndReason](/developers/mobile-sdk/class-reference/ios/client#clientsessionendreason) | Specifies the reason for signing out. |
---
---
### InjectorInAppMessageDelegate {id=injector-in-app-message-delegate}
A delegate to handle the states of [in-app message](/developers/mobile-sdk/campaigns/in-app-message).
**InjectorInAppMessageDelegate** is available from 4.6.0 SDK version.
To set your object as delegate, you must use [this method](/developers/mobile-sdk/method-reference/ios/campaigns#set-in-app-message-delegate).
##### snr_shouldInAppMessageAppear(data: InAppMessageData) -> Bool {id=injector-in-app-message-delegate-should-in-app-message-appear}
This method is called after an in-app message is loaded and Synerise SDK asks for permission to show it.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
##### snr_inAppMessageDidAppear(data: InAppMessageData) {id=injector-in-app-message-delegate-in-app-message-did-appear}
This method is called after an in-app message appears.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
##### snr_inAppMessageDidDisappear(data: InAppMessageData) {id=injector-in-app-message-delegate-in-app-message-did-disappear}
This method is called after an in-app message disappears.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
##### snr_inAppMessageDidChangeSize(rect: CGRect) {id=injector-in-app-message-delegate-in-app-message-did-change-size}
This method is called when an in-app message changes its size.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
##### snr_inAppMessageContextIsNeeded(data: InAppMessageData) -> [AnyHashable: Any]? {id=injector-in-app-message-delegate-in-app-message-context-is-needed}
This method is called when an individual context (for example a profile ID, an item SKU) for an in-app message is needed.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
##### snr_inAppMessageHandledAction(data: InAppMessageData, deepLink: String) {id=injector-in-app-message-delegate-in-app-message-handled-deeplink-action}
This method is called when the [`SRInApp.openDeeplink(url)` method](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#open-deeplink) is used in an in-app message.
This method was renamed in 5.0.0 SDK version from `snr_inAppMessageHandledAction(data:deeplink:)`.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
| **deepLink** | String | Deep link value from the action of the activity. |
##### snr_inAppMessageHandledAction(data: InAppMessageData, url: URL) {id=injector-in-app-message-delegate-in-app-message-handled-url-action}
This method is called when the [`SRInApp.openUrl(url)` method](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#open-url) is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
| **url** | URL | URL value from the action of the activity. |
##### snr_inAppMessageHandledCustomAction(data: InAppMessageData, name: String, parameters: [AnyHashable: Any]) {id=injector-in-app-message-delegate-in-app-message-handled-custom-action}
This method is called when the [`SRInApp.handleCustomAction(name, params)` method](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#trigger-a-custom-action) is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | [InAppMessageData](/developers/mobile-sdk/class-reference/ios/campaigns#inappmessagedata) | Model representation of the in-app message. |
| **name** | String | Custom action name for identification. |
| **parameters** | [AnyHashable: Any] | Custom action parameters. |
---
---
### InjectorInlineInAppMessageDelegate {id=injector-inline-in-app-message-delegate}
A delegate to handle global events for [inline in-app messages](/developers/mobile-sdk/campaigns/in-app-message/inline-in-app).
To set your object as delegate, you must use [this method](/developers/mobile-sdk/method-reference/ios/campaigns#set-inline-in-app-message-delegate).
##### snr_inlineInAppMessageDidBecomeAvailable(view: InlineInAppView, data: InlineInAppMessageData) {id=injector-inline-in-app-message-delegate-did-become-available}
This method is called when the SDK creates a ready-to-display component after an event-based trigger for a placement with no existing host view.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
##### snr_inlineInAppMessageHandledAction(data: InlineInAppMessageData, url: URL) {id=injector-inline-in-app-message-delegate-handled-url-action}
This method is called when the `SRInApp.openUrl(url)` method is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **url** | URL | The URL to open. |
##### snr_inlineInAppMessageHandledAction(data: InlineInAppMessageData, deepLink: String) {id=injector-inline-in-app-message-delegate-handled-deeplink-action}
This method is called when the `SRInApp.openDeeplink(url)` method is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **data** | InlineInAppMessageData | Inline in-app message data. |
| **deepLink** | String | The deep link value. |
##### snr_inlineInAppMessageHandledCustomAction(data: InlineInAppMessageData, name: String, parameters: [AnyHashable: Any]) {id=injector-inline-in-app-message-delegate-handled-custom-action}
This method is called when the `SRInApp.handleCustomAction(name, params)` method is used in an in-app message.
| Parameter | Type | Description |
| --- | --- | --- |
| **view** | InlineInAppView | The inline in-app view. |
##### snr_inlineInAppViewDidLoad(view: InlineInAppView, data: InlineInAppMessageData) {id=inline-in-app-view-delegate-did-load}
This method is called when the inline in-app message content is loaded for the first time.
| Parameter | Type | Description |
| --- | --- | --- |
| **view** | InlineInAppView | The inline in-app view. |
| **error** | Error | The error that occurred. |
##### snr_inlineInAppViewChangeSizeIsNeeded(view: InlineInAppView, data: InlineInAppMessageData, size: InlineInAppSize) {id=inline-in-app-view-delegate-change-size-is-needed}
This method is called when the in-app message content requests a size change via the `SRInApp.setComponentSize(width, height)` JS method. The measured size is delivered as an `InlineInAppSize`, exposing it in physical pixels, points, and as a fraction of the device screen.
| Parameter | Type | Description |
| --- | --- | --- |
| **view** | InlineInAppView | The inline in-app view. |
| **data** | InlineInAppMessageData | Inline in-app message data. |
---
---
### TrackerDelegate {id=tracker-delegate}
A delegate to handle events from the Tracker.
To set your object as delegate, you must use [this method](/developers/mobile-sdk/method-reference/ios/tracking#set-tracker-delegate).
##### snr_locationUpdateRequired() {id=tracker-delegate-location-update-required}
This method is called when the Tracker module requests a location update.
---
---
### NotificationServiceExtensionDelegate {id=notification-service-extension-delegate}
A delegate to handle events from Notification Extension Service.
**NotificationServiceExtensionDelegate** is available from 4.0.0 SDK version.
To set your object as delegate, you must use this code in your Notification Service Extension.
##### notificationServiceExtensionDidFailDecryptionWithError(_: Error) {id=notification-service-extension-delegate-notification-service-extension-did-fail-decryption}
This method is called when the decryption process fails.
| Parameter | Type | Description |
| --- | --- | --- |
| **error** | NSError | The error that occurred |
##### notificationServiceExtensionDidFailProcessingWithError(_: Error) {id=notification-service-extension-delegate-notification-service-extension-did-fail-processing}
This method is called when the processing notification operation fails.
| Parameter | Type | Description |
| --- | --- | --- |
| **error** | NSError | The error that occurred |
---
---
### ContentWidgetDelegate {id=content-widget-delegate}
A delegate to handle [Content Widget](/developers/mobile-sdk/displaying-recommendations/content-widget) actions.
To set your object as delegate, you must use this code below.
| Parameter | Type | Description |
| --- | --- | --- |
| **widget** | [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) | The widget instance that called the delegate method. |
##### snr_widgetDidNotLoad(widget:ContentWidget error: Error) {id=content-widget-delegate-widget-did-not-load}
This method is called when an error occurs while loading a widget.
| Parameter | Type | Description |
| --- | --- | --- |
| **widget** | [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget) | The widget instance that called the delegate method. |
| **error** | NSError | The error that occurred. |
##### snr_widgetDidReceiveClickAction(widget:ContentWidget model: BaseModel) {id=content-widget-delegate-widget-did-receive-click-action}
This method is called when the customer clicks a widget’s item.
| Parameter | Type | Description |
| --- | --- | --- |
| **widget** | [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget) | The widget instance that called the delegate method. |
| **model** | BaseModel | The model's object that was clicked. |
##### snr_widgetIsLoading(widget: ContentWidget isLoading: Bool) {id=content-widget-delegate-widget-is-loading}
This method is called when the widget’s loading state changes.
**Properties:**
| Property | Type | Description |
| --- | --- | --- |
| **sdk** | GeneralSettings | [General settings](/developers/mobile-sdk/settings#general) - This group contains options related to the general functioning of mobile SDK |
| **notifications** | NotificationsSettings | [Notifications settings](/developers/mobile-sdk/settings#notifications) - This group contains options related to push notifications |
| **tracker** | TrackerSettings | [Tracker](/developers/mobile-sdk/settings#tracker) - This group contains options related to tracking the customer activities in a mobile application |
| **inAppMessaging** | InAppMessagingSettings | [In-app messaging](/developers/mobile-sdk/settings#in-app-messaging) - This group contains options related to the [in-app messages](/docs/campaign/in-app-messages) feature |
| **injector** | InjectorSettings | [Injector](/developers/mobile-sdk/settings#injector) - This group contains options related to displaying [campaigns](/docs/campaign/Mobile) |
**Note:**
Learn more about settings [here](/developers/mobile-sdk/settings)
---
---
### Notifications
**Declared In:**
lib/modules/notifications/notifications_impl.dart
**Declaration:**
class NotificationsImpl
**Listeners:**
[NotificationsListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener)
**Methods:**
This method passes the Firebase Token to Synerise for notifications.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#register-for-push-notifications)
---
This method handles a notification payload and starts activity.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#handle-synerise-push-notification)
---
This method handles a notification payload with a user interaction and starts activity.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#handle-synerise-push-notification-click)
---
This method verifies if a notification was sent by Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-from-synerise)
---
This method verifies if a notification’s sender is Synerise and if the notification is a Simple Push campaign
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-simple-push-campaign)
---
This method verifies if a notification’s sender is Synerise and if the notification is a Banner campaign.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-banner-campaign) - **REMOVED in version 2.0.0**
---
This method verifies if a notification's sender is Synerise and if the notification is a Silent Command.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-silent-command)
---
This method verifies if a notification's sender is Synerise and if the notification is a Silent SDK Command.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#register-customer-account)
---
This method confirms a customer account with the confirmation token.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#confirm-customer-account-activation)
---
This method activates a customer with email.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#request-customer-account-activation)
---
This method requests a customer's account registration process with the PIN code.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#request-customer-account-activation-by-pin)
---
This method confirms a customer's account registration process with the PIN code.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#confirm-customer-account-activation-by-pin)
---
This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#sign-in-a-customer)
---
This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#sign-in-a-customer-conditionally)
---
This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#authenticate-customer-by-identityprovider)
---
This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#authenticate-customer-conditionally-by-identityprovider)
---
This method authenticates a customer with Simple Profile Authentication.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#authenticate-customer-via-simple-profile-authentication)
---
This method checks if a customer is signed in (via Synerise Authentication - RaaS, OAuth, Facebook, Apple).
Future<bool> isSignedIn() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple)
---
This method checks if a customer is signed in (via Simple Profile Authentication).
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication)
---
This method signs out a customer out.
Future<void> signOut() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#sign-out-a-customer)
---
This method signs out a customer out with a chosen mode and Determines if the method should sign out all devices
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#sign-out-customer-with-mode-or-from-all-devices)
---
This method refreshes the customer’s current token.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#refresh-customer-token)
---
This method retrieves the customer’s current, active token.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#retrieve-customer-token)
---
This method retrieves the customer’s current UUID.
Future<String> getUUID() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#get-current-customer-uuid)
---
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
Future<void> regenerateUUID() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#regenerate-customer)
---
This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#regenerate-customer-with-identifier)
---
This method destroys the session completely.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#destroy-current-session)
---
This method gets a customer’s account information.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#get-customer-account-information)
---
This method updates a customer’s account’s basic information (without identification data: uuid, customId, email).
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#update-customer-account-basic-information)
---
This method updates a customer’s account information.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#update-customer-account-information)
---
This method requests a customer’s password reset with email.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#request-password-reset-for-customer-account)
---
This method confirm a customer’s password reset with the new password and token provided by password reset request.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#confirm-password-reset-for-customer-account)
---
This method changes a customer’s password.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#change-customers-account-password)
---
This method requests a customer's email change.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#request-email-change-for-customer-account)
---
This method confirms an email change.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#confirm-email-change-for-customer-account)
---
Requests a customer's phone update. A confirmation code is sent to the phone number.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#request-phone-update-on-customer-account)
---
This method confirms a phone number update. This action requires the new phone number and confirmation code as parameters.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#confirm-phone-update-on-customer-account)
---
This method deletes a customer's account.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/tracking#set-custom-identifier-for-events)
---
This method sets a custom email in the parameters of every event.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/tracking#set-custom-email-for-events)
---
This method sends an event.
Future<void> send(Event event) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/tracking#send-event)
---
This method forces sending the events from the queue to the server.
Future<void> flush() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/tracking#flush-events-from-tracker)
---
---
### Injector
**Declared In:**
lib/modules/injector/injector_impl.dart
**Inherits From:**
[BaseModule](/developers/mobile-sdk/class-reference/flutter/modules#basemodule)
**Declaration:**
class InjectorImpl extends BaseModule
**Listeners:**
[InjectorListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-listener)
[InjectorInAppMessageListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-in-app-message-listener)
**Methods:**
Closes an in-app message and sends an `inApp.discard` event.
Usage examples:
- Closing a top bar or bottom bar when the user taps outside the in-app area.
- Automatically dismissing messages when navigating away from a screen.
- Controlling in-app visibility based on app logic for a smoother user experience.
void closeInAppMessage(String campaignHash)
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#close-in-app-message)
---
This method fetches a walkthrough.
void getWalkthrough() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#get-walkthrough) - **REMOVED in version 2.0.0**
---
This method shows a walkthrough when it is loaded.
void showWalkthrough() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#show-walkthrough)- **REMOVED in version 2.0.0**
---
This method checks if a walkthrough is loaded.
Future<bool> isWalkthroughLoaded() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-walkthrough-is-loaded)- **REMOVED in version 2.0.0**
---
This method checks if the walkthrough is unique compared to the previous one.
Future<bool> isLoadedWalkthroughUnique() async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-is-loaded-walkthrough-unique)- **REMOVED in version 2.0.0**
---
---
### Promotions
The module for handling promotions and vouchers from Synerise SDK.
**Declared In:**
lib/modules/promotions/promotions_impl.dart
**Related To:**
[PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse)
[Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion)
[AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse)
[VoucherCodesResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#vouchercodesresponse)
**Inherits From:**
[Module](/developers/mobile-sdk/class-reference/flutter/modules#basemodule)
**Declaration:**
class PromotionsImpl extends BaseModule
**Methods:**
This method retrieves all available promotions that are defined for a customer.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-all-promotions-of-a-customer)
---
This method retrieves promotions that match the parameters defined in an API query.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-promotions-with-query-parameters)
---
This method retrieves the promotion with the specified UUID.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-promotion-by-uuid)
---
This method retrieves the promotion with the specified code.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-promotion-by-code)
---
This method activates the promotion with the specified UUID.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#activate-promotion-by-uuid)
---
This method activates the promotion with the specified code.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#activate-promotion-by-code)
---
This method activates promotions with a code or with UUID in a batch.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#activate-promotions-in-a-batch)
---
This method deactivates the promotion with the specified UUID.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#deactivate-promotion-by-uuid)
---
This method deactivates the promotion with the specified code.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#deactivate-promotion-by-code)
---
This method deactivates promotions with a code or with UUID in a batch.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#deactivate-promotions-in-a-batch)
---
This method retrieves an assigned voucher code or assigns a voucher from a pool identified by UUID to the profile.
When the voucher is assigned for the first time, a [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-or-assign-voucher-from-pool)
---
This method assigns a voucher from a pool identified by UUID to the profile.
A [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#assign-voucher-code-from-pool)
---
This method retrieves voucher codes for a customer.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-voucher-codes-assigned-to-customer)
---
---
### Content
The module for handling content from Synerise backend such as documents, recommendations, and so on.
**Declared In:**
lib/modules/content/content_impl.dart
**Related To:**
[DocumentsApiQuery](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#documentsapiquery)
[Document](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#document)
[RecommendationResponse](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationresponse)
[RecommendationOptions](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationoptions)
[Recommendation](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendation)
[ScreenView](/developers/mobile-sdk/class-reference/flutter/miscellaneous#screenview)
[ScreenViewAudienceInfo](/developers/mobile-sdk/class-reference/flutter/miscellaneous#screenviewaudienceinfo)
[ScreenViewApiQuery](/developers/mobile-sdk/class-reference/flutter/miscellaneous#screenviewapiquery)
[BrickworksApiQuery](/developers/mobile-sdk/class-reference/flutter/miscellaneous#brickworksapiquery)
**Inherits From:**
[BaseModule](/developers/mobile-sdk/class-reference/flutter/modules#basemodule)
**Declaration:**
class ContentImpl extends BaseModule
**Methods:**
This method generates the document assigned to a slug.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#get-document) - **REMOVED in version 2.0.0 **
---
This method generates the document that is defined for the provided slug.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#generate-document)
---
This method generates the document that is defined for parameters provided in the query object.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#generate-document-with-query-parameters)
---
This method generates documents that are defined for parameters provided in the query object.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#get-documents) - **REMOVED in version 2.0.0 **
---
This method generates recommendations that are defined for the options provided. The recommendations are generated by using a document with an insert.
For instructions, see ["Displaying AI recommendations > With documents and screen views"](/developers/mobile-sdk/displaying-recommendations/documents).
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#get-recommendations) - **REMOVED in version 2.0.0 **
---
This method generates recommendations that are defined for the options provided. The recommendations are generated by using a document with an insert.
For instructions, see ["Displaying AI recommendations > With documents and screen views"](/developers/mobile-sdk/displaying-recommendations/documents).
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#get-recommendations-v2)
---
This method generates the customer's highest-priority screen view campaign.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#get-screen-view) - **REMOVED in version 2.0.0 **
---
This method generates a customer's highest-priority screen view campaign from the feed with the provided feed slug.
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#generate-screen-view)
---
This method generates customer's highest-priority screen view campaign that is defined for parameters provided in the query object.