# Synerise > Synerise is an AI-driven behavioral data and customer data platform (CDP). > It enables businesses to collect, unify, and act on customer data across web, mobile, and offline channels. ## Overview Synerise provides: - **Customer data unification** — Merges behavioral data from all channels into unified customer profiles - **AI-powered personalization** — Recommendations, search, predictions (churn, LTV, purchase likelihood) - **Marketing automation** — Workflow builder with event-triggered scenarios - **Omnichannel campaigns** — Email, SMS, mobile push, web push, WhatsApp, in-app, dynamic content - **Loyalty programs** — Points, vouchers, promotions, gamification, tiers - **Real-time analytics** — Dashboards, segmentations, funnels, trends, aggregates ## API Servers | Environment | Base URL | |---|---| | Microsoft Azure EU | `https://api.synerise.com` | | Microsoft Azure USA | `https://api.azu.synerise.com` | | Google Cloud Platform | `https://api.geb.synerise.com` | ## Authentication Synerise uses three authentication methods: ### JWT (Bearer Token) — Primary method Include in header: `Authorization: Bearer {JWT}` - Generated by login endpoints - Uses RS512 algorithm - Public key: `https://api.synerise.com/v4/public.pem` - Refresh before expiry via `auth/refresh` endpoints ### Tracker Key — For web/recommendation requests Include as query parameter: `?token={tracker_key}` - Same key as used in website tracking code - Used for recommendations, search, and tracker-scoped endpoints ### Basic Auth — For server-to-server Include in header: `Authorization: Basic base64({workspaceGuid}:{apiKey})` - Must be enabled per API key in workspace settings - No token expiration, no refresh needed ## Authorization Flows ### Profile (Client) login — for end users Token validity: 60 minutes (default) ``` POST /sauth/v3/auth/login/client Body: { "apiKey": "...", "identityProvider": "SYNERISE", "password": "...", "uuid": "..." } → Returns JWT ``` Anonymous login (no credentials): ``` POST /sauth/v3/auth/login/client/anonymous Body: { "apiKey": "...", "deviceId": "...", "uuid": "..." } → Returns JWT ``` ### Workspace login — for server-to-server / M2M Token validity: 60 minutes (default) ``` POST /uauth/v2/auth/login/profile Body: { "apiKey": "01234abc-1234-5678-9abc-def012345678" } → Returns JWT ``` ### User login — for Synerise portal users Multi-step: login → MFA → select workspace ``` POST /uauth/auth/login/user Body: { "username": "user@company.com", "password": "..." } → Returns JWT + mfaMethods POST /uauth/auth/login/user/profile/{workspaceGuid} Header: Authorization: Bearer {JWT from step 1} → Returns workspace-scoped JWT ``` ## API Consumer Scopes Each endpoint specifies which consumer types can call it: | Scope | Description | |---|---| | Workspace (Business Profile) | Server-to-server integrations using workspace API keys | | Synerise User | Portal users logged into the Synerise application | | Profile (Client) | End-user/customer authenticated via profile login | | Anonymous Profile | Unauthenticated end-user with UUID only | | Web SDK Tracker | Requests authenticated via tracker key | | Organization | Organization-level access (contact support) | ## Permission System Endpoints require specific permissions assigned to API keys or user roles. **Permission format:** `{SERVICE}_{RESOURCE}_{ACTION}` (e.g., `API_CUSTOM_EVENTS_CREATE`, `ANALYTICS_BACKEND_AGGREGATES_READ`) **Permission groups** map to the Synerise access management UI: - `analytics`, `analytics_aggregates`, `analytics_trends` - `assets_catalogs`, `assets_search`, `assets_schema_builder`, `assets_brickworks` - `automation_2_journeys` - `campaigns_promotions`, `campaigns_recommendations`, `campaigns_personalised_promotions` - `client_detail`, `client_management`, `client_activities`, `client_tags` - `settings_users`, `settings_customers_iam`, `settings_export` - `templates` Special values: - `NO_TOKEN` — No authentication required - `ROLE_USER` / `ROLE_PREAUTHORIZED_USER` — Role-based check (portal users) ## Key Concepts | Term | Definition | |---|---| | **Profile** | End-user/customer record. Called "client" in API. Has a UUID. | | **UUID** | Unique identifier per profile. Stored in cookies (web) or SDK (mobile). | | **Event** | Recorded action with `action` name and `params`, attributed to a profile. | | **Workspace** | Organizational container for a company's data and campaigns. Formerly "Business Profile". | | **Catalog** | Collection of item/product data for recommendations, search, promotions. | | **Document** | Structured data object stored in Synerise (Schema Builder). | | **IQL** | Items Query Language — filtering language for search/recommendation requests. | | **Jinjava** | Templating engine (Jinja2-based) for personalizing content across channels. | | **Aggregate** | Computed metric from event/profile data for segmentation and personalization. | | **Expression** | Formula-based calculation on profile/event data for analytics. | | **Voucher Pool** | Collection of unique voucher codes assignable to profiles. | | **Dynamic Content** | Personalized content displayed on websites/apps via campaigns. | ## Platform Modules | Module | Purpose | |---|---| | **AI Hub** | Recommendations, AI search, predictions (churn, LTV, propensity) | | **Automation Hub** | Workflow/scenario builder for automated processes | | **Behavioral Data Hub** | CRM, profile management | | **Data Modeling Hub** | Events, catalogs, documents, schema builder | | **Decision Hub** | Analytics dashboards, metrics, segmentations | | **Experience Hub** | Campaign management (email, SMS, push, dynamic content) | | **Settings** | Workspace configuration, IAM, API keys, tracking codes | ## SDKs - **Web SDK** — JavaScript tracking code for websites. Handles UUID management, event tracking, dynamic content. - **Android SDK** — Native Android. Auto event tracking, push notifications, in-app messages, recommendations. - **iOS SDK** — Native iOS. Same capabilities as Android. - **React Native SDK** — Cross-platform. Manual event triggers required. - **Flutter SDK** — Cross-platform with Huawei support. ## Common Request Patterns ### Required Headers - `Authorization: Bearer {JWT}` — on most endpoints - `Content-Type: application/json` — for request bodies - `Api-Version: 4.4` — required on `/v4/*` endpoints ### Pagination Two patterns: 1. **Page-based:** `?page=1&limit=100` (page is 1-indexed, max limit often 1000) 2. **Cursor-based:** `?pageToken={token}` — next/previous tokens returned in response ### Profile Identifiers Profiles can be identified by: `id` (numeric), `uuid`, `email`, or `custom_identify`. Use path parameter `identifierType` to specify which one. ### Error Response Format ```json { "error": "Bad Request", "status": 400, "message": "Description of the problem", "path": "/path_of_the_endpoint", "errors": [ { "code": 120, "field": "exampleField", "message": "details" } ] } ``` Common status codes: 200 (success), 202 (accepted/async), 400 (validation), 401 (unauthorized), 403 (forbidden), 404 (not found), 429 (rate limited). ### Rate Limiting HTTP 429 is returned when rate limits are exceeded. No specific limits are published — use batch endpoints where available and implement exponential backoff. ## Best Practices - **API keys:** Keep secret. Workspace keys for server-to-server ONLY. Never embed in client apps. - **Authentication:** Refresh tokens BEFORE expiry. Include space between "Bearer" and token. - **Headers:** Always include `Api-Version: 4.4` for v4 endpoints. Watch for `X-API-DEPRECATED` response header. - **HTTPS:** All communication must use TLS 1.2+. - **Rate limiting:** Implement exponential backoff. Use batch endpoints where available. - **Profile identification:** Default unique identifier is email (configurable to customId). - **Events:** Use `POST /v4/events/batch` for sending multiple events efficiently. - **Web SDK CSP:** Allowlist `*.synerise.com`, `*.snrcdn.net`, `*.snrbox.com`, `*.snrlink-page.com`. - **Deprecation:** Check `X-API-DEPRECATED` header. Migrate away from deprecated endpoints promptly. ## API Categories (730 endpoints) Authorization, Data Management (Events, AI Events), Profile Management, Analytics (Aggregates, Funnels, Segmentations, Trends, Metrics, Reports, Expressions, Histograms, Sankeys), AI Recommendations (Campaigns, Configuration), AI Search (Search, Visual Search, Listing, Suggestions, Query Rules, Synonyms, Query Classification), Loyalty (Promotions, Vouchers, Handbills, Points, Settings, Locks), Asset Management (Catalogs, Documents, Screen Views, Templates, Uploader), Campaigns (Workflows), Brickworks (Schemas, Records, External Sources, Content Generation), Settings (Access Control, User Management), Organizations (Consumption). ## Documentation - [toc.json](/api/toc.json) — Machine-readable table of contents mirroring the live site navigation - [llms-full.txt](/api/llms-full.txt) — Complete documentation as plain text - [Full Markdown](/api/docs/llms-full) — All docs as Markdown - [Single article](/api/docs/{slug}/markdown) — Individual article as Markdown - [OpenAPI YAML](/api/openapi.yaml) — API specification - [OpenAPI JSON](/api/openapi.json) — Enriched spec with code samples and permissions - [API as Markdown](/api/api-reference/markdown) — All endpoints as Markdown --- # Full Documentation (1205 articles) --- ## Ai 7 Days ### AI Demo # The 7-day AI Launch Plan

Put the power of AI-driven search, recommendations, and personalization to work in just one week

In the world of ecommerce, every competitive advantage counts. At Synerise, we’re on the leading edge of innovation for the most powerful tool there is for online enterprises—Artificial Intelligence. AI is a key component of the digital transformation of any business, but has special relevance and benefits for ecommerce. The oceans of data generated every day—every second—by consumers as they move through both online and offline spaces is too much for conventional computing methods to process, analyze and turn into business insights. Only AI-powered algorithms can dive in and separate the signal from the noise, the useful data from the distractions, and deliver real visibility into consumer preferences. With that information, you can then craft a hyper-personalized customer experience at a scale previously impossible. AI can make sure that every visitor to your site and every returning customer has their own customized path and content, based on information about their behavioral and purchase histories. This kind of tailored marketing message is the shortcut to accelerating progress in the purchase funnel, driving conversions and building customer loyalty. In short, it’s the path to success. **Synerise is now offering a simple and easy way to integrate our solutions into your ecommerce operation and see results in just seven days.** A week from now, your online sales can be transformed into a highly efficient process that delivers exactly what customers are looking for. Your search results, product recommendations and content can be optimized in a way that only algorithms powered by AI can deliver. A quick implementation and configuration is all that’s separating your online store from joining the businesses that are already using next-generation solutions for delivering the best customer value. Ready to learn more? Here’s the simple path you can take to start using the power of AI. AI objectives ## Day 1 - Implementing a product feed Provide data about your products and customer behavior: prepare a product feed, check og:tags on the website, implement the tracking code and transactional events. Start with building the foundation with information about your products and setting up the proper events. [Read more about product feed integration](/use-cases/import-product-feed-to-catalog) ## Day 2 - Training the first models On the second day, we can start training the first models: similar and visual recommendations based on the product feed. Recognize customers by tagging forms, configure email, sms and web push campaigns to prepare the foundations of the omnichannel experience. AI algorithms start learning, your customer base is indexed and your automated communication channels are set up and ready for future campaigns using AI. - [Read more about data requirements](/docs/ai-hub/recommendations-v2/introduction-to-recommendation-campaigns#requirements) - [Read more about form tagging](/developers/web/event-tracking) Training first AI models ## Day 3 - Implementing the first recommendations Implement first recommendations on the product page and import historical transaction data. AI is already at work on your site and brings the first effects but also continues to learn from customer histories. [Read more about importing your historical transaction](/docs/crm/crm-import) ## Day 4 - Introducing AI search Train cart and recommendation models, deploy product sets and AI search. AI goes further, optimizing content displays and recommendations, helping clients to make better decisions and save time. - [Read more about search implementation](/docs/ai-hub/ai-search) - [Read more about cross-sell recommendations](/docs/ai-hub/recommendations-v2/recommendation-types#cross-sell-and-cart-recommendations) - [Read more about cart recommendations](/docs/ai-hub/recommendations-v2/recommendation-types#cross-sell-and-cart-recommendations) AI Search Settings ## Day 5 - Training more models Train more models and refine recommendations. Now you’re delivering highly precise recommendations and product suggestions. This is the time to optimize ongoing campaigns, implement cart recommendations and new campaigns. - [Read more about recommendation statistics](/docs/ai-hub/recommendations-v2/recommendation-statistics) - [Read more about top products recommendations](/docs/ai-hub/recommendations-v2/recommendation-types#top-items) ## Day 6 - Implementing AI in email campaigns Send automated emails with recommendations and focus on automated messages triggered by specific customer actions. Your system knows which customers are more likely to respond to certain offers through automated campaigns and you can reach customers with recommendations even when they’re not on your site. [Read more about e-mail campaigns](/docs/campaign/e-mail) ## Day 7 - Refining personalized recommendations Perfect personalized recommendations, add personalization to AI Search, apply AI to remarketing. Now every aspect of your ecommerce is powered by fully trained AI algorithms, you’re delivering highly precise recommendations and product suggestions based on customer behavioral data, which further boosts the accuracy of the AI search engine and remarketing campaigns. [Read more about personalized recommendations](/docs/ai-hub/recommendations-v2/recommendation-types#personalized) ## Analyze the results We can’t skip the role of analytics in this 7-day plan. Integration with the AI module and campaign implementation must be supported by an analysis of the effects they bring. This is why it is important to check the results and metrics of individual campaigns, things like impressions, clicks, the quantity of the products bought from recommendations and the number of transactions made. For the best analysis of the effects of the campaign, it is best to use control groups. Analyze the results ## What’s next? When your Synerise solution is operating at full efficiency, there are a number of use cases that can be deployed to enhance your conversions and revenue. - When a word is misspelled in a search bar, AI can make informed guesses about what the user had in mind and show display the appropriate products. - Don’t go yet! Automated exited pop-ups can display personalized products based on customer interests. - Your automated email campaigns can be boosted by recommendations. Send complementary products related to recently-purchased products, or similar to last-seen items. - Save abandoned carts with reminders and complementary products based on items placed in carts. - Create dedicated landing pages with personalized offers and send them to customers who left your website without making a purchase. - Set up product comparisons using AI to help customers make the right choice for them. - Activate recommendations for visually similar products. --- ## Developers ### 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:**
```Java public class InitializationConfig ```
```Kotlin class InitializationConfig ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **salt** | String | no | - | [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) salt |
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. --- --- ### SDK Lifecycle ## InitializationConfig **Declared In:** Headers/SNRInitializationConfig.h **Inherits from:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration**:
```Swift class InitializationConfig: NSObject ```
```Objective-C @interface SNRInitializationConfig: NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **requestValidationSalt** | String | yes | [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) salt | --- --- ## Settings **Declared In:** Headers/SNRSettings.h **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class Settings: NSObject ```
```Objective-C @interface SNRSettings : NSObject ```
**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 } ```
```Objective-C typedef NS_ENUM(NSInteger, SNRTrackerAutoTrackMode) { SNRTrackerAutoTrackModePlain, SNRTrackerAutoTrackModeFine, SNRTrackerAutoTrackModeDisabled } ```
### Introduction to Synerise API # Introduction Synerise RESTful APIs are a quick and simple way to integrate your existing or future systems with Synerise or benefit from functionalities available within your applications. ## SSL Synerise API requires connectivity over HTTPS (SSL) and supports the TLS 1.2 protocol (support for newer versions to be added in the near future).
On older configurations, an update may be required, including the update of CA certificate repository.
## Servers When working with the Synerise API, make sure you're using the correct base URL, depending on the cloud where your workspace is hosted: - `https://api.synerise.com` for Microsoft Azure EU environment - `https://api.azu.synerise.com` for Microsoft Azure USA environment - `https://api.geb.synerise.com` for Google Cloud Platform environment ## API Versioning Synerise is built with CI/CD (Continuous Integration/Continuous Delivery) principles in mind and we often deploy changes multiple times a day. We do not have fixed release cycles, but instead features are brought live for you as soon as they are ready. Such an approach allows us to deliver features, changes, and bug fixes very fast and keeping track of them is possible thanks to our [live changelog](https://changelog.synerise.com). Thus, as part of our API Contract, we want to ensure that within an API Version: 1. No fields will be deleted or changed in a non-backwards compatible way. 2. We make changes that are additional, such as new fields, new methods, new error messages/codes, or mandatory parameters becoming optional (but, generally speaking, not causing compatibility issues). Whenever we may need to roll out elements that are not backwards compatible, we will do that as a new API version for the given functional area, so an endpoint that was version 1 is now also available as version 2, with the previous one still being operational. ## Deprecation Endpoints that already have newer versions send `X-API-DEPRECATED` in the response Headers, giving you time to switch to the new endpoint. Deprecated API endpoints are also marked visually in the API reference pages. ### Introduction to API Authorization Synerise uses a number of authentication methods in the API. The available methods depend on the endpoint and the consumer. JSON Web Tokens (JWTs) are the most common. ## API consumer types Synerise defines different types of API consumers that can receive their own authorization tokens. Each method within our API Reference indicates which types of API Consumers can use them. ### Profile This is the end user of your website or application - the one who browses pages, purchases items, and so on. In the portal, this is called a profile. In our APIs, the profile is usually called a "client" in endpoint URLs and JSON entity names. The profile can register and maintain their own account with following methods: - Synerise RaaS - Facebook authentication - OAuth-based authorization - Sign in with Apple They can also perform other customer actions, such as redeeming vouchers.
The profile can access and modify only its own data.
### Workspace The workspace is assigned to a particular company as explained [in these articles](/docs/settings/business-profile). This consumer can use methods that, for example, create profiles, record profile actions, or manage promotions. When working with the API, you will usually authorize as the workspace. ### User This is the user who logs in to [the Synerise Portal](https://app.synerise.com/). A User is an actual person who performs actions in the Synerise Portal interface, but many of those actions can be automated using the API. Users have access to *Workspaces* or *Organizations* and different levels of permissions within those.
Workspaces used to be called _business profiles_. Many endpoints still use this nomenclature due to backwards compatibility.
## Access control ### Access permissions Each endpoint requires a permission to access it. These permissions can be defined granularly for users, roles, or API keys, so you have strict control over access to each endpoint. You can also assign groups of permissions. To find which permission is needed for an endpoint, read the endpoint's description in the [API Reference](https://developers.synerise.com/). For more information on managing permissions, read [this article](/docs/settings/identity-access-management/permissions). ### IP allowlisting You can limit access to Synerise to certain IP addresses. For more information, see [IP access control](/developers/api/api-authorization/ip-access). ## JSON Web Tokens Authentication with [JSON Web Tokens (JWTs)](https://jwt.io/) is available in most of the API endpoints. The token is generated by one of the `/auth/login/` endpoints depending on the **Consumer Type**, as described further in this article. You need to include the received token in the `Authorization` header of your requests, with a `Bearer` prefix. See this simplified example of a call: ``` curl -X GET https://{SYNERISE_API_BASE_PATH}/v4/clients \ -H 'Accept: application/json' \ -H 'Api-Version: 4.4' \ -H 'Authorization: Bearer eyJhbGciOiJSzZXIiL...UFBQUFBSXVPQlFBcHUwd05BZ0FBQUE9PSIsIm5tZSI' \ -H 'Content-Type: application/json' ```
Remember to include a space between `Bearer` and the token.
If you are unauthorized or are using an invalid/expired token, the API returns `HTTP 401 Unauthorized` or `HTTP 403 Forbidden`. ### Token format Our JWT use the `RS512` hashing algorithm and their payload contains: - customer/user/profile identification. - the origin of the token (Synerise, Facebook, Oauth, Apple). - expiration time of the token. - **user tokens only:** information about the currently selected workspace and user permissions. ### Token lifetime By default, the token is valid for **one week**. You can request a refreshed token for the session by using the `/auth/refresh` endpoint **before** the current token expires. You can also verify your JWT signature by using the public key: - [Workspaces hosted on Microsoft Azure EU server](https://api.synerise.com/v4/public.pem) - [Workspaces hosted on Microsoft Azure USA server](https://api.azu.synerise.com/v4/public.pem) - [Workspaces hosted on Google Cloud Platform](https://api.geb.synerise.com/v4/public.pem) ### 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). ### Getting started
We recommend creating the tracking code with the creator, as described in this article. However, if you're looking for the legacy method or need to edit an existing tracking code without the creator, see [Advanced tracking code settings](/developers/web/advanced-tracking-code).
## What is Synerise Web SDK Synerise Web SDK (Software Development Kit) is a JavaScript library that allows you to integrate Synerise on your website. This library (SDK) is responsible for data exchange between Synerise and the website into which it is implemented. Thanks to the SDK, we not only send data ([events](/docs/assets/events)) but also download data to show [dynamic content campaigns](/docs/campaign/dynamiccontent). The SDK is also responsible for customer identification, which means that SDK assigns a UUID for anonymous users on your website, if they already have a UUID, it recognizes them. If the visitor's User Agent matches any of those used by Googlebot, the SDK doesn't initialize. This means that Googlebot's page crawling visits don't generate any Dynamic Content, events, or Profiles. ### How to implement Synerise Web SDK? By [adding a tracking code into the source code of your website](#creating-a-tracking-code). ### What can the tracking code do? The tracking code's permissions are designed to be restrictive, so the code can be included in the source code of your website without risk to your infrastructure or the personal data of your visitors. It enables the following features: - You can display [Dynamic Content](/docs/campaign/dynamiccontent) on the page. Profile data, such as name or date of birth, can be added to the Dynamic Content with Jinjava inserts. Only the data of the profile whose UUID is stored in the cookies can be used. - You can send events. By default, [page.visit](/docs/assets/events/event-reference/web-and-app#pagevisit) events are tracked automatically. Other events can be sent with [declarative tracking](/developers/web/event-tracking#declarative-tracking-custom-events). - You can [identify users on your website](/developers/web/user-identification). When a visitor enters your site for the first time or after clearing their cookies, the SDK generates a random UUID and an anonymous profile is created. If that user becomes recognized (for example, by sending a login form), it may be [merged with an existing recognized profile](/docs/crm/profile-merge). - Events sent by SDK requests can modify profiles if you allow it. To edit the list of events which can modify profile data, see [Event authentication settings](/docs/assets/events/event-settings). - The tracker key (part of the tracking code) can be used to authenticate customer-oriented requests to the [Recommendations](/developers/api/recommendations) and [Search](https://developers.synerise.com/AISearch/) APIs. This can be used to generate personalized recommendation and search results. - You can use [all methods provided by Synerise SDK](/developers/web/methods-reference). - You can also: - [track cart status](/developers/web/cart). - [send form data](/developers/web/tracking-form-data/tracking-form-data-sdk).
By default, sending form data with the SDK requires [JWT authentication](/developers/web/jwt-auth). If you want to change that, follow the instructions in ["Sending form data with JS SDK"](/developers/web/tracking-form-data/tracking-form-data-sdk).
- [send transaction events](/developers/web/transactions-sdk). - [send the status of newsletter agreements](/developers/web/newsletter-agreements#javascript-sdk). The code **can't be used to**: - Access the details or settings of your workspace. - Authenticate API requests, except for recommendation and search results. - Explicitly request personal data of customers. The SDK identifies the visitor by their UUID from the cookies. It can't access the visitor's Synerise profile directly (personal data from the profile can be displayed with Dynamic Content) or access the data of other profiles. ## Prerequisites - If you use a custom tracking domain, prepare DNS entries for it. See [Custom tracking domain](/developers/web/first-party-tracking). - Add the following domains to the allowlist in your Content Security Policy: - `*.synerise.com` - `*.snrcdn.net` - `*.snrbox.com` - If you use a custom tracking domain, you can skip this entry. - `*.snrlink-page.com` - `fcm.googleapis.com` - This is only required for Web Push. ## Creating a tracking code --- 1. Go to Settings icon **Settings > Tracking Codes > Add tracking code**. **Result**: The tracking code creation form opens.
Tracking code creation form
Tracking code creation form
2. In **Tracking code name**, enter the name. It's used for identifying the code on the list of tracking codes. 3. In **Domain name**, enter the domain where the code will be used. This setting **doesn't affect tracking or cookies** - its purpose is to identify the code. 4. Select the type of page where you want to implement the code.
If you choose **Single Page App**, you will need to manually implement page visit events and dynamic content after you include the tracking code in the page. This is described further in the article.
5. If you use Google data layer, enable the toggle and select the version. If your site uses multiple versions, you can only choose one for use with Synerise tracking. 6. If you use a custom tracking domain, enable **Custom domain tracking** and enter the domain in the field that appears.
Using a custom tracking domain requires additional configuration. See [Custom tracking domain](/developers/web/first-party-tracking).
7. This completes the basic settings. - If you don't need additional settings, continue to [Adding the tracking code to your site](#adding-the-tracking-code-to-your-site). - If you need additional settings, continue to [Additional options](#additional-options). ### Additional options
If you want to manually add these options to an existing tracking code, see [Advanced tracking code settings](/developers/web/advanced-tracking-code).
1. Expand **Additional options**. 2. Configure the settings that you need: #### Custom cookie expiration time By default, cookies expire after 400 days. To change the expiration time, enable the toggle and enter the period. #### Override cookie domain If you use several subdomains, they generate cookies with their own domain. To declare a specific domain instead, enable the toggle and enter the domain. #### Disable automatic tracking of page visits You can disable automatic collection of `page.visit` events. You can re-implement the events by using the [SDK methods](/developers/web/event-tracking).
For Single-Page Applications, this option is always enabled.
#### Custom service worker scope If you use Synerise Web push notifications and need to set a custom service worker scope (registration path), enable the toggle and enter the path. #### Customizing metadata You can add `` tags (for example, OG tags) to the website or modify existing ones. The new values are added to `page.visit` events. They can also be used with other features based on metadata, such as communication, recommendations, personalization, and so on. To add the metadata, enable the toggle and paste JS code inside the `function (metadata)` function.
If you chose **Shopify** as the page type, a piece of Jinjava required for the integration is already added to the metadata and this option can't be disabled.
**Example**:
function (metadata) { // DO NOT REMOVE
    metadata.size = 8;
    metadata.isExample = true;
    metadata['og:title'] = 'Sneakers';
    metadata['product:retailer_part_no'] = '1a4d3380-04d1';
    return metadata; // DO NOT REMOVE
    }                // DO NOT REMOVE
Syntax usage: - If the name of the meta key doesn't contain special characters, use the `metadata.keyName = 'keyValue'` syntax. - If the name of the meta key contains special characters, use the `metadata['key_name'] = 'keyValue'` syntax. - Up to 20 meta parameters can be returned. - The following value types are allowed: - string - number - boolean - array #### Manage some Synerise features You can turn off Web push notifications and/or Dynamic Content by disabling the toggles. The feature or features will be disabled entirely for this tracking code and **can't be restored with SDK methods**. ## Adding the tracking code to your site 1. After you complete the configuration, click **Generate**. **Result**: The tracking code is generated and displayed.
A screenshot of a generated tracking code
An example generated tracking code for a Web page
2. Continue depending on the selected page type:
1. Copy the tracking code. 2. Paste the code into your website, before the closing `` tag. You can use Google Tag Manager to do this (when using a custom tracking domain this is **not** recommended). 3. If you enabled the custom tracking domain, make sure it's added to the DNS and API methods as described in [Custom tracking domain](/developers/web/first-party-tracking).
1. Copy the tracking code. 2. Paste the code into your website, before the closing `` tag. You can use Google Tag Manager to do this (when using a custom tracking domain this is **not** recommended). 3. If you enabled the custom tracking domain, make sure it's added to the DNS and API methods as described in [Custom tracking domain](/developers/web/first-party-tracking). 3. Re-enable page visit tracking and Dynamic Content retrieval by implementing the following methods in the page:
SR.event.pageVisit()
          .then(function () {
              SR.dynamicContent.get();
      })
Page visits and dynamic content retrieval must be implemented according to the following rules: - og:tags must be loaded first, regardless of the method that is used to load them. - page visits and dynamic content must be requested whenever the page is loaded, reloaded, and when the view changes.
You can use Google Tag Manager to implement the methods. To do so, trigger `SR.event.pageVisit();` and `SR.dynamicContent.get();` methods on events that indicate a page or DOM being loaded. `SR.init` is only called when DOM is loaded.
For VTEX, 2 variants of the tracking code are generated. 1. Add the codes to the VTEX pages as described in [Integration for stores using Store Framework](/docs/settings/tool/vtex/vtex-integration). 2. If you enabled the custom tracking domain, make sure it's added to the DNS and API methods as described in [Custom tracking domain](/developers/web/first-party-tracking).
For Shopify, 2 variants of the tracking code are generated. 1. Add the tracking code to the Shopify page according to the [Shopify integration instructions](/docs/settings/tool/integrating-shopify-with-synerise#implement-tracking-codes-in-your-shop). 2. If you enabled the custom tracking domain, make sure it's added to the DNS and API methods as described in [Custom tracking domain](/developers/web/first-party-tracking).
## Nonce for Content Security Policies Nonce (number used once) is a content attribute which can be used by Content Security Policies (CSPs) to determine if an element should be allowed. If a script doesn't have a nonce value that matches the one expected by the CSP, the script can't execute. You can add the nonce to the Synerise SDK initialization script:
SR.init({
  trackerKey: "VALUE",
  nonce: "VALUE"
});
The tracking code and any scripts that the SDK adds to the page (for example, in Dynamic Content) will have the nonce value that you add to `SR.init`
You must generate the value of the nonce yourself and make sure it matches the one expected by the CSP.
For more details on nonce and implementing it, see [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce). ### 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) ### Customer identification ## Anonymous customers When a customer enters your website for the first time, they are anonymous. However, their actions are already being tracked - a UUID is assigned and stored in an anonymous profile in the database. The same UUID is stored in the [cookies](/developers/web/cookies) of the customer's browser. The anonymous profile stores information about the customer's activities, just like it does for recognized customers. The customer can now receive personalized recommendations on the website and be included in marketing campaigns. ## Recognized customers By default, the unique identifier is the customer's email. You can [configure your workspace to use `customId` instead](/docs/settings/configuration/non-unique-emails). When the customer 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. A freshly-recognized customer sees personalized content, based on their previous interactions with the website as an anonymous customer. If a recognized customer provides a unique identifier in a form, and another recognized customer's profile already exists in the browser, the context changes to the most recent customer.
It's not necessary for a customer to register an account on your website. A non-anonymous profile may be created based on information provided in other contexts, such as subscribing to a newsletter. See [Tracking form data with SDK](/developers/web/tracking-form-data), [Newsletters](/developers/web/newsletter-agreements), and [Tracking form data with API](/developers/web/tracking-form-data/tracking-form-data-api).
## Recognizing customers from link parameters --- You can append parameters to links to inform the Synerise JS SDK who clicked the link. The parameters are `snrs_cl` (the user's UUID) and `snrs_he` (hash of the user's identifier). A [tracking code](/developers/web/installation-and-configuration) must be implemented in the linked page. The instructions on adding the parameters to the links in templates are available at the links below: - [Email templates](/docs/campaign/e-mail/creating-email-templates#tips-before-you-start) - [Mobile push templates](/docs/campaign/Mobile/creating-mobile-push-templates/mobile-push-visual-builder#adding-tracking-parameters-to-links) - [SMS templates](/docs/campaign/SMS/creating-SMS-template#tracking-parameters-in-links) - [Web push templates](/docs/campaign/Webpush/creating-webpush-templates#tracking-parameters-in-links) When these parameters are present in a link, the user’s browser context is automatically switched to the identified user without any prompt. The primary purpose of this automatic context update is to maintain continuity of the user’s journey after clicking the link—for example, from an email campaign—ensuring that all subsequent [events](/docs/assets/events/introduction-to-events) are accurately attributed to the user whose identifier was included in the link. This mechanism enables seamless user journey continuity but can also lead to context changes when a link is shared with another person. In such cases, the recipient’s browser context will switch to that of the original user, which may affect how events are attributed. On the user interface on the Synerise platform, you can decide how end-user context is managed when these link parameters are detected; the full instruction is available in the ["Managing user context" section](/docs/settings/configuration/non-unique-emails#managing-user-context). ### 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.
```Dart static SyneriseInitializer initializer() ```
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/lifecycle#initialization) --- This method changes a Profile (formerly Client) API key dynamically.
```Dart SyneriseInitializer changeApiKey(String apiKey) ```
[(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.
SyneriseInitializer setRequestValidationSalt(String requestValidationSalt)
--- This method enables or disables console logs from Synerise SDK.
SyneriseInitializer withDebugModeEnabled(bool debugModeEnabled)
--- This method enables or disables crash handling by Synerise SDK.
SyneriseInitializer withCrashHandlingEnabled(bool crashHandlingEnabled)
--- 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)
SyneriseInitializer setMessagingServiceType(String messagingServiceType)
--- This method initializes Synerise.
Future<void> init() async
### 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.
```Java - void onRegisterForPushRequired(PushRegistrationOrigin origin); ```
```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`.
```Java - boolean onOpenUrl(SyneriseSource source, String url) ```
```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`.
This method was deprecated in SDK version 6.0.0.
```Java - boolean onOpenUrl(InjectorSource source, String url) ```
```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`.
```Java - boolean onDeepLink(SyneriseSource source, String deepLink) ```
```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`.
This method was deprecated in SDK version 6.0.0.
```Java - boolean onDeepLink(InjectorSource source, String deepLink) ```
```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.
```Java boolean shouldShow(InAppMessageData inAppMessageData) ```
```Kotlin shouldShow(inAppMessageData: InAppMessageData): boolean ```
| Parameter | Type | Description | | --- | --- | --- | | **inAppMessageData** | [InAppMessageData](/developers/mobile-sdk/class-reference/android/campaigns#inappmessagedata) | In-app message data. | #### onShown(InAppMessageData inAppMessageData) {id=on-in-app-listener-on-shown} This method is called after an in-app message appears.
```Java void onShown(InAppMessageData inAppMessageData) ```
```Kotlin onShown(inAppMessageData: InAppMessageData) ```
| Parameter | Type | Description | | --- | --- | --- | | **inAppMessageData** | [InAppMessageData](/developers/mobile-sdk/class-reference/android/campaigns#inappmessagedata) | In-app message data. | #### onDismissed(InAppMessageData inAppMessageData) {id=on-in-app-listener-on-dismissed} This method is called after an in-app message disappears.
```Java void onDismissed(InAppMessageData inAppMessageData) ```
```Kotlin onDismissed(inAppMessageData: InAppMessageData) ```
| 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.
```Java HashMap onContextFromAppRequired(InAppMessageData inAppMessageData) ```
```Kotlin onContextFromAppRequired(inAppMessageData: InAppMessageData): HashMap ```
| 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.
```Java void onHandledOpenUrl(InAppMessageData inAppMessageData) ```
```Kotlin onHandledOpenUrl(inAppMessageData: InAppMessageData) ```
| 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.
```Java void onHandledOpenDeepLink(InAppMessageData inAppMessageData) ```
```Kotlin onHandledOpenDeepLink(inAppMessageData: InAppMessageData) ```
| 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.
```Java void onCustomAction(String identifier, HashMap params, InAppMessageData inAppMessageData) ```
```Kotlin onCustomAction(identifier: String, params: HashMap , inAppMessageData: InAppMessageData) ```
| 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. | --- --- ## 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.
```Java - void onLoad(ContentWidget contentWidget) ```
```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.
```Java - void onLoadingError(ContentWidget contentWidget, ApiError apiError) ```
```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.
```Java - void onClickActionReceive(ContentWidget contentWidget, BaseModel model) ```
```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.
```Java - void onLoading(ContentWidget contentWidget, boolean isLoading) ```
```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.
```Java - void onSizeChange(ContentWidget contentWidget, ViewGroup.LayoutParams size) ```
```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 | ### 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 ## Change Profile API Key dynamically --- This method changes a Profile (formerly Client) API key dynamically. **Method name:** Client.changeApiKey(newApiKey) **Declaration:**
```java public static void changeApiKey(@NonNull String newApiKey) ```
```kotlin fun changeApiKey(@NonNull newApiKey:String) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **newApiKey** | String | yes | - | New API Key | **Return Value:** Void type method. **Example:**
```java Client.changeApiKey(apiKey); ```
```kotlin Client.changeApiKey(apiKey); ```
## Change Profile API Key dynamically with config --- This method changes a Profile (formerly Client) API key dynamically, with additional parameters. It can include a salt for [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) requests. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.19.0 | 5.20.0 | 0.23.0 | 1.3.0 | **Method name:** Client.changeApiKey(apiKey, initializationConfig) **Declaration:**
```java public static void changeApiKey(String apiKey, InitializationConfig initializationConfig) ```
```kotlin fun changeApiKey(@NonNull apiKey:String, @Nullable initializationConfig:InitializationConfig) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiKey** | String | yes | - | New API Key | | **initializationConfig** | [InitializationConfig](/developers/mobile-sdk/class-reference/android/lifecycle#initializationconfig) | no | - | Object for additional initialization settings after the API key change | **Return Value:** Void type method. **Example:**
```java Client.changeApiKey(apiKey, initializationConfig); ```
```kotlin Client.changeApiKey(apiKey, initializationConfig); ```
### Android # Class reference - Android ### 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:**
```Swift static func setDelegate(_ delegate: SyneriseDelegate) ```
```Objective-C + (void)setDelegate:(SNRSyneriseDelegate *)delegate ```
**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.
**Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func initialize(apiKey: String) -> Void ```
```Objective-C + (void)initializeWithApiKey:(NSString *)apiKey ```
Before version 5.0.0, this method was called `Synerise.initialize(clientApiKey:)`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiKey** | String | yes | - | Synerise Profile (formerly Client) API Key | **Return Value:** No value is returned. **Example:**
```Swift let apiKey = "YOUR_PROFILE_API_KEY" Synerise.initialize(apiKey: apiKey) ```
```Objective-C static NSString *apiKey = @"YOUR_PROFILE_API_KEY"; [SNRSynerise initializeWithApiKey:apiKey]; ```
## Initialize with custom environment --- This method initializes Synerise SDK with custom environment settings.
This method must be called before any other Synerise SDK method and only once during the application's lifecycle.
**Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func initialize(apiKey: String, baseUrl: String?) -> Void ```
```Objective-C + (void)initializeWithApiKey:(NSString *)apiKey andBaseUrl:(nullable NSString *)baseUrl ```
Before version 5.0.0, this method was called `Synerise.initialize(clientApiKey:baseUrl:)`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiKey** | String | yes | - | Synerise Profile (formerly Client) API Key | | **baseUrl** | String | no | - | Synerise API custom environment base URL | 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`
**SNR_SYNERISE_AZ_API_URL** - `https://api.snrapi.com` **SNR_SYNERISE_AZU_API_URL** - `https://api.azu.snrapi.com` **SNR_SYNERISE_GEB_API_URL** - `https://api.geb.snrapi.com`
**Return Value:** No value is returned. **Example:**
```Swift let apiKey = "YOUR_PROFILE_API_KEY" let apiBaseUrl = "YOUR_API_BASE_URL" Synerise.initialize(apiKey: apiKey, baseUrl: apiBaseUrl) ```
```Objective-C static NSString *apiKey = @"YOUR_PROFILE_API_KEY"; static NSString *apiBaseUrl = @"YOUR_API_BASE_URL"; [SNRSynerise initializeWithApiKey:apiKey andBaseUrl:apiBaseUrl]; ```
## Change Profile API Key dynamically --- This method changes a Profile (formerly Client) API key dynamically. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func changeApiKey(_ apiKey: String) -> Void ```
```Objective-C + (void)changeApiKey:(nonnull NSString *)apiKey ```
Before version 5.0.0, this method was called `Synerise.changeClientApiKey(_ clientApiKey:)`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiKey** | String | yes | - | Synerise Profile API Key (formerly Client API key) | **Return Value:** No value is returned. ## Change Profile API Key dynamically with config --- This method changes a Profile (formerly Client) API key dynamically, with additional parameters. It can include a salt for [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) requests. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.19.0 | 5.20.0 | 0.23.0 | 1.3.0 | **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func changeApiKey(_ apiKey: String, config: InitializationConfig?) -> Void ```
```Objective-C + (void)changeApiKey:(nonnull NSString *)apiKey config:(nullable SNRInitializationConfig *)config; ```
Before version 5.0.0, this method was called `Synerise.changeClientApiKey(_ clientApiKey:config:)`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiKey** | String | yes | - | Synerise Profile API Key (formerly Client API key) | | **config** | [InitializationConfig](/developers/mobile-sdk/class-reference/ios/lifecycle#initializationconfig) | no | - | Object for additional initialization settings after the API key change | **Return Value:** No value is returned. ## Set Request Validation Salt --- This method sets the salt string for request validation. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 | **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func setRequestValidationSalt(_: String?) -> Void ```
```Objective-C + (void)setRequestValidationSalt:(nullable NSString *)string ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **salt** | String | no | - | Synerise Profile salt string for request validation | **Return Value:** No value is returned. ## Set up host application type --- This method sets the Synerise SDK host application type. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.1 | 3.6.22 | - | - | **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func setHostApplicationType(_ type: HostApplicationType) -> Void ```
```Objective-C + (void)setHostApplicationType:(SNRHostApplicationType)type ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **type** | [HostApplicationType](/developers/mobile-sdk/class-reference/ios/miscellaneous#hostapplicationtype) | yes | - | Specifies the type of host application | **Return Value:** No value is returned. ## Set host application SDK plugin version --- This method sets the Synerise SDK plugin version. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.6 | 5.11.0 | - | - | **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func setHostApplicationSDKPluginVersion(_ version: String) -> Void ```
```Objective-C + (void)setHostApplicationSDKPluginVersion:(NSString *)version ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **version** | String | yes | - | Specifies the version of the Synerise SDK plugin in the host application | **Return Value:** No value is returned. ## Enable Debug Mode --- This method enables or disables console logs from Synerise SDK.
It is not recommended to use debug mode in the release version of your application.
**Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func setDebugModeEnabled(_: Bool) -> Void ```
```Objective-C + (void)setDebugModeEnabled:(BOOL)enabled; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **enabled** | Bool | yes | - | Enables or disables console logs | **Return Value:** No value is returned. ## Enable Crash Handling --- This method enables or disables crash handling by Synerise SDK.
If set to true, Synerise SDK will send the `client.applicationCrashed` event with information about crash.
**Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func setCrashHandlingEnabled(_: Bool) -> Void ```
```Objective-C + (void)setCrashHandlingEnabled:(BOOL)enabled ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **enabled** | Bool | yes | - | Enables or disables crash handling | **Return Value:** No value is returned. ## Set Background Task identifiers --- This method sets identifiers for Background Tasks processing. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.23.0 | - | - | - |
Do not use those identifiers for other Background Tasks in your app.
**Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func setBackgroundTaskIdentifiers(_: [String]) -> Void ```
```Objective-C + (void)setBackgroundTaskIdentifiers:(NSArray *)identifiers ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identifiers** | [String] | yes | - | Identifiers for Background Tasks registered in the host appliaction. | **Return Value:** No value is returned. ### SDK Lifecycle ### InitializationConfig Class for additional initialization parameters. **Declared In:** lib/classes/models/Misc/InitializationConfig.js **Declaration:**
class InitializationConfig
**Properties:** | Property | Type | Description | | --- | --- | --- | | **requestValidationSalt** | string | [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) salt | --- --- ### Synerise **Declared In:** lib/main/Synerise.js **Declaration:**
class Synerise
**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.
public withSettings(settings: ISettingsOptions)
--- This method initializes Synerise.
public init()
--- --- --- ### Synerise storage Synerise SDK uses several different cookies that store customer data. ## Cookies ### Expiration time By default, the `_snrs_p`, `_snrs_uuid`, and `_snrs_puuid` cookies expire after 400 days. You can change this by using the `cookieExpiration` parameter. The value is the number of days after which the cookies expire.
- If a browser's cookie expiration limit is lower than your setting, your setting is ignored. - The expiration time of the `_snrs_sa` and `_snrs_sb` cookies is 30 minutes and **cannot** be changed.
The following example sets cookie expiration time to 60 days:
SR.init({ 
    "trackerKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "cookieExpiration": 60
});
### _snrs_p This cookie stores general information about the customer. | Field | Description | |:-------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | host | The owner's domain address | | ~~permUuid~~ | This field is deprecated. Do not use it. | | uuid | A randomly generated customer UUID. This value cannot be used to identify a customer until they provide more information. | | identityHash | If the customer provided an email address, the value is hashed and the hash is then used to compare email addresses provided during subsequent visits. If the email address changes, a new UUID is generated for the customer. | | user_hash | If the *_ush* cookie is set, the value is stored here. In the _ush key, you can keep the id of the customer logged in to the owner's website. Thanks to this parameter, Synerise is able to link these two identifiers. | | init | The time of the first page visit (time from the customer's browser) | | last | The time of the most recent page visit | | current | The current time | | uniqueVisits | The number of unique page visits | | allVisits | The total number of all page visits | ### _snrs_params This cookie stores all `_snrs_` parameters attached to URLs (such parameters can be added to a link when a visitor to a website clicks a recommendation or dynamic content) for 3 days. If the visitor makes a transaction within this period, the `_snrs_` parameters will be added to [transaction events](/docs/assets/events/event-reference/items) sent through JS SDK thanks to [DataLayer integration](/developers/web/installation-and-configuration). ### _snrs_sa This cookie stores information about the current session. Each session lasts 30 minutes. | Field | Description | |:--------------|:-----------------------------------------------| | ssuid | A customer session ID | | appear | The start time of the current session | | sessionVisits | The number of page visits during this session | ### _snrs_sb This cookie stores information about the time when the customer left the page. | Field | Description | |:-------|:------------------------------------| | ssuid | A customer session ID | | leaves | The end time of the session | ### _snrs_sdk_d Special-purpose cookie for Synerise. It's not created automatically. Expiry time is set when the cookie is created. ### _snrs_uuid This cookie stores the customer's UUID (may differ between devices). ### _snrs_puuid Deprecated. This cookie stores the customer's permanent UUID. ### _snrs_cid This cookie stores the ID of a DC campaign. Expires after a year. ### _snrs_dc_sd This cookie stores information about the time when a dynamic content campaign should stop displaying. ### _snrs_dc_views_sd This cookie stores information about the number of views after which a dynamic content campaign will no longer be displayed. ### _snrs_notify_delay Deprecated. This cookie stores information about the delay before showing a notification. ### _snrs_notify_capping Deprecated. This cookie stores information about the maximum number of times a notification is to be displayed. ### _snrs_reset_uuid This is a special purpose cookie that allows you to [assign customer UUIDs](/developers/web/uuids#resetting-customer-uuids). ### _snrs_reset_uuid_and_identity_hash This session cookie allows you to set the UUID and identity hash of a website visitor, overriding the default mechanism of assigning a random identifier. - The cookie stores the visitor's UUID and identity hash in plain text format (for example, `87d3c1eb-0d1d-4749-8845-27f4b085d7ff:thisIsYourHash`). When present, it instructs the Synerise SDK to use these values, thereby resetting the visitor's identification within the SDK. - The cookie `_snrs_reset_uuid_and_identity_hash` must be set as a session cookie, valid only for the duration of the browser session. The SDK reads (retrieves data from) this cookie and, by default, clears (deletes) it after use, ensuring it expires when the session ends. - This cookie is not automatically created by the SDK. You must create a mechanism that creates the cookie, with the correct domain. ## Synerise local storage Additionally, Synerise SDK uses several local storage keys that store customer data. ### _snrs_dc_delay This key stores information about the delay before showing a dynamic content campaign. ### _snrs_dc_frq This key stores information about the frequency of checking if a dynamic content campaign has expired. Cleared when browser data is cleared. ### _snrs_dc_tests This key stores an array of dynamic content variants if A/B testing was applied in dynamic content campaigns. ### _snrs_profile_config This is an object stored in browser's localStorage. This object contains settings of the [workspace](/docs/settings/business-profile) from which the tracking code is implemented into the website. The objects store the following information: | Field | Description | |-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | recognizeBy | This key stores the name of the attribute based on which the visitor to the website is recognized when form tracking is enabled based on the JS SDK methods. Possible values: `email` and `custom_identify`. You can indicate this attribute in [the Synerise platform](/docs/settings/configuration/non-unique-emails). | | ~~profile~~ | This key is deprecated. Do not use it.
This key stored the subdomain (a random string of characters) generated automatically for the workspace when the workspace was created. This subdomain was used by JS SDK for integrating web push notifications. | | dataMarker | This key is deprecated for the new workspaces. Do not use it.
This key stores the configuration for form integration on the website. This key is available for old workspaces. | | providers | This object is required for notification integration (such as web push). Data in this object is necessary for communication between Synerise and Firebase. | | signedIdentifiedActions | This key contains an array of [events which require JWT authentication](/docs/assets/events/event-settings) as a result of JS SDK implementation. | | ~~notifications~~ | This key is deprecated.
This key contained an array of dynamic content campaigns that had been displayed to the visitors to the website. | | ~~cookieMatchers~~ | This key is deprecated.
This key contained the configuration that enabled cookie matching. | | snrsProfileConfigExpire | This key contains the time when the `_snrs_profile_config` object will be retrieved again. | ### synerise-traffic-storage This is a JSON object that contains all requests sent from the website to a tracker. The data is stored in case of a network failure so the SDK can retry sending later. Cleared when browser data is cleared. #### How does it work? 1. JS SDK sends an event, for example [page.visit](/docs/assets/events/event-reference/web-and-app#pagevisit). 2. An entry is created with a randomly generated UUID ([synerise-traffic-storage-UUID](#synerise-traffic-storage-uuid)). This entry contains the request to API. 3. If the request is successful (response 200), the entry with the request is removed. If the request cannot be executed (for example, due to temporary network failure), the request is kept in the entry and executed at the nearest opportunity. ### synerise-traffic-storage-UUID This key stores UUIDs under which requests from the website to a tracker are saved. ### synerise-form-catch This key stores information from submitted forms that has not been saved in Synerise (for example, due to temporary network failure). Cleared when browser data is cleared. ### snr-wp-state This key stores the current status of the web push module. Cleared when browser data is cleared. | Field | Description | |:------------------|:-------------------------------------------------------------------------------------------------------------------| | permission | Informs about the the browser's notification permission setting | | permissionSaved | Informs if the permission has been saved | | subscription | Informs about the customer's consent in Synerise to receive web-push notifications | | subscriptionSaved | Informs if the subscription has been saved | | tokenHash | The token for the current web-push status | | tokenTime | Timeout for the token of the permissionSaved status. Permission saved will be set to **false** after the timeout. | | uuid | The customer's UUID | ### snr-token Stores the [JSON Web Token](/developers/web/jwt-auth) used for customer authentication. Cleared when browser data is cleared. ### 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/business-profile) * 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: 33 ### 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:
...
       allprojects {
           repositories {
               google()
               jcenter()
               maven { url 'https://pkgs.dev.azure.com/Synerise/AndroidSDK/_packaging/prod/maven/v1' }
           }
       }
2. Add dependency to your `project/build.gradle` file:
buildscript {
           repositories {
               google()
               jcenter()
           }
           dependencies {
               classpath 'com.android.tools.build:gradle:3.4.2'
           }
       }
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
Callbacks Description
.build() 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.
.crashHandlingEnabled(boolean) For more information, see the Crash Handling section.
.notificationDefaultChannelId(String) Sets the ID of Push Notification Channel.
.notificationDefaultChannelName(String) Sets the name of Push Notification Channel.
.notificationHighPriorityChannelId(String) Sets the ID of High Priority Push Notification Channel.
.notificationHighPriorityChannelName(String) Sets the name of High Priority Push Notification Channel.
.rxJavaErrorHandlingEnabled(boolean) If set to true, Synerise handles rxJava errors.
If false, you need to call rxJavaPlugins.setErrorHandler on your own.
.syneriseDebugMode(boolean) 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.
Synerise.settings.tracker.autoTracking.trackMode = TrackMode Sets the mode for view tracking.
Synerise.settings.tracker.locationAutomatic = boolean; Use to obtain customer location and send the location event automatically.
Synerise.settings.tracker.setAutoFlushTimeout(int); 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.
Synerise.settings.tracker.setMaximumBatchSize(int); Sets the maximum number of events which may be sent in a single batch. Default value: 100. You can set the value between 1 and 100.
Synerise.settings.tracker.setMinimumBatchSize(int); 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:
```Swift public class App extends MultiDexApplication { @Override public void onCreate() { super.onCreate(); initSynerise(); } private void initSynerise() { String syneriseClientApiKey = getString(R.string.synerise_clientool/api_key); String appId = getString(R.string.app_name); Synerise.settings.tracker.autoTracking.trackMode = FINE; Synerise.settings.tracker.setMinimumBatchSize(10); Synerise.settings.tracker.setMaximumBatchSize(100); Synerise.settings.tracker.setAutoFlushTimeout(5000); Synerise.settings.injector.automatic = false; Synerise.settings.tracker.locationAutomatic = true; Synerise.Builder.with(this, syneriseClientApiKey, appId) .notificationIcon(R.drawable.notification_icon) .notificationIconColor(ContextCompat.getColor(this, R.color.amaranth)) .syneriseDebugMode(true) .pushRegistrationRequired(this) .locationUpdateRequired(this) .notificationDefaultChannelId("your-channel-id") .notificationDefaultChannelName("your-channel-name") .notificationHighPriorityChannelId("your-high-channel-id") .notificationHighPriorityChannelName("your-high-channel-name") .baseUrl("http://your-base-url.com/") .setRequestValidationSalt("YOUR_REQUEST_VALIDATION_SALT") .build(); } } ```
```kotlin class App : MultiDexApplication() { override fun onCreate() { super.onCreate() initSynerise() } private fun initSynerise() { val syneriseClientApiKey = accountManager!!.getClientProfileApiKey() val appId = getString(R.string.app_name) Synerise.settings.tracker.autoTracking.trackMode = FINE; Synerise.settings.tracker.setMinimumBatchSize(10); Synerise.settings.tracker.setMaximumBatchSize(100); Synerise.settings.tracker.setAutoFlushTimeout(5000); Synerise.settings.injector.automatic = false; Synerise.settings.tracker.locationAutomatic = true; Synerise.Builder.with(this, syneriseClientApiKey, appId) .notificationIcon(R.drawable.ic_cart) .notificationIconColor(ContextCompat.getColor(this, R.color.amaranth)) .syneriseDebugMode(true) .pushRegistrationRequired(this) .locationUpdateRequired(this) .notificationDefaultChannelId("your-channel-id") .notificationDefaultChannelName("your-channel-name") .notificationHighPriorityChannelId("your-high-channel-id") .notificationHighPriorityChannelName("your-high-channel-name") .baseUrl("http://your-base-url.com/") .setRequestValidationSalt("YOUR_REQUEST_VALIDATION_SALT") .build() } } ```
3. Add the key in your `/values` strings file (for example, `strings.xml`):
<resources>

       <string name="app_name" translatable="false">Your GREAT application name</string>
       <string name="synerise_client_api_key" translatable="false">EF1AD0E0-532B-6AEE-6010-DEDC78F6E155</string> <!-- replace with valid client api key -->

       ...

   </resources>
Secure sensitive keys (for example, `apiKey` and `requestValidationSalt`) with mechanisms like string obfuscation or encryption.
## Troubleshooting --- ### MultiDex {id=troubleshooting-multidex} Sometimes, MultiDex errors may occur. In that case, enable MultiDex as follows (API >= 21):
defaultConfig {
    applicationId "com.your.app"
    minSdkVersion 21
    ...
    multiDexEnabled true
}
or for API < 21:
defaultConfig {
    applicationId "com.your.app"
    minSdkVersion 20
    ...
    multiDexEnabled true
}
dependencies {
    ...
    // MultiDex
    implementation 'com.android.support:multidex:1.0.3'
    ...
}
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:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" tools:node="remove"/>
## 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: ``` # keep entire Synerise SDK -keep class com.synerise.sdk.** { *; } -keepclassmembers class com.synerise.sdk.** { *; } -keepclassmembers class com.synerise.sdk.** { public (); } ``` ### Customer profiles When a customer interacts with your content for the first time, you can create a profile in the database. This profile may only be identified by an ID - such a profile is *anonymous* (has no personal data). If a user provides their email, for example by signing up to a newsletter, they are *recognized*. A profile is also created when a customer [registers an account](/developers/api/clients/registration). If a customer profile with the same email already exists at the time of registration, the created account becomes connected to that profile and the data is merged. The endpoints described in this article operate on profiles regardless of those profiles' relation to registered accounts. ## Creating profiles Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/CreateAClientInCrm). The minimum data required to create a customer profile is one of the following identifiers: - `email` - `phone` - `uuid` - `customId` For additional fields that you can send, see the reference documentation.
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJh...8MltQ' \
--data-raw '{
   "email": "sampleclient@synerise.com"
}'
**Result:** The response is HTTP 202 with no content. A profile is created, some properties are generated automatically or receive placeholders. See the response in [Retrieving a single profile](#retrieving-a-single-profile). ## Retrieving a single profile Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/FindAClient). You can retrieve a single profile from the database by providing one of the following identifiers: - `email` - `phone` - `uuid` - `customId` The following request retrieves the data of the customer created in [Creating a customer profile](#creating-profiles):
curl --location --request \
GET 'https://{SYNERISE_API_BASE_PATH}/v4/clients/by-email/sampleclient@synerise.com' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJhb...hjM' \
The response is the customer data. During profile creation, the **only** provided property was the email (see curl example in [Creating profiles](#creating-profiles) - the other properties are generated automatically or receive placeholder values.
{
    "previousClients": [],
    "clientId": 2149203825,
    "email": "sampleclient@synerise.com",
    "phone": null,
    "customId": null,
    "uuid": "24f539a0-d257-11ea-92f0-23c0f0aec77f",
    "firstName": "Sampleclient",
    "lastName": null,
    "displayName": null,
    "company": null,
    "address": null,
    "city": null,
    "province": null,
    "zipCode": null,
    "countryCode": null,
    "birthDate": null,
    "lastActivityDate": "2020-07-30T11:23:51Z",
    "sex": "NOT_SPECIFIED",
    "avatarUrl": "https://www.gravatar.com/avatar/2b13fb10fcb2ff3327a41c3c5dd3d2cd?s=100&r=g&d=blank",
    "anonymous": false,
    "agreements": {
        "email": false,
        "sms": false,
        "push": false,
        "webPush": false,
        "bluetooth": false,
        "rfid": false,
        "wifi": false
    },
    "attributes": {
        "eventCreateTime": "2020-07-30T11:23:46.092Z",
        "correlationId": "D57HkYUzRRu2ImZmjNg-Iw"
    },
    "tags": []
}
## Listing profiles Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/ListClients). This method allows you to list customer profiles from the database. The results can be filtered (see method reference). **The maximum number of retrieved entries is 10 000.**
curl --location --request \
GET 'https://{SYNERISE_API_BASE_PATH}/crm/v1/list' \
--header 'Authorization: Bearer eyJh...8MltQ' \
The response is a list of profiles. ## Updating profiles Method reference available: - [Identification by ID](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/UpdateAClient) - [Identification by email](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/UpdateAClientByEmail). If you use the [non-unique emails feature](/docs/settings/configuration/non-unique-emails), identification by email is not recommended. - [Identification by customId](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/UpdateAClientByCustomId) You can update the customer profile. When sending the request, include only the fields that you want to update. Sending a null value deletes an attribute (if it's a custom attribute) or sets it to null/default value (if the attribute is Synerise-native). Empty strings are not accepted. The following example updates the customer's name and surname:
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients/by-email/sampleclient@synerise.com' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJhb...Jes' \
--data-raw '{
    "firstName": "John",
    "lastName": "Smith"
}'
**Result:** The response is HTTP 202 with no content. The profile data is updated. ## Deleting profiles Method reference available: - [Identification by ID](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/DeleteAClient) - [Identification by customId](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/DeleteAClientByCustomId) You can delete a profile.
curl --location --request \
DELETE 'https://{SYNERISE_API_BASE_PATH}/v4/clients/2149203825' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJhbG...DVDg2Udg' \
**Result:** The response is HTTP 202 with no content. The profile is deleted. ## Creating/updating multiple profiles Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/BatchAddOrUpdateClients). Customer profiles can be added or updated in batch. When you perform this operation, existing profiles are updated, and data that does not match any profiles results in creating new profiles. When sending the request, include only the fields that you want to update. Sending a null value deletes an attribute (if it's a custom attribute) or sets it to null/default value (if the attribute is Synerise-native). Empty strings are not accepted. The following request creates two new profiles and updates the `firstName` field of the customer created in [Creating profiles](#creating-profiles):
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients/batch' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJhb...EGRXjc' \
--data-raw '[
   {
      "email": "newclient@synerise.com"
   },
   {
      "customId": "newClientCustomId"
   },
   {
      "email": "sampleclient@synerise.com",
      "firstName": "Michael"
   }
]'
**Result:** The response is HTTP 202 with co content. The operation is queued.
Completing a batch operation may take some time, depending on request size and server load.
### Modules ### Synerise **Declared In:** Headers/SNRSynerise.h **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class Synerise: NSObject ```
```Objective-C @interface SNRSynerise : NSObject ```
**Properties:** | Property | Type | Description | | --- | --- | --- | | **settings** | [Settings](/developers/mobile-sdk/class-reference/ios/lifecycle#settings) | Settings module to configure the SDK |
The `settings` property is statically accessible.
**Methods:** This method sets an object for Synerise delegate methods.
```Swift static func setDelegate(_: SyneriseDelegate) ```
```Objective-C + (void)setDelegate:(nonnull id)delegate ```
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate) --- This method sets an object for notification delegate methods.
```Swift static func setNotificationDelegate(_: NotificationDelegate) ```
```Objective-C + (void)setNotificationDelegate:(id)delegate ```
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#notification-delegate) --- This method initializes Synerise.
```Swift static func initialize(apiKey:) ```
```Objective-C + (void)initializeWithApiKey:(nonnull NSString *)apiKey ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#initialization) --- This method initializes Synerise SDK with custom environment settings.
```Swift static func initialize(apiKey:baseUrl:) ```
```Objective-C + (void)initializeWithApiKey:(nonnull NSString *)apiKey andBaseUrl:(nullable NSString *)baseUrl ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#initialize-with-custom-environment) --- This method sets the salt string for request validation.
```Swift static func setRequestValidationSalt(_: String?) ```
```Objective-C + (void)setRequestValidationSalt:(nullable NSString *)string ```
[(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.
```Swift static func changeApiKey(apiKey: String) ```
```Objective-C + (void)changeApiKey:(NSString *)apiKey ```
[(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.
```Swift static func changeApiKey(_ apiKey: String, config: InitializationConfig?) -> Void ```
```Objective-C (void)changeApiKey:(NSString *)apiKey config:(nullable SNRInitializationConfig *)config; ```
[(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.
```Swift static func setHostApplicationType(_: HostApplicationType) ```
```Objective-C + (void)setHostApplicationType:(SNRHostApplicationType)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.
```Swift static func setHostApplicationSDKPluginVersion(_: String) ```
```Objective-C + (void)setHostApplicationSDKPluginVersion:(NSString *)type ```
[(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.
```Swift static func setDebugModeEnabled(_: Bool) ```
```Objective-C + (void)setDebugModeEnabled:(BOOL)enabled ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/lifecycle#enable-debug-mode) --- This method enables or disables crash handling by Synerise SDK.
```Swift static func setCrashHandlingEnabled(_: Bool) ```
```Objective-C + (void)setCrashHandlingEnabled:(BOOL)enabled ```
[(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.
```Swift static func setNotificationCategories(_: Set) ```
```Objective-C + (void)setNotificationCategories:(NSSet *)notificationCategories ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#set-notification-categories) --- This method sets identifiers for Background Tasks processing.
```Swift static func setBackgroundTaskIdentifiers(_: [String]) ```
```Objective-C + (void)setBackgroundTaskIdentifiers:(NSArray *)identifiers ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#set-notification-categories) --- This method verifies if a notification was sent by Synerise.
```Swift static func isSyneriseNotification(_: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseNotification:(nonnull NSDictionary *)userInfo ```
[(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
```Swift static func isSyneriseSimplePush(_: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseSimplePush:(nonnull NSDictionary *)userInfo ```
[(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.
```Swift static func isSyneriseBanner(_: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseBanner:(nonnull NSDictionary *)userInfo ```
[(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.
```Swift static func isSyneriseSilentCommand(_: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseSilentCommand:(nonnull NSDictionary *)userInfo ```
[(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.
```Swift static func isSyneriseSilentSDKCommand(_: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseSilentSDKCommand:(nonnull NSDictionary *)userInfo ```
[(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.
```Swift static func isNotificationEncrypted(_: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isNotificationEncrypted:(nonnull NSDictionary *)userInfo ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#check-if-push-notification-is-encrypted) --- This method decrypts the notification payload.
```Swift static func decryptNotification(_: [AnyHashable: Any]) -> [AnyHashable: Any]? ```
```Objective-C + (nullable NSDictionary *)decryptNotification:(nonnull NSDictionary *)userInfo ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/campaigns#decrypt-push-notification) --- This method handles a notification payload and starts activity.
```Swift static func handleNotification(_: [AnyHashable: Any]) ```
```Objective-C + (void)handleNotification:(nonnull NSDictionary *)userInfo ```
[(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.
```Swift static func handleNotification(_: [AnyHashable: Any], actionIdentifier: String) ```
```Objective-C + (void)handleNotification:(nonnull NSDictionary *)userInfo actionIdentifier:(nullable NSString *)actionIdentifier ```
[(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`
--- --- ### Client The module for managing customer account data, registration, authentication, and authorization. **Declared In:** Headers/SNRClient.h **Related To:** [ClientStateDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#client-state-delegate) [ClientRegisterAccountContext](/developers/mobile-sdk/class-reference/ios/client#clientregisteraccountcontext) [ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/ios/client#clientconditionalauthresult) [ClientConditionalAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientconditionalauthenticationcontext) [ClientAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientauthenticationcontext) [ClientOAuthAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientoauthauthenticationcontext) [ClientFacebookAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientfacebookauthenticationcontext) [ClientAppleSignInAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientapplesigninauthenticationcontext) [ClientAccountInformation](/developers/mobile-sdk/class-reference/ios/client#clientaccountinformation) [ClientUpdateAccountContext](/developers/mobile-sdk/class-reference/ios/client#clientupdateaccountcontext) [ClientUpdateAccountBasicInformationContext](/developers/mobile-sdk/class-reference/ios/client#clientupdateaccountbasicinformationcontext) [ClientPasswordResetRequestContext](/developers/mobile-sdk/class-reference/ios/client#clientpasswordresetrequestcontext) [ClientPasswordResetConfirmationContext](/developers/mobile-sdk/class-reference/ios/client#clientpasswordresetconfirmationcontext) [Token](/developers/mobile-sdk/class-reference/ios/client#token) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class Client: NSObject ```
```Objective-C @interface SNRTracker : NSObject ```
**Methods:** This method sets an object for a customers's state delegate methods.
```Swift static func setClientStateDelegate(_: ClientStateDelegate) ```
```Objective-C + (void)setClientStateDelegate:(nonnull id)delegate ```
[(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.
```Swift static func registerAccount(context: ClientRegisterAccountContext, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)registerAccount:(nonnull SNRClientRegisterAccountContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func confirmAccountActivation(token: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)confirmAccount:(nonnull NSString *)token success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#confirm-customer-account-activation) --- This method activates a customer with email.
```Swift static func requestAccountActivation(email: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)requestAccountActivation:(nonnull NSString *)email success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func requestAccountActivationByPin(email: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)requestAccountActivationByPinWithEmail:(nonnull NSString *)email success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func confirmAccountActivationByPin(pinCode: String, email: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)confirmAccountActivationByPin:(nonnull NSString *)pinCode email:(nonnull NSString *)email success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func signIn(email: String, password: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)signInWithEmail:(nonnull NSString *)email password:(nonnull NSString *)password success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func signInConditionally(email: String, password: String, success: ((ClientAuthenticationResult) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)signInConditionallyWithEmail:(nonnull NSString *)email password:(nonnull NSString *)password success:(nonnull void (^)(SNRClientAuthenticationResult *authResult))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func authenticate(token: AnyObject, clientIdentityProvider: ClientIdentityProvider, authID: String?, context: ClientAuthenticationContext?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)authenticateWithToken:(id)token clientIdentityProvider:(SNRClientIdentityProvider)clientIdentityProvider authID:(nullable NSString *)authID context:(nullable SNRClientAuthenticationContext *)context success:(void (^)(BOOL isSuccess))success failure:(void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func authenticateConditionally(token: AnyObject, clientIdentityProvider: ClientIdentityProvider, authID: String?, context: ClientConditionalAuthenticationContext?, success: ((ClientAuthenticationResult) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)authenticateConditionallyWithToken:(id)token clientIdentityProvider:(SNRClientIdentityProvider)clientIdentityProvider authID:(nullable NSString *)authID context:(nullable SNRClientConditionalAuthenticationContext *)context success:(void (^)(SNRClientAuthenticationResult *authResult))success failure:(void (^)(SNRApiError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider) --- This method authenticates a customer with OAuth.
```Swift static func authenticateByOAuth(accessToken: String, authID: String?, context: ClientOAuthAuthenticationContext?, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)authenticateByOAuthWithAccessToken:(nonnull NSString *)accessToken authID:(nullable NSString *)authID context:(nullable SNRClientOAuthAuthenticationContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func authenticateByOAuthIfRegistered(accessToken: String, authID: String?, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)authenticateByOAuthIfRegisteredWithAccessToken:(nonnull NSString *)accessToken authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func authenticateByFacebook(facebookToken: String, authID: String?, context: ClientFacebookAuthenticationContext?, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)authenticateByFacebookWithFacebookToken:(nonnull NSString *)facebookToken authID:(nullable NSString *)authID context:(nullable SNRClientFacebookAuthenticationContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func authenticateByFacebookIfRegistered(facebookToken: String, authID: String?, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)authenticateByFacebookIfRegisteredWithFacebookToken:(nonnull NSString *)facebookToken authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func authenticateByAppleSignIn(identityToken: Data, authID: String?, context: ClientAppleSignInAuthenticationContext?, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)authenticateByAppleSignInWithIdentityToken:(nonnull NSData *)identityToken authID:(nullable NSString *)authID context:(nullable SNRClientAppleSignInAuthenticationContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func authenticateByAppleSignInIfRegistered(identityToken: Data, authID: String?, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)authenticateByAppleSignInIfRegisteredWithIdentityToken:(nonnull NSData *)identityToken authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func authenticate(tokenPayload: TokenPayload, authID: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateWithTokenPayload:(SNRTokenPayload *)tokenPayload authID:(NSString *)authID success:(void (^)(void))success failure:(void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func simpleAuthentication(data: ClientSimpleAuthenticationData, authID: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)simpleAuthentication:(SNRClientSimpleAuthenticationData *)data authID:(NSString *)authID success:(void (^)(void))success failure:(void (^)(SNRApiError *error))failure ```
[(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).
```Swift static func isSignedInViaSimpleAuthentication() -> Bool ```
```Objective-C + (BOOL)isSignedInViaSimpleAuthentication ```
[(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.
```Swift static func signOut(mode: ClientSignOutMode) ```
```Objective-C + (void)signOutWithMode:(SNRClientSignOutMode)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
```Swift static func signOut(mode: ClientSignOutMode, fromAllDevices: Bool, success: (() -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)signOutWithMode:(SNRClientSignOutMode)mode fromAllDevices:(BOOL)fromAllDevices success:(void (^)(void))success failure:(void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func refreshToken(success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)refreshTokenWithSuccess:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-session#refresh-customer-token) --- This method retrieves the customer’s current, active token.
```Swift static func retrieveToken(success: ((Token) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)retrieveTokenWithSuccess:(nonnull void (^)(SNRToken *token))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func getUUIDForAuthentication(authID: String) -> String ```
```Objective-C + (NSString *)getUUIDForAuthenticationWithAuthID:(NSString *)authID; ```
[(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.
```Swift static func regenerateUUID(clientIdentifier: String) ```
```Objective-C + (BOOL)regenerateUUIDWithClientIdentifier:(nullable NSString *)clientIdentifier ```
[(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.
```Swift static func getAccount(success: ((ClientAccountInformation) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getAccountWithSuccess:(void (^)(SNRClientAccountInformation *accountInformation))success failure:(void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#get-customer-account-information) --- This method retrieves events for an authenticated customer.
```Swift static func getEvents(apiQuery: ClientEventsApiQuery, success: (([ClientEventData]) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getEventsWithApiQuery:(nonnull SNRClientEventsApiQuery *)apiQuery success:(nonnull void (^)(NSArray *events))success failure:(nonnull void (^)(NSError *error))failure ```
[(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).
```Swift static func updateAccountBasicInformation(context: ClientUpdateAccountBasicInformationContext, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)updateAccountBasicInformation:(nonnull SNRClientUpdateAccountBasicInformationContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func updateAccount(context: ClientUpdateAccountContext, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)updateAccount:(nonnull SNRClientUpdateAccountContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func requestPasswordReset(context: ClientPasswordResetRequestContext, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)requestPasswordReset:(nonnull SNRClientPasswordResetRequestContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func confirmResetPassword(context: ClientPasswordResetConfirmationContext, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)confirmResetPassword:(nonnull SNRClientPasswordResetConfirmationContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func changePassword(password: String, oldPassword: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)changePassword:(nonnull NSString *)password oldPassword:(nonnull NSString *)oldPassword success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#change-customers-account-password) --- This method requests a customer's email change.
```Swift static func requestEmailChange(email: String, password: String?, externalToken: AnyObject?, authID: String?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)requestEmailChange:(NSString *)email password:(nullable NSString *)password externalToken:(nullable id)externalToken authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/client-account#request-email-change-for-customer-account) --- This method confirms an email change.
```Swift static func confirmEmailChange(token: String, newsletterAgreement: Bool, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)confirmEmailChange:(nonnull NSString *)token newsletterAgreement:(BOOL)newsletterAgreement success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func requestPhoneUpdate(phone: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)requestPhoneUpdate:(nonnull NSString *)phone success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func confirmPhoneUpdate(phone:confirmationCode: String, smsAgreement: Bool, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)confirmPhoneUpdate:(nonnull NSString *)phone confirmationCode:(nonnull NSString *)confirmationCode smsAgreement:(BOOL)smsAgreement success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func deleteAccount(clientAuthFactor: AnyObject, clientIdentityProvider: ClientIdentityProvider, authID: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)deleteAccount:(nonnull id)clientAuthFactor clientIdentityProvider:(SNRClientIdentityProvider)clientIdentityProvider authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func deleteAccount(password: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)deleteAccount:(nonnull NSString *)password success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func registerForPush(registrationToken: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)registerForPush:(nonnull NSString *)registrationToken success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func registerForPush(registrationToken: String, mobilePushAgreement: Bool, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)registerForPush:(nonnull NSString *)registrationToken mobilePushAgreement:(BOOL)mobilePushAgreement success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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:**
```Swift class Tracker: NSObject ```
```Objective-C @interface SNRTracker : NSObject ```
**Methods:** This method sets an object for Tracker module delegate methods.
```Swift static func setDelegate(_: TrackerDelegate) ```
```Objective-C + (void)setDelegate:(nonnull id)delegate ```
[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.
```Swift static func setCustomIdentifier(_: String?) ```
```Objective-C + (void)setCustomIdentifier:(nullable NSString *)customIdentifier ```
[(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.
```Swift static func setCustomEmail(_: String?) ```
```Objective-C + (void)setCustomEmail:(nullable NSString *)customEmail ```
[(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.
```Swift static func flushEvents(completionHandler: (() -> Void)?) ```
```Objective-C + (void)flushEventsWithCompletionHandler:(nullable void (^)(void))completion ```
[(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:**
```Swift class Injector: NSObject ```
```Objective-C @interface SNRInjector : NSObject ```
**Methods:** This method sets an object for in-app messages delegate methods.
```Swift static func setInAppMessageDelegate(_: InjectorInAppMessageDelegate) ```
```Objective-C + (void)setInAppMessageDelegate:(id)delegate ```
[(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.
```swift static func closeInAppMessage(campaignHash: String) -> Void ```
```objective-c + (void)closeInAppMessage:(nonnull NSString *)campaignHash ```
[(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.
```Swift static func isWalkthroughLoaded() -> Bool ```
```Objective-C + (BOOL)isWalkthroughLoaded ```
[(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.
```Swift static func isLoadedWalkthroughUnique() -> Bool ```
```Objective-C + (BOOL)isLoadedWalkthroughUnique ```
[(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.
```Swift static func getPushes(success: (([[AnyHashable: Any]]) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getPushesWithSuccess:(nonnull void (^)(NSArray *pushes))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func getBanners() -> [[AnyHashable: Any]] ```
```Objective-C + (nonnull NSArray *)getBanners ```
[(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.
```Swift static func fetchBanners(success: (([[AnyHashable: Any]]) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)fetchBannersWithSuccess:(nonnull void (^)(NSArray *banners))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func showBanner(_: [AnyHashable: Any], markPresented: Bool) ```
```Objective-C + (void)showBanner:(nonnull NSDictionary *)bannerDictionary markPresented:(BOOL)markPresented ```
[(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:**
```Swift class Promotions: NSObject ```
```Objective-C @interface SNRPromotions : NSObject ```
**Methods:** This method retrieves all available promotions that are defined for a customer.
```Swift static func getPromotions(success: ((PromotionResponse) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getPromotionsWithSuccess:(nonnull void (^)(SNRPromotionResponse *promotionResponse))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func getPromotions(apiQuery: PromotionsApiQuery, success: ((PromotionResponse) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getPromotionsWithApiQuery:(nonnull SNRPromotionsApiQuery *)apiQuery success:(nonnull void (^)(SNRPromotionResponse *promotionResponse))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func getPromotion(uuid: String, success: ((Promotion) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getPromotionByUuid:(nonnull NSString *)uuid success:(nonnull void (^)(SNRPromotion *promotion))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-promotion-by-uuid) --- This method retrieves the promotion with the specified code.
```Swift static func getPromotion(code: String, success: ((Promotion) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getPromotionByCode:(nonnull NSString *)code success:(nonnull void (^)(SNRPromotion *promotion))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#get-promotion-by-code) --- This method activates the promotion with the specified UUID.
```Swift static func activatePromotion(uuid: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)activatePromotionByUuid:(nonnull NSString *)uuid success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#activate-promotion-by-uuid) --- This method activates the promotion with the specified code.
```Swift static func activatePromotion(code: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)activatePromotionByCode:(nonnull NSString *)code success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func activatePromotions(identifiers: [PromotionIdentifier], success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)activatePromotionsWithIdentifiers:(nonnull NSArray *)identifiers success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func deactivatePromotion(uuid: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)deactivatePromotionByUuid:(nonnull NSString *)uuid success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#deactivate-promotion-by-uuid) --- This method deactivates the promotion with the specified code.
```Swift static func deactivatePromotion(code: String, success: ((Bool) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)deactivatePromotionByUuid:(nonnull NSString *)uuid success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func deactivatePromotions(identifiers: [PromotionIdentifier], success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)deactivatePromotionsWithIdentifiers:(nonnull NSArray *)identifiers success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func getOrAssignVoucher(poolUUID: String, success: ((AssignVoucherResponse) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getOrAssignVoucherWithPoolUUID:(NSString *)poolUUID success:(void (^)(SNRAssignVoucherResponse *assignVoucherResponse))success failure:(void (^)(NSError *error))failure ```
[(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.
```Swift static func assignVoucherCode(poolUUID: String, success: ((AssignVoucherResponse) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)assignVoucherCodeWithPoolUUID:(nonnull NSString *)poolUUID success:(nonnull void (^)(SNRAssignVoucherResponse *assignVoucherResponse))success failure:(nonnull void (^)(NSError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/promotions#assign-voucher-code-from-pool) --- This method retrieves voucher codes for a customer.
```Swift static func getAssignedVoucherCodes(success: ((VoucherCodesResponse) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getAssignedVoucherCodesWithSuccess:(nonnull void (^)(SNRVoucherCodesResponse *voucherCodesResponse))success failure:(nonnull void (^)(NSError *error))failure ```
[(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:**
```Swift class Content: NSObject ```
```Objective-C @interface SNRContent : NSObject ```
**Methods:** This method generates the document assigned to a slug.
```Swift static func getDocument(slug: String, success: (([AnyHashable: Any]) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getDocument:(nonnull NSString *)slug success:(nonnull void (^)(NSDictionary *document))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func generateDocument(slug: String, success: ((Document) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)generateDocument:(nonnull NSString *)slug success:(nonnull void (^)(SNRDocument *document))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func generateDocument(apiQuery: DocumentApiQuery, success: ((Document) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)generateDocumentWithApiQuery:(SNRDocumentApiQuery *)apiQuery success:(void (^)(SNRDocument *document))success failure:(void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func getDocuments(apiQuery: DocumentsApiQuery, success: (([[AnyHashable: Any]]) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getDocumentsWithApiQuery:(nonnull SNRDocumentsApiQuery *)apiQuery success:(nonnull void (^)(NSArray *documents))success failure:(nonnull void (^)(NSError *error))failure ```
[(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).
```Swift static func getRecommendations(options: RecommendationOptions, success: ((RecommendationResponse) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getRecommendations:(nonnull SNRRecommendationOptions *)options success:(nonnull void (^)(SNRRecommendationResponse *recommendationResponse))success failure:(nonnull void (^)(NSError *error))failure ```
[(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).
```Swift static func getRecommendationsV2(options: RecommendationOptions, success: ((RecommendationResponse) -> Void), failure: ((Error) -> Void)) ```
```Objective-C + (void)getRecommendationsV2:(nonnull SNRRecommendationOptions *)options success:(nonnull void (^)(SNRRecommendationResponse *recommendationResponse))success failure:(nonnull void (^)(NSError *error))failure ```
[(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.
```Swift static func getScreenView(success: ((ScreenViewResponse) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)getScreenViewWithSuccess:(nonnull void (^)(SNRScreenViewResponse *screenViewResponse))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func generateScreenView(feedSlug: String, success: ((ScreenView) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)generateScreenView:(NSString *)feedSlug success:(nonnull void (^)(SNRScreenView *screenView))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(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.
```Swift static func generateScreenView(apiQuery: ScreenViewApiQuery, success: ((ScreenView) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)generateScreenView:(SNRScreenViewApiQuery *)apiQuery success:(nonnull void (^)(SNRScreenView *screenView))success failure:(nonnull void (^)(SNRApiError *error))failure ```
[(Click for more details)](/developers/mobile-sdk/method-reference/ios/content#generate-screen-view-with-query-parameters) ### 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.seen event
- `recommendation.click` sent when a customer clicks the recommended item.
Recommendation.click event
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
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
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:
{
      "name": "Similar Products",
      "recommendations": "{% recommendations_json3 campaignId=COhsCCOdu8Cg %} {% endrecommendations_json3 %}"
  }
- 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
Content Widget - 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.
#### Example
```java ContentWidgetHorizontalSliderLayout layout = new ContentWidgetHorizontalSliderLayout(); layout.setCardViewSize(250, 300); layout.cardViewHorizontalSpacing = 15; layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent); ```
```kotlin val layout = ContentWidgetHorizontalSliderLayout() layout.setCardViewSize(250, 300) layout.cardViewHorizontalSpacing = 15 layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent) ```
### 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
Content Widget - Grid View
#### Constructor | Parameter | Type | Default | Description | | --- | --- | --- | --- | | preferredWidth | `Float` | - | Preferred width of your widget. You can pass the width in dp (recommended) or px |
```java float screenWidthDp = displayMetrics.widthPixels; ContentWidgetGridLayout layout = new ContentWidgetGridLayout(screenWidthDp); ```
```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.
#### Example
```java float screenWidthDp = displayMetrics.widthPixels; ContentWidgetGridLayout layout = new ContentWidgetGridLayout(screenWidthDp); layout.setCardViewSize(250, 300); layout.cardViewHorizontalSpacing = 15; layout.cardViewVerticalSpacing = 20; layout.includeEdgeSpacing = false; layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent); ```
```kotlin val screenWidthDp = displayMetrics.widthPixels val layout = ContentWidgetGridLayout(screenWidthDp) layout.setCardViewSize(250, 300) layout.cardViewHorizontalSpacing = 15 layout.cardViewVerticalSpacing = 20 layout.includeEdgeSpacing = false layout.cardViewBackgroundColor = ContextCompat.getColor(Synerise.getApplicationContext(), R.color.regent) ```
### 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) ```
#### Example
```java ContentWidgetItemLayout itemLayoutDetails = new ContentWidgetItemLayout(); itemLayoutDetails.cardViewElevation = 5; itemLayoutDetails.cardViewCornerRadius = 10; itemLayoutDetails.imageHeightToCardHeightRatio = 0.6 itemLayoutDetails.imageWidthToCardWidthRatio = 1; itemLayoutDetails.imageMargin = 5; 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); 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); ```
```kotlin val itemLayoutDetails = ContentWidgetItemLayout() itemLayoutDetails.cardViewElevation = 5 itemLayoutDetails.cardViewCornerRadius = 10 itemLayoutDetails.imageHeightToCardHeightRatio = 0.6 itemLayoutDetails.imageWidthToCardWidthRatio = 1 itemLayoutDetails.imageMargin = 5 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) 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) ```
## 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
```Java Drawable likeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart); Drawable unlikeHeart = ContextCompat.getDrawable(this, R.drawable.ic_heart_outline); favouriteIcon.setStateDrawables(unlikeHeart, likeHeart); ```
```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.
```java 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 recommendation = (Recommendation) model; ViewUtils.pulse(imageButton); } @Override public boolean onStateCheck(BaseModel model) { return false; } }); itemLayoutDetails.setItemAction(favouriteIcon); ```
```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) ### 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:**
```JavaScript Synerise.Initializer() .withBaseUrl("YOUR_API_BASE_URL") .withApiKey('YOUR_PROFILE_API_KEY') .withDebugModeEnabled(true) .withCrashHandlingEnabled(true) .withSettings({ sdk: { enabled: true }) .init(); ```
## Change Profile API key dynamically --- This method changes a Profile (formerly Client) API key dynamically. **Declared In:** lib/main/Synerise.js **Declaration:**
public static changeApiKey(ApiKey: string, config?: InitializationConfig | undefined)
Before version 1.0.0, this method was called `changeClientApiKey`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiKey** | string | yes | - | New API key | | **config** | [InitializationConfig](/developers/mobile-sdk/class-reference/react-native/lifecycle#initializationconfig) | no | - | Object for additional initialization settings after the API key change | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.changeApiKey(apiKey); ```
## Change Profile API Key dynamically with config --- This method changes a Profile (formerly Client) API key dynamically, with additional parameters. It can include a salt for [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) requests. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.19.0 | 5.20.0 | 0.23.0 | 1.3.0 | **Declared In:** lib/main/Synerise.js **Declaration:**
public static changeApiKey(ApiKey: string, config?: InitializationConfig | undefined)
Before version 1.0.0, this method was called `changeClientApiKey`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiKey** | string | yes | - | New API key | | **config** | [InitializationConfig](/developers/mobile-sdk/class-reference/react-native/lifecycle#initializationconfig) | no | - | Object for additional initialization settings after the API key change | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.changeApiKey(apiKey); ```
### Android # Method reference - Android ### 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:
<application
              android:name=".App"
              android:allowBackup="true"
              android:icon="@mipmap/ic_launcher"
              android:label="@string/app_name"
              android:roundIcon="@mipmap/ic_launcher_round"
              android:supportsRtl="true"
              android:theme="@style/AppTheme">
              ...
              <service android:name=".service.MyFirebaseMessagingService">
                  <intent-filter>
                      <action android:name="com.google.firebase.MESSAGING_EVENT" />
                  </intent-filter>
              </service>
          </application>
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
```java @Override public void onNewToken(String refreshedToken) { super.onNewToken(refreshedToken); Log.d(TAG, "Refreshed token: " + refreshedToken); if (refreshedToken != null) { 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 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:
<meta-data
               android:name="com.synerise.sdk.messaging.notification_icon"
               android:resource="@drawable/ic_notification_icon" />
      <meta-data
               android:name="com.synerise.sdk.messaging.notification_icon_color"
               android:resource="@color/amaranth" />
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.
```java Synerise.settings.notifications.setEncryption(true); ```
```kotlin Synerise.settings.notifications.setEncryption(true) ```
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) ### 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.
public static IApiCall authenticate(@NonNull String token, @NonNull ClientIdentityProvider provider, @Nullable Agreements agreements, @Nullable Attributes attributes, @Nullable String authId)
[(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.
public static IDataApiCall<AuthConditions> authenticateConditionally(@NonNull String token, @NonNull ClientIdentityProvider provider, @Nullable Agreements agreements, @Nullable Attributes attributes, @Nullable String authId)
[(Click for more details)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-conditionally-by-identityprovider) --- This method authenticates a customer with OAuth.
public static IApiCall authenticateByOAuth(@NonNull String accessToken, @Nullable Agreements agreements, @Nullable Attributes attributes, @Nullable String authId)
[(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.
public static IApiCall authenticateByFacebook(@NonNull String facebookToken, @Nullable Agreements agreements, @Nullable Attributes attributes, @Nullable String authId)
[(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.
public static IApiCall requestEmailChange(String email, String password, @Nullable String externalToken, @Nullable String authId)
[(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:** There are no properties. **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) ### 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_initializer.dart **Class:** [Synerise](/developers/mobile-sdk/class-reference/flutter/lifecycle#synerise) [SyneriseInitializer](/developers/mobile-sdk/class-reference/flutter/lifecycle#syneriseinitializer) **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** | bool | no | - | Enables or disables console logs | | **withCrashHandlingEnabled** | bool | no | - | Enables or disables crash handling | | **setRequestValidationSalt** | String | no | - | Sets salt string for request validation |
Before version 2.0.0, the `withApiKey` method was called `withClientApiKey`.
**Return Value:** No value is returned. **Example:**
```Dart Synerise.initializer() .withBaseUrl("YOUR_API_BASE_URL") .withApiKey("YOUR_PROFILE_API_KEY") .withDebugModeEnabled(false) .init(); ```
## Change Profile API Key dynamically --- This method changes a Profile (formerly Client) API key dynamically. **Declared In:** lib/synerise.dart **Class:** [Synerise](/developers/mobile-sdk/class-reference/flutter/lifecycle#synerise) **Declaration:**
static Future<void> changeApiKey(String apiKey, [InitializationConfig? config]) async
Before version 2.0.0, this method was called `changeClientApiKey`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientApiKey** | String | yes | - | Synerise Profile API Key (formerly Client API key) | | **config** | [InitializationConfig](/developers/mobile-sdk/class-reference/flutter/lifecycle#initializationconfig) | no | - | Object for additional initialization settings after the API key change | **Return Value:** No value is returned. ## Change Profile API Key dynamically with config --- This method changes a Profile (formerly Client) API key dynamically, with additional parameters. It can include a salt for [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) requests. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.19.0 | 5.20.0 | 0.23.0 | 1.3.0 | **Declared In:** lib/synerise.dart **Class:** [Synerise](/developers/mobile-sdk/class-reference/flutter/lifecycle#synerise) **Declaration:**
static Future<void> changeApiKey(String apiKey, [InitializationConfig? config]) async
Before version 2.0.0, this method was called `changeClientApiKey`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientApiKey** | String | yes | - | Synerise Profile API Key (formerly Client API key) | | **config** | [InitializationConfig](/developers/mobile-sdk/class-reference/flutter/lifecycle#initializationconfig) | no | - | Object for additional initialization settings after the API key change | **Return Value:** No value is returned. ## Set up Debug Mode --- This method enables or disables console logs from Synerise SDK.
It is not recommended to use debug mode in the release version of your application.
**Declared In:** lib/main/synerise_initializer.dart **Class:** [Synerise](/developers/mobile-sdk/class-reference/flutter/lifecycle#synerise) **Declaration:**
.withDebugModeEnabled(bool debugModeEnabled)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **enabled** | Bool | yes | - | Enables or disables console logs | **Return Value:** No value is returned. ## Enable Crash Handling --- This method enables or disables crash handling by Synerise SDK.
If set to true, Synerise SDK will send the `client.applicationCrashed` event with information about crash.
**Declared In:** lib/main/synerise_initializer.dart **Class:** [Synerise](/developers/mobile-sdk/class-reference/flutter/lifecycle#synerise) **Declaration:**
.withCrashHandlingEnabled(bool crashHandlingEnabled)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **enabled** | Bool | yes | - | Enables or disables crash handling | **Return Value:** No value is returned. ## Set Request Validation Salt --- This method sets the salt string for request validation. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 | **Declared In:** lib/main/synerise_initializer.dart **Class:** [Synerise](/developers/mobile-sdk/class-reference/flutter/lifecycle#synerise) **Declaration:**
.setRequestValidationSalt(String requestValidationSalt)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **string** | String | yes | - | Synerise Profile salt string for request validation | **Return Value:** No value is returned. ### 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:
{
  "data": {
    "issuer": "Synerise",
    "message-type": "static-content",
    "content-type": "simple-push",
    "content": {
      <<campaign content>>
    }
  }
}
{
  "aps": {
    <<Apple params for iOS notification>>
  },    
  "issuer": "Synerise",
  "message-type": "static-content",
  "content-type": "simple-push",
  "content": {
    <<campaign content>>
  }
}
- `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).
```Swift Synerise.settings.sdk.localizable = [ SNR_LOCALIZABLE_STRING_KEY_OK: "Go in!", SNR_LOCALIZABLE_STRING_KEY_CANCEL: "Go out!" ]; ```
```Objective-C SNRSynerise.settings.sdk.localizable = @[ SNR_LOCALIZABLE_STRING_KEY_OK: @"Go in!", SNR_LOCALIZABLE_STRING_KEY_CANCEL: @"Go out!" ]; ```
```JavaScript Synerise.Settings.sdk.localizable = { LocalizableStringKeyOK: "Go in!", LocalizableStringKeyCancel: "Go out!" }; ```
```Dart Synerise.settings.sdk.localizable = { Localizable.localizableStringKeyOk: "Go in!", Localizable.localizableStringKeyCancel: "Go out!" }; ```
## Blocking campaigns ---
This feature is available only for iOS SDK.
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 { } ```
```Objective-C @interface SampleViewController: UIViewController @end ```
*When View Controller implements that protocol and Synerise tries to run an activity, the activity is skipped.* ### Profile management 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:
<activity
         android:name=".ui.linking.DeepLinkingActivity">
         <intent-filter>
             <action android:name="syne://test" />
             <category android:name="android.intent.category.DEFAULT" />
              <data 
                 android:scheme="syne"
                 android:host="test" />
         </intent-filter>
      </activity>
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:
<activity
         android:name=".ui.linking.DeepLinkingActivity"
         android:parentActivityName=".ui.linking.ParentDeepLinkingActivity">
         <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="test"
                 android:scheme="syne" />
         </intent-filter>
      </activity>
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.
#### Sample implementation {id=handling-open-url-deeplink-actions-in-android}
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.
// MARK: - SyneriseDelegate

func snr_handledAction(url: URL, source: SyneriseSource) {
  if source == .simplePush {
    if UIApplication.shared.canOpenURL(url) {
      UIApplication.shared.openURL(url)
    }
    return
  }

  if source == .simplePush {
    //...
    return
  }
}
#### 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.
// MARK: - SyneriseDelegate

func snr_handledAction(deepLink: String, source: SyneriseSource) {
  if source == .inAppMessage {
    goToHelpWithId(deepLink)
    return
  }

  if source == .simplePush {
    goToMessageWithId(deepLink)
    return
  }
}
#### 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.
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  //...
  //other methods
  func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
    let sourceApplication: String? = options[UIApplication.OpenURLOptionsKey.sourceApplication] as? String
    let annotation: Any? = options[UIApplication.OpenURLOptionsKey.annotation]
        
    let handled: Bool = ApplicationDelegate.shared.application(app, open: url, sourceApplication: sourceApplication, annotation: annotation)
      if handled == true {
        return true
      }
        
      if url.scheme == "sample-swift" {
        applicationController.getMainCoordinator()?.didReceiveDeeplink(host: url.host!, pathComponents: url.pathComponents)
        return true
      }
        
    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).
### 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.
{
         "applinks": {
           "apps": [],
           "details": [
             {
               "appID": “<<TEAM_ID>>.com.synerise.sdk.sample",
               "paths": [
                 "*"
               ]
             }
           ]
         }
       }
4. Configure your app to handle universal links.
```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:
<activity
         android:name=".ui.linking.DeepLinkingActivity">
         <intent-filter>
             <action android:name="syne://test" />
             <category android:name="android.intent.category.DEFAULT" />
              <data 
                 android:scheme="syne"
                 android:host="test" />
         </intent-filter>
      </activity>
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:
<activity
         android:name=".ui.linking.DeepLinkingActivity"
         android:parentActivityName=".ui.linking.ParentDeepLinkingActivity">
         <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="test"
                 android:scheme="syne" />
         </intent-filter>
      </activity>
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:
<activity
         android:name=".ui.linking.DeepLinkingActivity"
         android:parentActivityName=".ui.linking.ParentDeepLinkingActivity">
         <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="test"
                 android:scheme="syne" />
         </intent-filter>
      </activity>
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 }); ```
### Merging profiles with the API
This article describes the endpoints that force merging profiles. For other situations where profiles are merged, see the [User Guide](/docs/crm/profile-merge).
Sometimes, multiple profiles refer to the same customer. In that case, they need to be merged. In such cases, a number of _source_ profiles are merged into a _target_ profile. The source profiles are deleted after merging. After the merge is complete, a [client.merge](/docs/assets/events/event-reference/profiles#clientmerge) event is saved to the target profile. With the endpoints described below, you can force a merge. This can be used to: - merge recognized profiles. In this case, the identifiers (such as email or customId) of the source profiles are lost, as described in ["Properties, tags, and attributes"](#properties-tags-and-attributes). - merge a recognized profile into an anonymous one. In this case, the target profile remains anonymous.
- This operation is **irreversible**. Use it carefully. - The source profiles are **deleted**. - Don't merge more than 20 accounts at once.
## Identities and event history UUIDs (including historical UUIDs) of the source profiles are added to the historical UUIDs of the target profile. Thanks to this, events of source profiles become associated with the target profile.
Moving identities and events when merging
Moving identities and events when merging
The identities (UUIDs) can be found on the profile's card:
Location of the Identities list on a profile's card
Location of the Identities list on a profile's card.
## Properties, tags, and attributes _Properties_ are the data stored **outside of the `attributes` object** of a profile's data: `clientId, email, phone, customId, uuid, firstName, lastName, displayName, company, address, city, province, zipCode, countryCode, birthDate, sex, avatarUrl, anonymous, agreements (object), tags (list)` _Attributes_ are the data stored in the `attributes` object. **When [non-unique emails](/docs/settings/configuration/non-unique-emails) are enabled, the profile's email and marketing agreement are attributes!** To see the properties and attributes of a profile, fetch its data with [`/v4/clients`](https://developers.synerise.com/ProfileManagement/ProfileManagement.html#operation/GetClientData). When profiles are merged: - All properties (including tags) of the source profiles are ignored and lost. - If an attribute already exists in the target profile, it's not modified. In this case, attribute values from the source profiles are lost. - If an attribute from a source profile doesn't exist in the target profile, it's copied into the target profile.
Moving data when merging
Moving data when merging
## Merging with customId
- This operation is **irreversible**. Use it carefully. - The source profiles are **deleted**. - Don't merge more than 20 accounts at once.
The following request merges profiles `lue42` and `mjz84` into a third profile: `tla114`.
curl --location --request POST \
'https://{SYNERISE_API_BASE_PATH}/v4/clients/merge/from/custom-ids/lue42,mjz84/to/custom-id/tla114' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJh...ey4'
For more details, see the [API reference](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/MergeClientsByCustomId). ## Merging with clientId
- This operation is **irreversible**. Use it carefully. - The source profiles are **deleted**. - Don't merge more than 20 accounts at once.
The following request merges profiles `123` and `456` into a third profile: `789`.
curl --location --request POST \
'https://{SYNERISE_API_BASE_PATH}/v4/clients/merge/from/ids/123,456/to/id/789' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJh...ey4'
For more details, see the [API reference](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/MergeClientsByClientId). ### 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 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)
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
{ "action": "client.simpleAuthLogin", "eventUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "unique": null, "createDate": 1689166104952, "label": "Simple Profile Auth client login", "params": { "ip": "xxx.xx.xxx.xx" } }
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/profiles/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 # 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).
```Swift Synerise.setDelegate(YOUR_OBJECT) ```
```Objective-C [SNRSynerise setDelegate:YOUR_OBJECT]; ```
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.
```Swift func snr_initializationError(error: Error) -> Void ```
```Objective-C - (void)SNR_initializationError:(NSError *)error ```
| 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.
```Swift func snr_registerForPushNotificationsIsNeeded() -> Void ```
```Objective-C - (void)SNR_registerForPushNotificationsIsNeeded ```
#### 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.
```Swift func snr_registerForPushNotificationsIsNeeded(origin: PushNotificationsRegistrationOrigin) -> Void ```
```Objective-C - (void)SNR_registerForPushNotificationsIsNeededByOrigin:(SNRPushNotificationsRegistrationOrigin)origin ```
| 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.
```Swift func snr_handledAction(url: URL) -> Void ```
```Objective-C - (void)SNR_handledActionWithURL:(NSURL *)url ```
| 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.
```Swift func snr_handledAction(url: URL, source: SyneriseSource) -> Void ```
```Objective-C - (void)SNR_handledActionWithURL:(NSURL *)url source:(SNRSyneriseSource)source ```
| Parameter | Type | Description | | --- | --- | --- | | **url** | NSURL | URL value from the action of the activity. | | **source** | [SyneriseSource](/developers/mobile-sdk/class-reference/ios/campaigns#synerisesource) | Identifies Synerise campaign source ([SyneriseSource](/developers/mobile-sdk/class-reference/ios/campaigns#synerisesource)). | #### snr_handledAction(url: URL, activity: SyneriseActivity, completionHandler: SyneriseActivityCompletionHandler) {id=snr-handled-url-action-advanced-with-parameters-deprecated} This method is called when Synerise handles URL action from campaign activities.
This method was deprecated in SDK version 5.0.0.
```Swift func snr_handledAction(url: URL, activity: SyneriseActivity, completionHandler: SyneriseActivityCompletionHandler) -> Void ```
```Objective-C - (void)SNR_handledActionWithURL:(NSURL *)url activity:(SNRSyneriseActivity)activity completionHandler:(SNRSyneriseActivityCompletionHandler)completionHandler ```
| 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.
```Swift func snr_handledAction(deepLink: String) -> Void ```
```Objective-C - (void)SNR_handledActionWithDeepLink:(NSString *)deepLink ```
| 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.
```Swift func snr_handledAction(deepLink: String, source: SyneriseSource) -> Void ```
```Objective-C - (void)SNR_handledActionWithDeepLink:(NSString *)deepLink source:(SNRSyneriseSource)source ```
| 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.
This method was deprecated in SDK version 5.0.0.
```Swift func snr_handledAction(deepLink: String, activity: SyneriseActivity, completionHandler: SyneriseActivityCompletionHandler) -> Void ```
```Objective-C - (void)SNR_handledActionWithDeepLink:(NSString *)deepLink activity:(SNRSyneriseActivity)activity completionHandler:(SNRSyneriseActivityCompletionHandler)completionHandler ```
| 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).
```Swift Synerise.setNotificationDelegate(YOUR_OBJECT) ```
```Objective-C [SNRSynerise setNotificationDelegate:YOUR_OBJECT]; ```
#### snr_notificationDidReceive(notificationInfo: NotificationInfo) {id=notification-delegate-notification-did-receive} This method is called when a Synerise notification is received.
```Swift snr_notificationDidReceive(notificationInfo: NotificationInfo) ```
```Objective-C - (void)SNR_notificationDidReceive:(SNRNotificationInfo *)notificationInfo ```
| 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.
```Swift func snr_notificationDidDissmis(notificationInfo: NotificationInfo) ```
```Objective-C - (void)SNR_notificationDidDissmis:(SNRNotificationInfo *)notificationInfo ```
| 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.
```Swift func snr_notificationClicked(notificationInfo: NotificationInfo) ```
```Objective-C - (void)SNR_notificationClicked:(SNRNotificationInfo *)notificationInfo ```
| 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.
```Swift func snr_notificationClicked(notificationInfo: NotificationInfo, actionButton: String) ```
```Objective-C - (void)SNR_notificationActionButtonClicked:(SNRNotificationInfo *)notificationInfo actionButton:(NSString *)actionButton ```
| 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).
```Swift Client.setClientStateDelegate(YOUR_OBJECT) ```
```Objective-C [SNRClient setClientStateDelegate:YOUR_OBJECT]; ```
#### 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.
```Swift func snr_clientIsSignedOut(reason: ClientSessionEndReason) ```
```Objective-C - (void)SNR_clientIsSignedOutWithReason:(SNRClientSessionEndReason)reason ```
| 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).
```Swift Injector.setInAppMessageDelegate(YOUR_OBJECT) ```
```Objective-C [SNRInjector setInAppMessageDelegate:YOUR_OBJECT]; ```
#### 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.
```Swift func snr_shouldInAppMessageAppear(data: InAppMessageData) -> Bool ```
```Objective-C - (BOOL)SNR_shouldInAppMessageAppear:(SNRInAppMessageData *)data ```
| 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.
```Swift func snr_inAppMessageDidAppear(data: InAppMessageData) ```
```Objective-C - (void)SNR_inAppMessageDidAppear:(SNRInAppMessageData *)data ```
| 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.
```Swift func snr_inAppMessageDidDisappear(data: InAppMessageData) ```
```Objective-C - (void)SNR_inAppMessageDidDisappear:(SNRInAppMessageData *)data ```
| 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.
```Swift func snr_inAppMessageDidChangeSize(rect: CGRect) ```
```Objective-C - (void)SNR_inAppMessageDidChangeSize:(CGRect)rect ```
| 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.
```Swift func snr_inAppMessageContextIsNeeded(data: InAppMessageData) -> [AnyHashable: Any]? ```
```Objective-C - (nullable NSDictionary *)SNR_inAppMessageContextIsNeeded:(SNRInAppMessageData *)data ```
| 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:)`.
```Swift func snr_inAppMessageHandledAction(data: InAppMessageData, deepLink: String) ```
```Objective-C - (void)SNR_inAppMessageHandledDeeplinkAction:(SNRInAppMessageData *)data deepLink:(NSString *)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.
```Swift func snr_inAppMessageHandledAction(data: InAppMessageData, url: URL) ```
```Objective-C - (void)SNR_inAppMessageHandledURLAction:(SNRInAppMessageData *)data url:(NSURL *)url ```
| 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.
```Swift func snr_inAppMessageHandledCustomAction(data: InAppMessageData, name: String, parameters: [AnyHashable: Any]) ```
```Objective-C - (void)SNR_inAppMessageHandledCustomAction:(SNRInAppMessageData *)data name:(NSString *)name parameters:(NSDictionary *)parameters ```
| 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. | --- --- ## 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).
```Swift Tracker.setDelegate(YOUR_OBJECT) ```
```Objective-C [SNRTracker setDelegate:YOUR_OBJECT]; ```
#### snr_locationUpdateRequired() {id=tracker-delegate-location-update-required} This method is called when the Tracker module requests a location update.
```Swift func snr_locationUpdateRequired() ```
```Objective-C - (void)SNR_locationUpdateRequired ```
--- --- ## 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.
```Swift NotificationServiceExtension.setDelegate(YOUR_OBJECT) ```
```Objective-C [SNRNotificationServiceExtension setDelegate:YOUR_OBJECT]; ```
#### notificationServiceExtensionDidFailDecryptionWithError(_: Error) {id=notification-service-extension-delegate-notification-service-extension-did-fail-decryption} This method is called when the decryption process fails.
```Swift func notificationServiceExtensionDidFailDecryptionWithError(_: Error) ```
```Objective-C - (void)notificationServiceExtensionDidFailDecryptionWithError:(NSError *)error ```
| 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.
```Swift func notificationServiceExtensionDidFailProcessingWithError(_: Error) ```
```Objective-C - (void)notificationServiceExtensionDidFailProcessingWithError:(NSError *)error ```
| 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.
```Swift let widget = ContentWidget(options: widgetOptions, appearance: widgetAppearance) widget.delegate = YOUR_OBJECT ```
```Objective-C SNRContentWidget *widget = [SNRContentWidget initWithOptions:options andAppearance:appearance]; widget.delegate = YOUR_OBJECT; ```
#### snr_widgetDidLoad(widget: ContentWidget) {id=content-widget-delegate-widget-did-load} This method is called after a widget is loaded.
```Swift func snr_widgetDidLoad(widget: ContentWidget) ```
```Objective-C - (void)SNR_widgetDidLoad:(SNRContentWidget *)widget ```
| 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.
```Swift func snr_widgetDidNotLoad(widget:ContentWidget error: Error) ```
```Objective-C - (void)SNR_widget:(SNRContentWidget *)widget didNotLoadWithError:(NSError *)error ```
| 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.
```Swift func snr_widgetDidReceiveClickAction(widget:ContentWidget model: BaseModel) ```
```Objective-C - (void)SNR_widget:(SNRContentWidget *)widget didReceiveClickActionForModel:(SNRBaseModel *)model ```
| 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.
```Swift func snr_widgetIsLoading(widget: ContentWidget isLoading: Bool) ```
```Objective-C - (void)SNR_widget:(SNRContentWidget *)widget isLoading:(BOOL)isLoading ```
| Parameter | Type | Description | | --- | --- | --- | | **widget** | [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget) | The widget instance that called the delegate method. | | **isLoading** | Bool | Widget's loading state. | #### snr_widgetDidChangeSize(widget: ContentWidget size: CGSize) {id=content-widget-delegate-widget-did-change-size} This method is called when the widget’s size changes.
```Swift func snr_widgetDidChangeSize(widget: ContentWidget size: CGSize) ```
```Objective-C - (void)SNR_widget:(SNRContentWidget *)widget didChangeToSize:(CGSize)size ```
| Parameter | Type | Description | | --- | --- | --- | | **widget** | [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget) | The widget instance that called the delegate method. | | **size** | CGSize | Widget's new size. | --- --- ## InjectorWalkthroughDelegate {id=injector-walkthrough-delegate}
**InjectorWalkthroughDelegate** was removed in 5.0.0 SDK version.
--- --- ## InjectorBannerDelegate {id=injector-banner-delegate}
**InjectorBannerDelegate** was removed in 5.0.0 SDK version.
### iOS # Class reference - iOS ### Customer authentication --- ## Register customer account --- This method registers a new customer with an email, password, and optional data. This method requires the context object with a customer’s email, password, and optional data. Omitted fields are not modified. Depending on the backend configuration, the account may require activation. For details, see [customer registration](/developers/mobile-sdk/user-identification-and-authorization/overview). Do not allow signing in again (or signing up) when a customer is already signed in. Sign the customer out first. Do not create multiple instances nor call this method multiple times before execution. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_REGISTER_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> registerAccount(ClientAccountRegisterContext context, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountRegisterContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountregistercontext) | yes | - | Object with the customer's email, password, and other optional data | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
ClientAccountRegisterContext clientAccountRegisterContext = ClientAccountRegisterContext(email: email, password: password);

await Synerise.client.registerAccount(clientAccountRegisterContext, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> registerAccount(ClientAccountRegisterContext context) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountRegisterContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountregistercontext) | yes | - | Object with the customer's email, password, and other optional data | **Return Value:** No value is returned. **Example:**
await Synerise.client.registerAccount(clientAccountRegisterContext).catchError((error)
## Request customer account activation --- This method requests sending an email with a URL that confirms the registration and activates the account. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> requestAccountActivation(String email,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
Before version 2.0.0, this method was called `activateAccount` **Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s email | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.synerise-flutter-sdkAccount(email, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> activateAccount(String email) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s email | **Return Value:** No value is returned. **Example:**
await Synerise.client.activateAccount(email).catchError((error)
## Confirm customer account activation --- This method confirms a customer account with the confirmation token. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 400 status code if the account is already confirmed or 404 if the account does not exist.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> confirmAccountActivation(String token, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
Before version 1.0.0, this method was called `confirmAccount`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Customer’s token provided by email | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmAccountActivation(token, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> confirmAccountActivation(String token) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Customer’s token provided by email | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmAccount(token).catchError((error)
## Request customer account activation by pin --- This method requests a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> requestAccountActivationByPin(String email, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.requestAccountActivationByPin(email, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> requestAccountActivationByPin(String email) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | **Return Value:** No value is returned. **Example:**
await Synerise.client.requestAccountActivationByPin(email).catchError((error) {
## Confirm customer account activation by pin --- This method confirms a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> confirmAccountActivationByPin(String email, String pinCode, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **pinCode** | String | yes | Code sent to a customer's email | | **email** | String | yes | Customer's email | | **onSuccess** | Function() | yes | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmAccountActivationByPin(email, pinCode, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> confirmAccountActivationByPin(String email, String pinCode) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **pinCode** | String | yes | Code sent to a customer's email | | **email** | String | yes | Customer's email | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmAccountActivationByPin(email, pinCode).catchError((error) {
## Sign in a customer --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. **Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> signIn(String email, String password, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s email | | **password** | String | yes | - | Customer’s password | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.signIn(email, password, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> signIn(String email, String password) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s email | | **password** | String | yes | - | Customer’s password | **Return Value:** No value is returned. **Example:**
await Synerise.client.signIn(email,password).catchError((error)
## Sign in a customer conditionally --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthresult) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> signInConditionally(String email, String password,
      {required void Function(ClientConditionalAuthResult) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | | **password** | String | yes | Customer's password | **Return Value:** No value is returned. **Example:**
```Dart await Synerise.client.signInConditionally(email, password, onSuccess: (ClientConditionalAuthResult result) { //onSuccess handling }, onError: (SyneriseError error) { //onError handling }); ```
**Declaration:**
Future<ClientConditionalAuthResult> signInConditionally(String email, String password) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | | **password** | String | yes | Customer's password | **Return Value:** [ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthresult) **Example:**
```Dart await Synerise.client.signInConditionally(email, password).catchError((error) ```
## Authenticate customer by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. If an account for the customer does not exist and the identity provider is different than Synerise, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | 0.3.0 | **Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientAuthContext](/developers/mobile-sdk/class-reference/flutter/client#clientauthcontext) [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> authenticate(ClientAuthContext clientAuthContext, IdentityProvider identityProvider, String tokenString,
    {required void Function(bool) onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientAuthContext** | [ClientAuthContext](/developers/mobile-sdk/class-reference/flutter/client#clientauthcontext) | yes | - | Object which contains agreements, attributes, and identifier of authorization | | **identityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) | yes | - | Provider of your token | | **tokenString** | String | yes | - | Token retrieved from provider | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.authenticate(clientAuthContext, identityProvider, tokenString, onSuccess: (bool result) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<bool> authenticate(ClientAuthContext clientAuthContext, IdentityProvider identityProvider, String tokenString) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientAuthContext** | [ClientAuthContext](/developers/mobile-sdk/class-reference/flutter/client#clientauthcontext) | yes | - | Object which contains agreements, attributes, and identifier of authorization | | **identityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) | yes | - | Provider of your token | | **tokenString** | String | yes | - | Token retrieved from provider | **Return Value:** **true** if the operation is success, otherwise it throws an error. **Example:**
await Synerise.client.authenticate(clientAuthContext, identityProvider, tokenString).catchError((error)
## Authenticate customer conditionally by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthresult) [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> authenticateConditionally(ClientAuthContext clientAuthContext, IdentityProvider identityProvider, String tokenString,
    {String? authID, required void Function(ClientConditionalAuthResult) onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Optional | Description | | --- | --- | --- | --- | | **clientAuthContext** | [ClientAuthContext](/developers/mobile-sdk/class-reference/flutter/client#clientauthcontext) | no | Object which contains agreements and attributes | | **identityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) | no | Provider of your token | | **tokenString** | String | no | Token retrieved from provider | | **authID** | String | yes | Optional identifier of authorization | | **onSuccess** | Function([ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthresult) result) | yes | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | Function to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
Token token = Token(tokenString: "tokenString", origin: TokenOrigin.anonymous, expirationDate: DateTime;
    await Synerise.client.retrieveToken(onSuccess: (Token token) {
      token = token;
    }, onError: (SyneriseError error) {
    //onError handling
    });
    String tokenString = token.tokenString;
    IdentityProvider identityProvider = IdentityProvider.oauth;
    
    await Synerise.client.authenticateConditionally(identityProvider, tokenString, onSuccess: (ClientConditionalAuthResult result) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<ClientConditionalAuthResult> authenticateConditionally(ClientAuthContext clientAuthContext, IdentityProvider identityProvider, String tokenString) async
**Parameters:** | Parameter | Type | Optional | Description | | --- | --- | --- | --- | | **token** | String | no | Token retrieved from provider | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) | no | Provider of your token | | **authID** | String | yes | Optional identifier of authorization | | **context** | [ClientConditionalAuthContext](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthcontext) | no | Object which contains agreements and attributes |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** [ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthresult) **Example:**
ClientAgreements? agreements = ClientAgreements(push: false, rfid: false, wifi: false);
    Map<String, Object>? attributes;
    ClientAuthContext clientAuthContext = ClientAuthContext(authId: 'AUTH_ID', agreements: agreements, attributes: attributes);
    Token token = await Synerise.client.retrieveToken().catchError((error) {
      String errorMessage = Utils.handlePlatformException(error);
      Utils.displaySimpleAlert("error on handling api call \n $errorMessage", context);
      throw Exception(errorMessage);
    });
    String tokenString = token.tokenString;
    IdentityProvider identityProvider = IdentityProvider.oauth;
    
    ClientConditionalAuthResult result =
        await Synerise.client.authenticateConditionally(clientAuthContext, identityProvider, tokenString).catchError((error) {
      String errorMessage = Utils.handlePlatformException(error);
      Utils.displaySimpleAlert("error on handling api call: you need to be signed in to authenticate \n $errorMessage", context);
      throw Exception(errorMessage);
    });
## Authenticate customer via Simple Profile Authentication --- This method authenticates a customer with Simple Profile Authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 |
When you use this method, you must set a request validation salt by using the `Synerise.setRequestValidationSalt(_:)` method (if salt is enabled for Simple Profile Authentication).
The API key must have the `SAUTH_SIMPLE_AUTH_CREATE` from the **Auth** group.
**Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientSimpleAuthenticationData](/developers/mobile-sdk/class-reference/flutter/client#clientsimpleauthenticationdata) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> simpleAuthentication(ClientSimpleAuthenticationData data, String authID, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **data** | [ClientSimpleAuthenticationData](/developers/mobile-sdk/class-reference/flutter/client#clientsimpleauthenticationdata) | yes | Object which contains customer data | | **authID** | String | yes | Required identifier of authorization | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
ClientSimpleAuthenticationData data =
        ClientSimpleAuthenticationData(firstName: firstName, lastName: lastName, email: email, customId: customID);
    await Synerise.client.simpleAuthentication(data, authID, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> simpleAuthentication(ClientSimpleAuthenticationData clientSimpleAuthenticationData, String authID) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **data** | [ClientSimpleAuthenticationData](/developers/mobile-sdk/class-reference/flutter/client#clientsimpleauthenticationdata) | yes | - | Object which contains customer data | | **authID** | String | yes | null | Required identifier of authorization |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned.
## Check if a customer is signed in (via RaaS, OAuth, Facebook, Apple) --- This method checks if a customer is signed in (via Synerise Authentication - RaaS, OAuth, Facebook, Apple). **Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client) **Declaration:**
Future<bool> isSignedIn() async
**Return Value:** **true** if the customer is signed in, otherwise returns **false**. **Example:**
bool isSignedInBool = await Synerise.client.isSignedIn();
## Check if a customer is signed in (via Simple Profile Authentication) --- This method checks if a customer is signed in (via Simple Profile Authentication). | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 | **Declared In:** lib/modules/client/client_impl.dart **Class:** [Client](/developers/mobile-sdk/class-reference/flutter/modules#client) **Declaration:**
Future<bool> isSignedInViaSimpleAuthentication() async
**Return Value:** **true** if the customer is signed in (via Simple Profile Authentication), otherwise returns **false**. **Example:**
await Synerise.client
        .isSignedInViaSimpleAuthentication()
        .then((bool result) {
      if (result == true) {
        //result handling
      } else {
        //error handling
      }
    });
## Sign out a customer --- This method signs out a customer out.
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client) **Declaration:**
Future<void> signOut() async
**Return Value:** No value is returned. **Example:**
```Dart Synerise.client.signOut().whenComplete(() => { //onSuccess handling }); ```
## Sign out customer with mode or from all devices --- This method signs out a customer out with a chosen mode and Determines if the method should sign out all devices. Available modes: - `.signOut` mode signs out the customer. - `.signOutWithSessionDestroy` mode signs out the customer and additionally, clears the anonymous session and regenerates the customer UUID. The `fromAllDevices` parameter determines whether the method should notify the backend to sign out all devices. **IMPORTANT: It is an asynchronous method.** | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.11.0 | 5.1.0 | 0.14.0 | 1.0.0 |
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> signOutWithMode(ClientSignOutMode mode, bool fromAllDevices, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **mode** | [ClientSignOutMode](/developers/mobile-sdk/class-reference/flutter/client#clientsignoutmode) | yes | Mode of signing out | | **fromAllDevices** | bool | yes | Determines if the method should sign out all devices | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
ClientSignOutMode mode = ClientSignOutMode.signOutWithSessionDestroy;
    bool fromAllDevices = true;
    await Synerise.client.signOutWithMode(mode, fromAllDevices, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> signOutWithMode(ClientSignOutMode mode, bool fromAllDevices) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **mode** | [ClientSignOutMode](/developers/mobile-sdk/class-reference/flutter/client#clientsignoutmode) | yes | Mode of signing out | | **fromAllDevices** | bool | yes | Determines if the method should sign out all devices | **Return Value:** No value is returned. **Example:**
ClientSignOutMode mode = ClientSignOutMode.signOutWithSessionDestroy;
    bool fromAllDevices = true;
    await Synerise.client.signOutWithMode(mode, fromAllDevices).catchError((error) {
### API # Synerise API In this section, the cURL examples use a `{SYNERISE_API_BASE_PATH}` variable in the endpoint URLs. This value depends on where your instance of Synerise is hosted: - `https://api.synerise.com` for Microsoft Azure EU environment - `https://api.azu.synerise.com` for Microsoft Azure USA environment - `https://api.geb.synerise.com` for Google Cloud Platform environment ### Huawei integration in Android SDK ## Enable integration in the Synerise platform Before you start integrating Huawei services in your app, you must configure the integration in Synerise platform. For instructions, see ["Huawei integration"](/docs/settings/tool/huawei-integration). ## Configuration In order to integrate Huawei Mobile Services with Synerise, you must add `.mesaggingServiceType(MessagingServiceType)` to your `Synerise.Builder`. We recommend passing `MessagingServiceType.HMS` as an argument when you build the app for AppGallery.
More information about `Synerise.Builder` is available in ["Configuration"](/developers/mobile-sdk/installation-and-configuration/android#configuration).
## Implementing Huawei notifications in applications 1. Register your service in the AndroidManifest:
<application
           android:name=".App"
           android:allowBackup="true"
           android:icon="@mipmap/ic_launcher"
           android:label="@string/app_name"
           android:roundIcon="@mipmap/ic_launcher_round"
           android:supportsRtl="true"
           android:theme="@style/AppTheme">
           ...
           <service
           android:name=".service.MyPushService"
           android:exported="false">
           <intent-filter>
               <action android:name="com.huawei.push.action.MESSAGING_EVENT" />
           </intent-filter>
       </service>
       </application>
2. In `onRegisterForPush`, pass the huaweiToken using the [`Client.registerForPush(token, pushAgreement)` method](/developers/mobile-sdk/method-reference/android/campaigns#register-for-push-notifications). 3. Add the Huawei registration method:
```kotlin override fun onNewToken(p0: String?, p1: Bundle?) { super.onNewToken(p0, p1) val call = Client.registerForPush(p0!!, true) call.execute( { Log.i(TAG, "Register for Push succeed: $p0") } ) { apiError: Any? -> Log.i(TAG, "Register for push failed:" + apiError.toString()) } Log.i(TAG, p0!!) Log.i(TAG, "receive token: $p0") } ```
1. Pass the incoming push notification payload to the `Injector` in your `HmsMessageService` implementation:
```kotlin val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) override fun onMessageReceived(p0: RemoteMessage?) { super.onMessageReceived(p0) val data: Map = p0!!.dataOfMap scope.launch { Injector.handlePushPayload(data) } } ```
For more information, visit [Huawei Codelab](https://developer.huawei.com/consumer/en/codelab/HMSPushKit/index.html#0).
## Links and Deep Links In order to implement links and deep links, refer to [this](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-android) instruction. ## Configuring notification encryption Instructions for encrypting push notifications are available [here](/developers/mobile-sdk/configuring-push-notifications/android#configure-notification-encryption). ### iOS # Content Widget (iOS) 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.seen event
- `recommendation.click` sent when a customer clicks the recommended item.
Recommendation.click event
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
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
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:
{
      "name": "Similar Products",
      "recommendations": "{% recommendations_json3 campaignId=COhsCCOdu8Cg %} {% endrecommendations_json3 %}"
  }
- 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`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetoptions) and [`ContentWidgetAppearance`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) settings first. | Class | Description | | --- | --- | | [`ContentWidgetOptions`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetoptions) | [`ContentWidgetOptions`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetoptions) contains options for business logic, such as the slug, product identifier, and so on. [Read more](#options). | | [`ContentWidgetAppearance`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) | [`ContentWidgetAppearance`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) contains the UI configuration. [Read more](#options). | The example below is the most basic implementation.
```swift let options = ContentWidgetOptions() options.slug = "similar" options.mapping = { model in guard let imageURLString = model.attributes["imageLink"] as? String, let imageURL = URL(string: imageURLString), let title = model.attributes["title"] as? String, let priceDictionary = model.attributes["price"] as? [AnyHashable: Any], let priceValue = priceDictionary["value"] as? Double else { return nil } let dataModel = ContentWidgetRecommendationDataModel(imageURL: imageURL, title: title, priceCurrency: "PLN", price: NSNumber(value: priceValue), salePrice: nil) if let salePriceDictionary = model.attributes["salePrice"] as? [AnyHashable: Any], let salePriceValue = salePriceDictionary["value"] as? Double { dataModel.salePriceValue = NSNumber(floatLiteral: salePriceValue) } let badgeDataModel = ContentWidgetBadgeDataModel(backgroundColor: UIColor.black, textColor: UIColor.white, text: "Black Week") dataModel.badge = badgeDataModel return dataModel } let gridLayout = ContentWidgetGridLayout() let itemLayout = ContentWidgetBasicProductItemLayout() let appearance = ContentWidgetAppearance(widgetLayout: gridLayout, itemLayout: itemLayout) let widget = ContentWidget(options: options, appearance: appearance) let widgetView = widget.getView() widgetView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height) view.addSubview(widgetView) ```
```objective-c SNRContentWidgetOptions *options = [SNRContentWidgetOptions new]; options.slug = @"similar"; options.mapping = ^(SNRContentWidgetRecommendationModel *model) { NSString *imageURLString = model.attributes[@"imageLink"]; NSString *imageURL = [[NSURL alloc] initWithString:imageURLString]; NSString *title = model.attributes[@"title"]; NSDictionary *priceDictionary = model.attributes[@"price"]; NSNumber *priceValue = priceDictionary[@"value"]; if (imageURL == nil || title == nil || priceValue == nil) { return nil; } SNRContentWidgetRecommendationDataModel *dataModel = [[SNRContentWidgetRecommendationDataModel alloc] initWithimageURL:imageURL title:title priceCurrency:@"PLN" price:priceValue salePrice:nil]; NSDictionary *salePriceDictionary = model.attributes[@"salePrice"]; NSNumber *salePriceValue = salePriceDictionary[@"value"]; if (salePrice != nil) { dataModel.salePriceValue = salePriceValue; } SNRContentWidgetBadgeDataModel *badgeDataModel = [[SNRContentWidgetBadgeDataModel alloc] initWithBackgroundColor:backgroundColor textColor:textColor text:text]; dataModel.badge = badgeDataModel; return dataModel; } SNRContentWidgetGridLayout *gridLayout = [SNRContentWidgetGridLayout new]; SNRContentWidgetBasicProductItemLayout *itemLayout = [SNRContentWidgetBasicProductItemLayout new]; SNRContentWidgetAppearance *appearance = [[SNRContentWidgetAppearance alloc] initWithLayout:gridLayout andItemLayout:itemLayout]; SNRContentWidget *widget = [[SNRContentWidget alloc] initWithOptions:options andAppearance:appearance]; UIView *widgetView = [widget getView]; widgetView.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height); [self.view addSubview:widgetView]; ```
## Options --- The [`ContentWidgetRecommendationsOptions`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetoptions) class is responsible for defining the business logic options of the widget, for example: - slug of the document - product identifier - recommendation data model mapper The table explains the parameters that can be configured in [`ContentWidgetRecommendationsOptions`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetoptions). | Parameter | Type | Default | Description | | --- | --- | --- | --- | | slug | `String` | nil | Slug of a document | | productID | `String` | nil | Product identifier for generating data | | mapping | `((ContentWidgetRecommendationModel) -> (ContentWidgetRecommendationDataModel?))` | nil | Mapping block responsible for mapping data from the feed to a `ContentWidgetRecommendationDataModel` | | recommendationEventType | `ContentWidgetRecommendationEventType` | - | Recommendation event type.
  • **.view** sends all products in one event. We highly recommend using this type of event in content widget.
  • **.seen** sends each event as a separate event.
|
```swift let widgetOptions = ContentWidgetRecommendationsOptions() widgetOptions.slug = "similar" widgetOptions.productID = "12345" widgetOptions.mapping = { model in guard let imageURLString = model.attributes["imageLink"] as? String, let imageURL = URL(string: imageURLString), let title = model.attributes["title"] as? String, let priceDictionary = model.attributes["price"] as? [AnyHashable: Any], let priceValue = priceDictionary["value"] as? Double else { return nil } let dataModel = ContentWidgetRecommendationDataModel(imageURL: imageURL, title: title, priceCurrency: "PLN", price: NSNumber(value: priceValue), salePrice: nil) if let salePriceDictionary = model.attributes["salePrice"] as? [AnyHashable: Any], let salePriceValue = salePriceDictionary["value"] as? Double { dataModel.salePriceValue = NSNumber(floatLiteral: salePriceValue) } let badgeDataModel = ContentWidgetBadgeDataModel(backgroundColor: UIColor.black, textColor: UIColor.white, text: "Black Week") dataModel.badge = badgeDataModel return dataModel } ```
```objective-c SNRContentWidgetRecommendationsOptions *widgetOptions = [SNRContentWidgetRecommendationsOptions new]; widgetOptions.slug = @"similar"; widgetOptions.productID = @"12345"; widgetOptions.mapping = ^(SNRContentWidgetRecommendationModel *model) { NSString *imageURLString = model.attributes[@"imageLink"]; NSString *imageURL = [[NSURL alloc] initWithString:imageURLString]; NSString *title = model.attributes[@"title"]; NSDictionary *priceDictionary = model.attributes[@"price"]; NSNumber *priceValue = priceDictionary[@"value"]; if (imageURL == nil || title == nil || priceValue == nil) { return nil; } SNRContentWidgetRecommendationDataModel *dataModel = [[SNRContentWidgetRecommendationDataModel alloc] initWithimageURL:imageURL title:title priceCurrency:@"PLN" price:priceValue salePrice:nil]; NSDictionary *salePriceDictionary = model.attributes[@"salePrice"]; NSNumber *salePriceValue = salePriceDictionary[@"value"]; if (salePrice != nil) { dataModel.salePriceValue = salePriceValue; } SNRContentWidgetBadgeDataModel *badgeDataModel = [[SNRContentWidgetBadgeDataModel alloc] initWithBackgroundColor:backgroundColor textColor:textColor text:text]; dataModel.badge = badgeDataModel; return dataModel; } ```
## Appearance --- The [`ContentWidgetAppearance`](/developers/mobile-sdk/class-reference/ios/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`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgethorizontalsliderlayout) and [`ContentWidgetGridLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetgridlayout). - **Item layout class**: defines appearance and parameters for the item in the widget. Currently, there is only one layout provided: [`ContentWidgetBasicProductItemLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetbasicproductitemlayout). The table explains the parameters that can be configured in [`ContentWidgetAppearance`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance). | Parameter | Type | Default | Description | | --- | --- | --- | --- | | layout | [`ContentWidgetLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetlayout) | - | Class that inherits from [`ContentWidgetLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetlayout) contains the UI details of `widgetLayout` | | itemLayout | [`ContentWidgetItemLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetitemlayout) | - | Class that inherits from [`ContentWidgetItemLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetitemlayout) contains the UI details of a single item in a widget | ## Widget layouts --- ### Horizontal Slider This layout is intended to present recommendations in a fixed-hight horizontal scrollable slider. **Example widget configuration with horizontal slider:** Content Widget - Horizontal Slider #### Parameters The table explains the parameters of `SNRContentWidgetHorizontalLayout`. | Property | Type | Default | Description | | --- | --- | --- | --- | | backgroundColor | `UIColor` | UIColor.clearColor | Background color of a widget | | insets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner widget margins in pt | | itemSize | `CGSize` | (150.0, 200.0) | Size of a single item in pt | | itemSpacing | `CGFloat` | 16.0 | Horizontal spacing between items in pt | | numberOfItems | `Int` | - | A **read-only** property. It returns the number of items after a widget is loaded | #### Example
```swift let horizontalSliderLayout = ContentWidgetHorizontalSliderLayout() horizontalSliderLayout.insets = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0) horizontalSliderLayout.itemSize = CGSize(width: 150, height: 350) horizontalSliderLayout.itemSpacing = 8.0 ```
```objective-c SNRContentWidgetHorizontalSliderLayout *horizontalSliderLayout = [SNRContentWidgetHorizontalSliderLayout new]; horizontalSliderLayout.insets = UIEdgeInsetsMake(16.0f, 16.0f, 16.0f, 16.0f); horizontalSliderLayout.itemSize = CGSizeMake(150.0f, 350.0f); horizontalSliderLayout.itemSpacing = 8.0f; ```
### 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. **Example widget configuration with grid layout:** Content Widget - Grid View #### Parameters The table explains the parameters of the grid layout. | Property | Type | Default | Description | | --- | --- | --- | --- | | backgroundColor | `UIColor` | UIColor.clearColor | Background color of a widget | | insets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner widget margins in pt | | itemSize | `CGSize` | (150.0, 200.0) | Size of a single item in pt| | itemHorizontalSpacing | `CGFloat` | 16.0 | Horizontal spacing between items in pt | | itemVerticalSpacing | `CGFloat` | 16.0 | Vertical spacing between items in pt | | numberOfItems | `Int` | - | A **read-only** property. It returns the number of items after the widget is loaded | #### Example
```swift let gridLayout = ContentWidgetGridLayout() gridLayout.insets = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0) gridLayout.itemSize = CGSize(width: 150, height: 350) gridLayout.horizontalItemSpacing = 8.0 gridLayout.verticalItemSpacing = 8.0 ```
```objective-c SNRContentWidgetGridLayout *gridLayout = [SNRContentWidgetGridLayout new]; gridLayout.insets = UIEdgeInsetsMake(16.0f, 16.0f, 16.0f, 16.0f); gridLayout.itemSize = CGSizeMake(150.0f, 350.0f); gridLayout.horizontalItemSpacing = 8.0f; gridLayout.verticalItemSpacing = 8.0f; ```
## Widget Item layouts --- ### Basic Product 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 all parameters you can configure in the basic item layout. | Property | Type | Default | Description | | --- | --- | --- | --- | | backgroundColor | `UIColor` | UIColor.whiteColor | Background color of an item | | cornerRadius | `CGFloat` | 0.0 | Radius of the item corners | | borderWidth | `CGFloat` | 0.0 | Width of the item's border | | borderColor | `CGFloat` | nil | Color of the item's border | | shadowColor | `UIColor` | nil | Color of the item's shadow | | imageWidthRatio | `CGFloat` | 1.0 | Image width. A ratio of `1.0` means that the image width equals to 100% of the entire height of the item | | imageHeightRatio | `CGFloat` | 0.35 | Image height. A ratio of `0.35` means that image height equals to 35% of the entire height of the item | | imageBackground | `UIColor` | UIColor.clearColor | Background color of the image | | imageContentMode | `UIViewContentMode` | UIViewContentMode.scaleToFill | Display content mode of the image | | topTextInsets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner margins of the top text label | | topTextFont | `UIFont` | UIFont.systemFont(ofSize: 16.0) | Font of the top text label | | topTextFontColor | `UIColor` | UIColor.blackColor | Color of the top text label | | topTextAlignment | `NSTextAlignment` | NSTextAlignment.center | Alignment of the top text label | | titleInsets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner margins of the title label | | titleFont | `UIFont` | UIFont.systemFont(ofSize: 16.0) | Font of the title label | | titleFontColor | `UIColor` | UIColor.blackColor | Color of the title label | | titleAlignment | `NSTextAlignment` | NSTextAlignment.center | Alignment of the title label | | subtitleInsets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner margins of the subtitle label | | subtitleFont | `UIFont` | UIFont.systemFont(ofSize: 16.0) | Font of the subtitle label | | subtitleFontColor | `UIColor` | UIColor.blackColor | Color of the subtitle label | | subtitleAlignment | `NSTextAlignment` | NSTextAlignment.center | Alignment of the subtitle label | | identifierInsets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner margins of the identifier label | | identifierFont | `UIFont` | UIFont.systemFont(ofSize: 16.0) | Font of the identifier label | | identifierFontColor | `UIColor` | UIColor.blackColor | Color of the identifier label | | identifierAlignment | `NSTextAlignment` | NSTextAlignment.center | Alignment of the identifier label | | priceInsets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner margins of the price label | | priceFont | `UIFont` | UIFont.systemFont(ofSize: 14.0) | Font of the price label | | priceFontColor | `UIColor` | UIColor.blackColor | Color of the price label | | priceAlignment | `NSTextAlignment` | NSTextAlignment.center | Alignment of the price label | | priceGroupSeparator | `String` | nil | Separator of price group | | priceDecimalSeparator | `String` | nil | Separator of price decimal | | priceCurrencyPosition | `ContentWidgetPriceCurrencyPosition` | .right | Determines the side on which the price currency is | | isSalePriceVisible | `Bool` | true | Flag determining whether to show the sale price label or not | | salePriceOrientation | `UILayoutConstraintAxis` | UILayoutConstraintAxis.Horizontal | Orientation of the sale price label | | isDiscountPercentageVisible | `Bool` | true | Flag determining whether to show the discount percentage label or not | | discountPercentageFont | `UIFont` | UIFont.systemFont(ofSize: 10.0) | Font of the discount percentage label | | discountPercentageFontColor | `UIColor` | UIColor.blackColor | Font of the discount percentage label | | regularPriceFont | `UIFont` | nil | Font of the regular price label | | regularPriceFontColor | `UIColor` | nil | Color of the sale regular label | | salePriceFont | `UIFont` | nil | Font of the sale price label | | salePriceFontColor | `UIColor` | nil | Color of the sale price label | | loyaltyPointsInsets | `UIEdgeInsets` | (8.0, 8.0, 8.0, 8.0) | Inner margins of the loyalty points label | | loyaltyPointsAlignment | `NSTextAlignment` | NSTextAlignment.left | Alignment of the loyalty points label | | loyaltyPointsNumberFont | `UIFont` | UIFont.systemFont(ofSize: 16.0) | Font of the loyalty points number label | | loyaltyPointsNumberFontColor | `UIColor` | UIColor.blackColor | Color of the loyalty points number label | | loyaltyPointsTextFont | `UIFont` | UIFont.systemFont(ofSize: 16.0) | Font of the loyalty points text label | | loyaltyPointsTextFontColor | `UIColor` | UIColor.blackColor | Color of the loyalty points text label | | loyaltyPointsText | `UIFont` | 'Loyalty points' | Text after the number of loyalty points | | badge | `SNRContentWidgetBadgeItemLayoutPartial` | nil | Optional badge view | | actionButton | `SNRContentWidgetImageButtonCustomAction` | nil | Optional button for your own custom action | #### Example
```swift let itemLayout = ContentWidgetBasicProductItemLayout() itemLayout.imageWidthRatio = 1.0 itemLayout.imageHeightRatio = 0.4 itemLayout.borderWidth = 2.0 itemLayout.borderColor = UIColor.black itemLayout.shadowColor = UIColor.black itemLayout.cornerRadius = 12.0 ```
```objective-c SNRContentWidgetBasicProductItemLayout *itemLayout = [SNRContentWidgetBasicProductItemLayout new]; itemLayout.imageWidthRatio = 1.0f; itemLayout.imageHeightRatio = 0.4f; itemLayout.borderWidth = 2.0f; itemLayout.borderColor = [UIColor blackColor]; itemLayout.shadowColor = [UIColor blackColor]; itemLayout.cornerRadius = 12.0f; ```
## Interaction with the Widget --- ### Public Interface `load()` - Starts fetching data and creates a view structure of the widget. `isLoaded()` - Checks whether the widget is successfully loaded. `getView()` - Gets the root view of the whole widget view structure. ### Delegation [`ContentWidgetDelegate`](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#content-widget-delegate) is used to inform developers about the state of a widget. - `snr_widgetIsLoading(widget:isLoading:)` - Called when the widget’s loading state changes. It's an **optional** method. - `snr_widgetDidLoad(widget:)` - Called after the widget is loaded. It's a **required** method. - `snr_widgetDidNotLoad(widget:error:)` - Called when an error occurs while loading. It's a **required** method. - `snr_widgetDidChangeSize(widget:size:)` - Called when the widget size changes. It's an **optional** method. - `snr_widgetDidReceiveClickAction(widget:model:)` - Called when the customer clicks a widget item. It's a **required** method.
Check the [`ContentWidgetDelegate`](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#content-widget-delegate) section for more details.
### Image Button Custom Action [`ContentWidgetImageButtonCustomAction`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetbasecustomaction) is used to add an image button to your widget (only if the item layout allows). You can add a button with a single state or make it selectable. #### Parameters | Property | Type | Default | Description | | --- | --- | --- | --- | | predefinedActionType | [`ContentWidgetBaseCustomActionPredefiniedActionType`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetbasecustomactionpredefiniedactiontype) | .none | It determines which event is sent on click | | size | `CGSize` | CGSize.Zero | Button size | | position | `CGPoint` | CGPoint.Zero | Position | | backgroundColor | `UIColor` | UIColor.clearColor | Background color of the button | | tintColor | `UIColor` | UIColor.blackColor | Fill color of the button's image, if an asset supports it | | image | `UIImage` | nil | Button image | | isSelectable | `Bool` | nil | Flag determining whether the button is selectable | | selectedImage | `UIImage` | nil | Image of the button when the button is selected | | isSelected | `SNRContentWidgetImageButtonCustomActionIsSelectedBlock` | nil | Block/closure to be executed when the widget needs to determine the state of a button in the cell | | onReceiveClickAction | `SNRContentWidgetImageButtonCustomActionReceiveClickActionBlock` | nil | Block/closure to be executed when the button is clicked | #### Block/Closures - `isSelected` - Called when the widget tries to determine button's state. The only one parameter is model of data for the cell (for example [`Recommendation`](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendation)). It's an **optional** property. - `onReceiveClickAction` - Called when the button was clicked. Parameters are model of data for the cell (for example [`Recommendation`](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendation)) and current state of button. It's an **optional** property. ## Sample Implementations --- ### Horizontal Slider This is an example with [`ContentWidgetHorizontalSliderLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgethorizontalsliderlayout). It always has fixed height, so after the widget is loaded, its content height can be calculated. That is why it is done in the `snr_widgetDidLoad(widget:)` method. The widget content size in a horizontal slider layout can be calculated by the `getSize()` method.
```swift class ContentWidgetHorizontalSliderSampleViewController: UIViewController, ContentWidgetDelegate { var widget: ContentWidget! @IBOutlet weak var widgetContainerView: UIView! // MARK: - Lifecycle override func viewDidLoad() { super.viewDidLoad() setupWidget() } // MARK: - Private func setupWidget() -> Void { let options = ContentWidgetRecommendationsOptions() options.slug = "similar" options.productID = "12345" options.mapping = { model in guard let imageURLString = model.attributes["imageLink"] as? String, let imageURL = URL(string: imageURLString), let title = model.attributes["title"] as? String, let priceDictionary = model.attributes["price"] as? [AnyHashable: Any], let priceValue = priceDictionary["value"] as? Double else { return nil } let dataModel = ContentWidgetRecommendationDataModel(imageURL: imageURL, title: title, priceCurrency: "PLN", price: NSNumber(value: priceValue), salePrice: nil) if let salePriceDictionary = model.attributes["salePrice"] as? [AnyHashable: Any], let salePriceValue = salePriceDictionary["value"] as? Double { dataModel.salePriceValue = NSNumber(floatLiteral: salePriceValue) } let badgeDataModel = ContentWidgetBadgeDataModel(backgroundColor: UIColor.black, textColor: UIColor.white, text: "Black Week") dataModel.badge = badgeDataModel return dataModel } let horizontalSliderLayout = ContentWidgetHorizontalSliderLayout() horizontalSliderLayout.insets = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0) horizontalSliderLayout.itemSize = CGSize(width: 150, height: 350) horizontalSliderLayout.itemSpacing = 8.0 let itemLayout = ContentWidgetBasicProductItemLayout() itemLayout.imageWidthRatio = 1.0 itemLayout.imageHeightRatio = 0.4 itemLayout.borderWidth = 2.0 itemLayout.borderColor = UIColor.black itemLayout.shadowColor = UIColor.black itemLayout.cornerRadius = 12.0 let actionButton = ContentWidgetImageButtonCustomAction() actionButton.backgroundColor = UIColor.clear actionButton.tintColor = UIColor.black actionButton.image = UIImage(imageLiteralResourceName: "Shop Flow/icon_favorite_add") actionButton.isSelectable = true actionButton.selectedImage = UIImage(imageLiteralResourceName: "Shop Flow/icon_favorite_remove") actionButton.size = CGSize(width: 40, height: 40) actionButton.predefinedActionType = .sendLikeEvent actionButton.onReceiveClickAction = { model, isSelected in if let recommendationModel = model as? Recommendation { print("Content Widget did receive click action for action button \(recommendationModel.title)") } } actionButton.isSelected = { model in return false } itemLayout.actionButton = actionButton itemLayout.actionButtonPosition = CGPoint(x: (150.0 - 40 - 8), y: 8) let appearance = ContentWidgetAppearance(widgetLayout: horizontalSliderLayout, itemLayout: itemLayout) widget = ContentWidget(options: options, appearance: appearance) widget.delegate = self widget.load() } // MARK: - ContentWidgetDelegate func snr_widgetIsLoading(widget: ContentWidget, isLoading: Bool) { print("Content Widget is loading: \(isLoading)") } func snr_widgetDidLoad(widget: ContentWidget) { print("Content Widget did load") let widgetView: UIView = widget.getView() let widgetSize: CGSize = (widget.layout as! ContentWidgetHorizontalSliderLayout).getSize() widgetContainerView.addSubview(widgetView) widgetView.translatesAutoresizingMaskIntoConstraints = false widgetView.topAnchor.constraint(equalTo: widgetContainerView.topAnchor).isActive = true widgetView.bottomAnchor.constraint(equalTo: widgetContainerView.bottomAnchor).isActive = true widgetView.leftAnchor.constraint(equalTo: widgetContainerView.leftAnchor).isActive = true widgetView.rightAnchor.constraint(equalTo: widgetContainerView.rightAnchor).isActive = true widgetContainerView.heightAnchor.constraint(equalToConstant: widgetSize.height).isActive = true } func snr_widgetDidNotLoad(widget: ContentWidget, error: Error) { print("Content Widget did not load. Error: \(error.localizedDescription)") } func snr_widgetDidChangeSize(widget: ContentWidget, size: CGSize) { print("Content Widget did change size to: \(size)") } func snr_widgetDidReceiveClickAction(widget: ContentWidget, model: BaseModel) { if let recommendationModel = model as? Recommendation { print("Content Widget did receive click action for \(recommendationModel.title)") } } } ```
```objective-c @interface ContentWidgetHorizontalSliderSampleViewController : UIViewController @property (weak, nonatomic, nonnull, readwrite) IBOutlet UIView *widgetContainerView; @end @@implementation ContentWidgetHorizontalSliderSampleViewController () @property (strong, nonatomic, nullable, readwrite) SNRContentWidget *widget; @end @@implementation ContentWidgetHorizontalSliderSampleViewController #pragma mark - Lifecycle - (void)viewDidLoad { [super viewDidLoad]; [self setupWidget]; } #pragma mark - Private - (void)setupWidget { SNRContentWidgetOptions *options = [SNRContentWidgetOptions new]; options.slug = @"similar"; options.productID = @"12345"; options.mapping = ^(SNRContentWidgetRecommendationModel *model) { NSString *imageURLString = model.attributes[@"imageLink"]; NSString *imageURL = [[NSURL alloc] initWithString:imageURLString]; NSString *title = model.attributes[@"title"]; NSDictionary *priceDictionary = model.attributes[@"price"]; NSNumber *priceValue = priceDictionary[@"value"]; if (imageURL == nil || title == nil || priceValue == nil) { return nil; } SNRContentWidgetRecommendationDataModel *dataModel = [[SNRContentWidgetRecommendationDataModel alloc] initWithimageURL:imageURL title:title priceCurrency:@"PLN" price:priceValue salePrice:nil]; NSDictionary *salePriceDictionary = model.attributes[@"salePrice"]; NSNumber *salePriceValue = salePriceDictionary[@"value"]; if (salePrice != nil) { dataModel.salePriceValue = salePriceValue; } SNRContentWidgetBadgeDataModel *badgeDataModel = [[SNRContentWidgetBadgeDataModel alloc] initWithBackgroundColor:backgroundColor textColor:textColor text:text]; dataModel.badge = badgeDataModel; return dataModel; } SNRContentWidgetHorizontalSliderLayout *horizontalSliderLayout = [SNRContentWidgetHorizontalSliderLayout new]; horizontalSliderLayout.insets = UIEdgeInsetsMake(16.0f, 16.0f, 16.0f, 16.0f); horizontalSliderLayout.itemSize = CGSizeMake(150.0f, 350.0f); horizontalSliderLayout.itemSpacing = 8.0f; SNRContentWidgetBasicProductItemLayout *itemLayout = [SNRContentWidgetBasicProductItemLayout new]; itemLayout.imageWidthRatio = 1.0f; itemLayout.imageHeightRatio = 0.4f; itemLayout.borderWidth = 2.0f; itemLayout.borderColor = [UIColor blackColor]; itemLayout.shadowColor = [UIColor blackColor]; itemLayout.cornerRadius = 12.0f; SNRContentWidgetImageButtonCustomAction *actionButton = [SNRContentWidgetImageButtonCustomAction new]; actionButton.backgroundColor = [UIColor clearColor]; actionButton.tintColor = [UIColor blackColor]; actionButton.image = [UIImage imageNamed:@"Shop Flow/icon_favorite_add"]; actionButton.isSelectable = YES actionButton.selectedImage = [UIImage imageNamed:@"Shop Flow/icon_favorite_remove"]; actionButton.size = CGSizeMake(40.0f, 40.0f); actionButton.predefinedActionType = SNRContentWidgetBaseCustomActionPredefiniedActionTypeSendLikeEvent; actionButton.onReceiveClickAction = ^(SNRBaseModel *model, BOOL isSelected) { NSLog(@"Content Widget did receive click action for action button %@", ((SNRRecommednation *)recommendationModel.title)); }; actionButton.isSelected = ^(SNRBaseModel *model) { return NO; }; itemLayout.actionButton = actionButton itemLayout.actionButtonPosition = CGPointMake((150.0f - 40.0f - 8), 8.0f) SNRContentWidgetAppearance *appearance = [[SNRContentWidgetAppearance alloc] initWithLayout:horizontalSliderLayout andItemLayout:itemLayout]; SNRContentWidget *widget = [[SNRContentWidget alloc] initWithOptions:options andAppearance:appearance]; widget.delegate = self [widget load]; self.widget = widget; } #pragma mark - SNRContentWidgetDelegate - (void)SNR_widget:(SNRContentWidget *)widget isLoading:(BOOL)isLoading { NSLog(@"Content Widget is loading: %@", isLoading ?? @"true" : @"false"); } - (void)SNR_widgetDidLoad:(SNRContentWidget *)widget { NSLog(@"Content Widget did load"); UIView *widgetView = [widget getView]; CGSize widgetSize = [((SNRContentWidgetHorizontalSliderLayout *)widget.layout getSize]; [self.widgetContainerView addSubview:widgetView]; widgetView.translatesAutoresizingMaskIntoConstraints = NO; [widgetView.topAnchor constraintEqualTo:widgetContainerView.topAnchor].active = YES; [widgetView.bottomAnchor constraintEqualTo:widgetContainerView.bottomAnchor].active = YES; [widgetView.leftAnchor constraintEqualTo:widgetContainerView.leftAnchor].active = YES; [widgetView.rightAnchor constraintEqualTo:widgetContainerView.rightAnchor].active = YES; [widgetContainerView.heightAnchor constraintEqualToConstant:widgetSize.height].active = YES; } - (void)SNR_widget:(SNRContentWidget *)widget didNotLoadWithError:(NSError *)error { NSLog(@"Content Widget did not load. Error: %@", error.localizedDescription); } - (void)SNR_widget:(SNRContentWidget *)widget didChangeToSize:(CGSize)size { NSLog(@"Content Widget did change size to %@", NSStringFromCGSize(size)); } - (void)SNR_widget:(SNRContentWidget *)widget didReceiveClickActionForModel:(SNRBaseModel *)model { if ([model isKindOfClass:[SNRRecommendation class]] == YES) { SNRRecommendation *recommendationModel = ((SNRRecommendation *)model); NSLog(@"Content Widget did receive click action for %@", recommendationModel.title); } } @end ```
### Grid View A basic example with [`ContentWidgetGridLayout`](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetgridlayout) and `UITableViewController`. Remember that cells are prototyped. Initially, the height of the tenth row equals zero, because there is no possibility of getting the correct height of the widget. Before the widget is loaded, we don't know how many items it's going to contain. The widget view is flexible, so it fits the dimensions that you set up. If the height of the widget that you set is smaller than the total height of the generated grid, the content can be scrolled vertically. The grid's content height depends on: - The widget width that you set up - The number of items that have been loaded That is why the code below reloads the tenth row after the widget is loaded. Earlier, it was impossible to calculate the height correctly. In addition, the widget row is reloaded when the `snr_widgetDidChangeSize(widget:size:)` method is called. In this case, it's a required action, because the widget has pinned constraints to superview in a prototyped cell. The widget's content size changes with the tableview size, for example when the screen orientation changes, the widget's height needs to be re-calculated. Otherwise, the cell height may be larger that necessary. The total widget content size in a grid layout can be calculated by the `getSize(preferredWidth:)` method.
```swift class ContentWidgetGridViewSampleViewController: UITableViewController, ContentWidgetDelegate { var widget: ContentWidget! @IBOutlet weak var widgetContainerView: UIView! // MARK: - Lifecycle override func viewDidLoad() { super.viewDidLoad() setupWidget() } func setupWidget() -> Void { let options = ContentWidgetRecommendationsOptions() options.slug = "similar" options.productID = "12345" options.mapping = { model in guard let imageURLString = model.attributes["imageLink"] as? String, let imageURL = URL(string: imageURLString), let title = model.attributes["title"] as? String, let priceDictionary = model.attributes["price"] as? [AnyHashable: Any], let priceValue = priceDictionary["value"] as? Double else { return nil } let dataModel = ContentWidgetRecommendationDataModel(imageURL: imageURL, title: title, priceCurrency: "PLN", price: NSNumber(value: priceValue), salePrice: nil) if let salePriceDictionary = model.attributes["salePrice"] as? [AnyHashable: Any], let salePriceValue = salePriceDictionary["value"] as? Double { dataModel.salePriceValue = NSNumber(floatLiteral: salePriceValue) } let badgeDataModel = ContentWidgetBadgeDataModel(backgroundColor: UIColor.black, textColor: UIColor.white, text: "Black Week") dataModel.badge = badgeDataModel return dataModel } let gridLayout = ContentWidgetGridLayout() gridLayout.insets = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0) gridLayout.itemSize = CGSize(width: 150.0, height: 350.0) gridLayout.horizontalItemSpacing = 8.0 gridLayout.verticalItemSpacing = 8.0 let itemLayout = ContentWidgetBasicProductItemLayout() itemLayout.imageWidthRatio = 1.0 itemLayout.imageHeightRatio = 0.4 itemLayout.borderWidth = 2.0 itemLayout.borderColor = UIColor.black itemLayout.shadowColor = UIColor.black itemLayout.cornerRadius = 12.0 actionButton.onReceiveClickAction = { model, isSelected in if let recommendationModel = model as? Recommendation { print("Content Widget did receive click action for action button \(recommendationModel.title)") } } actionButton.isSelected = { model in return false } itemLayout.actionButton = actionButton itemLayout.actionButtonPosition = CGPoint(x: (150.0 - 40.0 - 8.0), y: 8.0) let appearance = ContentWidgetAppearance(widgetLayout: gridLayout, itemLayout: itemLayout) widget = ContentWidget(options: options, appearance: appearance) widget.delegate = self widget.load() } // MARK: - UITableViewDataSource, UITableViewDelegate override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 10 } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { if indexPath.row == 10 { if widget != nil && widget.isLoaded() { return (widget.layout as! ContentWidgetGridLayout).getSize(preferredWidth: tableView.bounds.size.width).height } else { return 0 } } return 100.0 } // MARK: - ContentWidgetDelegate func snr_widgetIsLoading(widget: ContentWidget, isLoading: Bool) { print("Content Widget is loading: \(isLoading)") } func snr_widgetDidLoad(widget: ContentWidget) { print("Content Widget did load") view.addSubview(widgetView) widgetView = widget.getView() widgetContainerView.addSubview(widgetView) widgetView.translatesAutoresizingMaskIntoConstraints = false widgetView.topAnchor.constraint(equalTo: widgetContainerView.topAnchor).isActive = true widgetView.bottomAnchor.constraint(equalTo: widgetContainerView.bottomAnchor).isActive = true widgetView.leftAnchor.constraint(equalTo: widgetContainerView.leftAnchor).isActive = true widgetView.rightAnchor.constraint(equalTo: widgetContainerView.rightAnchor).isActive = true tableView.reloadData() } func snr_widgetDidNotLoad(widget: ContentWidget, error: Error) { print("Content Widget did not load. Error: \(error.localizedDescription)") } func snr_widgetDidChangeSize(widget: ContentWidget, size: CGSize) { print("Content Widget did change size to: \(size)") tableView.reloadData() } func snr_widgetDidReceiveClickAction(widget: ContentWidget, model: BaseModel) { if let recommendationModel = model as? Recommendation { print("Content Widget did receive click action for \(recommendationModel.title)") } } } ```
```objective-c @interface ContentWidgetGridViewSampleViewController : UITableViewController @property (weak, nonatomic, nonnull, readwrite) IBOutlet UIView *widgetContainerView; @end @@implementation ContentWidgetGridViewSampleViewController () @property (strong, nonatomic, nullable, readwrite) SNRContentWidget *widget; @end @@implementation ContentWidgetGridViewSampleViewController #pragma mark - Lifecycle - (void)viewDidLoad { [super viewDidLoad]; [self setupWidget]; } #pragma mark - Private - (void)setupWidget { SNRContentWidgetOptions *options = [SNRContentWidgetOptions new]; options.slug = @"similar"; options.productID = @"12345"; options.mapping = ^(SNRContentWidgetRecommendationModel *model) { NSString *imageURLString = model.attributes[@"imageLink"]; NSString *imageURL = [[NSURL alloc] initWithString:imageURLString]; NSString *title = model.attributes[@"title"]; NSDictionary *priceDictionary = model.attributes[@"price"]; NSNumber *priceValue = priceDictionary[@"value"]; if (imageURL == nil || title == nil || priceValue == nil) { return nil; } SNRContentWidgetRecommendationDataModel *dataModel = [[SNRContentWidgetRecommendationDataModel alloc] initWithimageURL:imageURL title:title priceCurrency:@"PLN" price:priceValue salePrice:nil]; NSDictionary *salePriceDictionary = model.attributes[@"salePrice"]; NSNumber *salePriceValue = salePriceDictionary[@"value"]; if (salePrice != nil) { dataModel.salePriceValue = salePriceValue; } SNRContentWidgetBadgeDataModel *badgeDataModel = [[SNRContentWidgetBadgeDataModel alloc] initWithBackgroundColor:backgroundColor textColor:textColor text:text]; dataModel.badge = badgeDataModel; return dataModel; } SNRContentWidgetGridLayout *gridLayout = [SNRContentWidgetGridLayout new]; gridLayout.insets = UIEdgeInsetsMake(16.0f, 16.0f, 16.0f, 16.0f); gridLayout.itemSize = CGSizeMake(150.0f, 350.0f); gridLayout.horizontalItemSpacing = 8.0f; gridLayout.verticalItemSpacing = 8.0f; SNRContentWidgetImageButtonCustomAction *actionButton = [SNRContentWidgetImageButtonCustomAction new]; actionButton.backgroundColor = [UIColor clearColor]; actionButton.tintColor = [UIColor blackColor]; actionButton.image = [UIImage imageNamed:@"Shop Flow/icon_favorite_add"]; actionButton.isSelectable = YES actionButton.selectedImage = [UIImage imageNamed:@"Shop Flow/icon_favorite_remove"]; actionButton.size = CGSizeMake(40.0f, 40.0f); actionButton.predefinedActionType = SNRContentWidgetBaseCustomActionPredefiniedActionTypeSendLikeEvent; actionButton.onReceiveClickAction = ^(SNRBaseModel *model, BOOL isSelected) { NSLog(@"Content Widget did receive click action for action button %@", ((SNRRecommednation *)recommendationModel.title)); }; actionButton.isSelected = ^(SNRBaseModel *model) { return NO; }; itemLayout.actionButton = actionButton itemLayout.actionButtonPosition = CGPointMake((150.0f - 40.0f - 8), 8.0f) SNRContentWidgetAppearance *appearance = [[SNRContentWidgetAppearance alloc] initWithLayout:gridLayout andItemLayout:itemLayout]; SNRContentWidget *widget = [[SNRContentWidget alloc] initWithOptions:options andAppearance:appearance]; widget.delegate = self; [widget load]; } #pragma mark - UITableViewDataSource, UITableViewDelegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return 10; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.row == 10) { if (self.widget != nil && [self.widget isLoaded] == YES) { return [((ContentWidgetGridLayout *)widget.layout) getSizeForPreferredWidth:tableView.bounds.size.width].height; } else { return 0; } } return 100.0f; } #pragma mark - SNRContentWidgetDelegate - (void)SNR_widget:(SNRContentWidget *)widget isLoading:(BOOL)isLoading { NSLog(@"Content Widget is loading: %@", isLoading ?? @"true" : @"false"); } - (void)SNR_widgetDidLoad:(SNRContentWidget *)widget { NSLog(@"Content Widget did load"); UIView *widgetView = [self.widget getView]; CGSize widgetSize = [((SNRContentWidgetHorizontalSliderLayout *)widget.layout getSize]; [self.widgetContainerView addSubview:widgetView]; widgetView.translatesAutoresizingMaskIntoConstraints = NO; [widgetView.topAnchor constraintEqualTo:widgetContainerView.topAnchor].active = YES; [widgetView.bottomAnchor constraintEqualTo:widgetContainerView.bottomAnchor].active = YES; [widgetView.leftAnchor constraintEqualTo:widgetContainerView.leftAnchor].active = YES; [widgetView.rightAnchor constraintEqualTo:widgetContainerView.rightAnchor].active = YES; [widgetContainerView.heightAnchor constraintEqualToConstant:widgetSize.height].active = YES; } - (void)SNR_widget:(SNRContentWidget *)widget didNotLoadWithError:(NSError *)error { NSLog(@"Content Widget did not load. Error: %@", error.localizedDescription); } - (void)SNR_widget:(SNRContentWidget *)widget didChangeToSize:(CGSize)size { NSLog(@"Content Widget did change size to %@", NSStringFromCGSize(size)); } - (void)SNR_widget:(SNRContentWidget *)widget didReceiveClickActionForModel:(SNRBaseModel *)model { if ([model isKindOfClass:[SNRRecommendation class]] == YES) { SNRRecommendation *recommendationModel = ((SNRRecommendation *)model); NSLog(@"Content Widget did receive click action for %@", recommendationModel.title); } } @end ```
## More information --- You can find more information under the following links: - [Sample App on GitHub](https://github.com/Synerise/ios-sdk/tree/master/SampleAppSwift/4.1.0) - [Horizontal Slider implementation in the Sample App on GitHub](https://github.com/Synerise/synerise-ios-sdk/blob/master/SampleAppSwift/4.1.0/SampleAppSwift/Main/Developer%20Tools%20Flow/ViewControllers/ContentAPI/RecommendationsWidgetAsSliderTableViewController.swift) - [Grid implementation in the Sample App on GitHub](https://github.com/Synerise/synerise-ios-sdk/blob/master/SampleAppSwift/4.1.0/SampleAppSwift/Main/Developer%20Tools%20Flow/ViewControllers/ContentAPI/RecommendationsWidgetAsGridTableViewController.swift) ### Client ### ClientIdentityProvider **Declared In:** Headers/SNRClientIdentityProvider.h **Declaration:**
```Swift enum ClientIdentityProvider: Int { synerise, oauth, simpleAuth, facebook, apple, google } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRClientIdentityProvider) { SNRClientIdentityProviderSynerise, SNRClientIdentityProviderOAuth, SNRClientIdentityProviderSimpleAuth, SNRClientIdentityProviderFacebook, SNRClientIdentityProviderApple, SNRClientIdentityProviderGoogle } ```
**Functions:** Converts from **ClientIdentityProvider** to **String**.
```Swift func SNR_ClientIdentityProviderToString(_: ClientIdentityProvider) -> String ```
```Objective-C NSString * SNR_ClientIdentityProviderToString(SNRClientIdentityProvider type) ```
--- Converts from **String** to **ClientIdentityProvider**.
```Swift func SNR_StringToClientIdentityProvider(_: String) -> ClientIdentityProvider ```
```Objective-C SNRClientIdentityProvider SNR_StringToClientIdentityProvider(NSString * _Nullable string) ```
--- --- ### ClientConditionalAuthenticationContext **Declared In:** Headers/SNRClientConditionalAuthContext.h **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientConditionalAuthContext: BaseModel ```
```Objective-C @interface SNRClientConditionalAuthContext : SNRBaseModel ```
**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 ```
--- --- ### ClientAuthenticationContext **Declared In:** Headers/SNRClientAuthenticationContext.h **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientAuthenticationContext: BaseModel ```
```Objective-C @interface SNRClientAuthenticationContext : SNRBaseModel ```
**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 ```
--- --- ### ClientConditionalAuthResult **Declared In:** Headers/SNRClientConditionalAuthResult.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientConditionalAuthResult: BaseModel ```
```Objective-C @interface SNRClientConditionalAuthResult : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **isSuccess** | Bool | no | Result of authentication operation | | **token** | String | yes | Token as a raw string | | **status** | [ClientConditionalAuthStatus](/developers/mobile-sdk/class-reference/ios/client#clientconditionalauthstatus) | no | Status of the authentication | | **conditions** | [AnyObject] | yes | Authentication conditions |
All properties are read-only.
--- --- ### ClientConditionalAuthStatus **Declared In:** Headers/SNRClientConditionalAuthStatus.h **Declaration:**
```Swift enum ClientConditionalAuthStatus: Int { success, unauthorized, activationRequired, registrationRequired, approvalRequired, termsAcceptanceRequired, mfaRequired, unknown } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRClientConditionalAuthStatus) { SNRClientConditionalAuthStatusSuccess, SNRClientConditionalAuthStatusUnauthorized, SNRClientConditionalAuthStatusActivationRequired, SNRClientConditionalAuthStatusRegistrationRequired, SNRClientConditionalAuthStatusApprovalRequired, SNRClientConditionalAuthStatusTermsAcceptanceRequired, SNRClientConditionalAuthStatusMFARequired, SNRClientConditionalAuthStatusUnknown } ```
**Functions:** Converts from **ClientConditionalAuthStatus** to **String**.
```Swift func SNR_ClientConditionalAuthStatusToString(_: ClientConditionalAuthStatus) -> String ```
```Objective-C NSString * SNR_ClientConditionalAuthStatusToString(SNRClientConditionalAuthStatus status) ```
--- Converts from **String** to **ClientConditionalAuthStatus**.
```Swift func SNR_StringToClientConditionalAuthStatus(_: String) -> ClientConditionalAuthStatus ```
```Objective-C SNRClientConditionalAuthStatus SNR_StringToClientConditionalAuthStatus(NSString * _Nullable string) ```
--- --- ### ClientSimpleAuthenticationData **Declared In:** Headers/SNRClientSimpleAuthenticationData.h **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientSimpleAuthenticationData: BaseModel ```
```Objective-C @interface SNRClientSimpleAuthenticationData : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | | **phone** | String | yes | Customer's phone | | **customId** | String | yes | Customer's custom ID | | **uuid** | String | yes | Customer's UUID | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) | yes | Customer's sex | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **avatarUrl** | String | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) | yes | Customer's agreements | | **attributes** | [AnyHashable: Any] | yes | Customer's attributes | **Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
--- --- ### ClientSessionEndReason **Declared In:** Headers/SNRClientSessionEndReason.h **Declaration:**
```Swift enum ClientSessionEndReason: Int { userSignOut, systemSignOut, sessionExpiration, securityException, clientRejected, userAccountDeleted } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRClientSessionEndReason) { SNRClientSessionEndReasonUserSignOut, SNRClientSessionEndReasonSystemSignOut, SNRClientSessionEndReasonSessionExpiration, SNRClientSessionEndReasonSessionDestroyed, SNRClientSessionEndReasonSecurityException, SNRClientSessionEndReasonClientRejected, SNRClientSessionEndReasonUserAccountDeleted } ```
--- --- ### ClientSignOutMode **Declared In:** Headers/SNRClientSignOutMode.h **Declaration:**
```Swift enum ClientSignOutMode: Int { .signOut, .signOutWithSessionDestroy } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRClientSignOutMode) { SNRClientSignOutModeSignOut, SNRClientSignOutModeSignOutWithSessionDestroy } ```
--- --- ### ClientAccountInformation **Declared In:** Headers/SNRClientAccountInformation.h **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Conforms To:** [NSSecureCoding](https://developer.apple.com/documentation/foundation/nssecurecoding) **Declaration:**
```Swift class ClientAccountInformation: BaseModel ```
```Objective-C @interface SNRClientAccountInformation : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **clientId** | Int | no | Customer's ID | | **email** | String | no | Customer's email | | **phone** | String | yes | Customer's phone | | **customId** | String | yes | Customer's custom ID | | **uuid** | String | no | Customer's UUID | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) | no | Customer's sex | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **lastActivityDate** | Date | no | Customer's last activity date | | **avatarUrl** | String | yes | Customer's avatar URL | | **anonymous** | Bool | no | Customer's anonymous flag | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) | no | Customer's agreements | | **attributes** | [AnyHashable: Any] | yes | Customer's attributes | | **tags** | [String] | yes | Customer's tags |
All properties are read-only.
--- --- ### ClientUpdateAccountBasicInformationContext **Declared In:** Headers/SNRClientUpdateAccountBasicInformationContext.h **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Conforms To:** [NSSecureCoding](https://developer.apple.com/documentation/foundation/nssecurecoding) **Declaration:**
```Swift class ClientUpdateAccountBasicInformationContext: BaseModel ```
```Objective-C @interface SNRClientUpdateAccountBasicInformationContext : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) | yes | Customer's sex | | **phone** | String | yes | Customer's phone | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **avatarUrl** | String | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) | no | Customer's agreements | | **attributes** | [AnyHashable: Any] | yes | Customer's attributes | **Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
--- --- ### ClientUpdateAccountContext **Declared In:** Headers/SNRClientUpdateAccountContext.h **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Conforms To:** [NSSecureCoding](https://developer.apple.com/documentation/foundation/nssecurecoding) **Declaration:**
```Swift class ClientUpdateAccountContext: BaseModel ```
```Objective-C @interface SNRClientUpdateAccountContext : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | | **phone** | String | yes | Customer's phone | | **customId** | String | yes | Customer's custom ID | | **uuid** | String | yes | Customer's UUID | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) | yes | Customer's sex | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **avatarUrl** | String | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) | no | Customer's agreements | | **attributes** | [AnyHashable: Any] | yes | Customer's attributes | **Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
--- --- ### ClientRegisterAccountContext **Declared In:** Headers/SNRClientRegisterAccountContext.h **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientRegisterAccountContext: BaseModel ```
```Objective-C @interface SNRClientRegisterAccountContext : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | String | no | Customer's email | | **password** | String | no | Customer's password | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **customId** | String | yes | Customer's custom ID | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/ios/client#clientsex) | yes | Customer's sex | | **phone** | String | yes | Customer's phone | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province code | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) | yes | Customer's agreements | | **attributes** | [AnyHashable: Any] | yes | Customer's attributes | **Initializers:**
```Swift init(email: String, password: String) ```
```Objective-C - (instancetype)initWithEmail:(nonnull NSString *)email andPassword:(nonnull NSString *)password ```
--- --- ### ClientPasswordResetRequestContext **Declared In:** Headers/SNRClientPasswordResetRequestContext.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientPasswordResetRequestContext: BaseModel ```
```Objective-C @interface SNRClientPasswordResetRequestContext : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | Bool | no | Customer's email | **Initializers:**
```Swift init(email: String) ```
```Objective-C - (instancetype)initWithEmail:(nonnull NSString *)email ```
--- --- ### ClientPasswordResetConfirmationContext **Declared In:** Headers/SNRClientPasswordResetConfirmationContext.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientPasswordResetConfirmationContext: BaseModel ```
```Objective-C @interface SNRClientPasswordResetConfirmationContext : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **password** | String | no | Customer's password | | **token** | String | no | Customer's token | **Initializers:**
```Swift init(password: String, token: String) ```
```Objective-C - (instancetype)initWithPassword:(nonnull NSString *)password andToken:(nonnull NSString *)token ```
--- --- ### ClientSex **Declared In:** Headers/SNRClientSex.h **Declaration:**
```Swift enum ClientSex: Int { notSpecified, male, female, other } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRClientSex) { SNRClientSexNotSpecified = 0, SNRClientSexMale, SNRClientSexFemale, SNRClientSexOther, } ```
**Functions:** Converts from **ClientSex** to **String**.
```Swift func SNR_ClientSexToString(_: ClientSex) -> String ```
```Objective-C NSString * SNR_ClientSexToString(SNRClientSex type) ```

Converts from **String** to **ClientSex**.
```Swift func SNR_StringToClientSex(_: String) -> ClientSex ```
```Objective-C SNRClientSex SNR_StringToClientSex(NSString * _Nullable string) ```
--- --- ### ClientAgreements **Declared In:** Headers/SNRClientAgreements.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Conforms To:** [NSSecureCoding](https://developer.apple.com/documentation/foundation/nssecurecoding) [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class ClientAgreements: BaseModel ```
```Objective-C @interface SNRClientAgreements : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | Bool | no | Email agreement | | **sms** | Bool | no | SMS agreement | | **push** | Bool | no | Push notifications agreement | | **bluetooth** | Bool | no | Bluetooth agreement | | **rfid** | Bool | no | RFID agreement | | **wifi** | Bool | no | WIFI agreement | **Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
--- --- ### ClientEventData **Declared In:** Headers/SNRClientEventData.h **Related To:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientEventData: BaseModel ```
```Objective-C @interface SNRClientEventData : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **time** | String | no | Event's time | | **label** | String | no | Event's label | | **action** | String | no | Event's action | | **client** | [AnyHashable: Any] | no | Event's customer identification | | **params** | [AnyHashable: Any] | no | Event's parameters |
All properties are read-only.
**Methods:** This method retrieves a customer ID.
```Swift func getClientID() -> Int ```
```Objective-C - (NSInteger)getClientID ```
--- This method retrieves a customer UUID.
```Swift func getClientUUIDString() -> String? ```
```Objective-C - (nullable NSString *)getClientUUIDString ```
--- This method retrieves a customer email.
```Swift func getClientEmail() -> String? ```
```Objective-C - (nullable NSString *)getClientEmail ```
--- --- ### 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:**
```Swift class ClientEventsApiQuery: NSObject ```
```Objective-C @interface SNRClientEventsApiQuery : NSObject ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **actions** | [String] | no | [] | Specifies event actions for query | | **timeFrom** | String | yes | nil | Specifies time from for query | | **timeTo** | String | yes | nil | Specifies time to for query | | **limit** | String | no | 100 | Limit of items in the response | **Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
--- --- ### TokenPayload **Declared In:** Headers/SNRTokenPayload.h **Related To:** [TokenOrigin](/developers/mobile-sdk/class-reference/ios/client#tokenorigin) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class TokenPayload: BaseModel ```
```Objective-C @interface SNRTokenPayload : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **tokenString** | String | no | Token as a raw string | | **expirationDate** | Date | no | Token's expiration time | | **creationDate** | Date | no | Token's creation time | | **rlm** | String | no | Token's RLM | | **origin** | [TokenOrigin](/developers/mobile-sdk/class-reference/ios/client#tokenorigin) | no | Token's origin | | **uuid** | String | no | Customer's UUID | | **clientId** | String | no | Customer's ID | | **customId** | String | yes | Customer's custom ID | **Initializers:**
```Swift init(tokenString: String, expirationDate: Date, creationDate: Date, rlm: String, origin: TokenOrigin, uuid: String, clientId: String, customId: String?) ```
```Objective-C - (instancetype)initWithTokenString:(NSString *)tokenString expirationDate:(NSDate *)expirationDate creationDate:(NSDate *)creationDate rlm:(NSString *)rlm origin:(SNRTokenOrigin)origin uuid:(NSString *)uuid clientId:(NSString *)clientId customId:(nullable NSString *)customId; ```
--- --- ### Token **Declared In:** Headers/SNRToken.h **Related To:** [TokenOrigin](/developers/mobile-sdk/class-reference/ios/client#tokenorigin) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class Token: BaseModel ```
```Objective-C @interface SNRToken : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **tokenString** | String | no | Token as a raw string | | **expirationDate** | String | no | Token's expiration time | | **rlm** | String | no | Token's RLM | | **origin** | [TokenOrigin](/developers/mobile-sdk/class-reference/ios/client#tokenorigin) | no | Token's origin | | **clientId** | String | no | Customer's ID | | **customId** | String | yes | Customer's custom ID | **Methods:** Checks if the token is near expiration.
```Swift func isNearExpiring() -> Bool ```
```Objective-C - (BOOL)isNearExpiring ```
--- --- ### TokenOrigin
The `Oauth` value was renamed in 5.0.0 version to `OAuth`.
**Declared In:** Headers/SNRTokenOrigin.h **Declaration:**
```Swift enum TokenOrigin: Int { unknown, synerise, simpleAuth, facebook, OAuth, apple } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRTokenOrigin) { SNRTokenOriginUnknown, SNRTokenOriginSynerise, SNRTokenOriginSimpleAuth, SNRTokenOriginFacebook, SNRTokenOriginOAuth, SNRTokenOriginApple } ```
**Functions:** Converts from **TokenOrigin** to **String**.
```Swift func SNR_TokenOriginToString(_: TokenOrigin) -> String ```
```Objective-C NSString * SNR_TokenOriginToString(SNRTokenOrigin type) ```
--- Converts from **String** to **TokenOrigin**.
```Swift func SNR_StringToTokenOrigin(_: String) -> TokenOrigin ```
```Objective-C SNRTokenOrigin SNR_StringToTokenOrigin(NSString *string) ```
--- --- ## Removed symbols --- ### ClientOAuthAuthenticationContext{#clientoauthauthenticationcontext} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** Headers/SNRClientOAuthAuthenticationContext.h **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientOAuthAuthenticationContext: BaseModel ```
```Objective-C @interface SNRClientOAuthAuthenticationContext : SNRBaseModel ```
**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 ```
--- --- ### ClientFacebookAuthenticationContext{#clientfacebookauthenticationcontext} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** Headers/SNRClientFacebookAuthenticationContext.h **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientFacebookAuthenticationContext: BaseModel ```
```Objective-C @interface SNRClientFacebookAuthenticationContext : SNRBaseModel ```
**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 ```
--- --- ### ClientAppleSignInAuthenticationContext{#clientapplesigninauthenticationcontext} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | n/a | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | n/a | 0.9.19 | n/a | | Removed in: | 5.0.0 | n/a | 1.0.0 | n/a | **Declared In:** Headers/SNRClientAppleSignInAuthenticationContext.h **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/ios/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class ClientAppleSignInAuthenticationContext: BaseModel ```
```Objective-C @interface SNRClientAppleSignInAuthenticationContext : SNRBaseModel ```
**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 ```
### Filters The simplest possible IQL query consists of a single item filter. The filter returns true (matched) or false (not matched). ## Elements of a filter An item filter has three elements: - A variable, which is an item attribute based on which you are filtering. - An operator which defines how the attribute's value is compared with the filter value. - A filter value to compare the attribute with. This value can be a constant or inserted dynamically from a [context](/developers/iql/context).
size     ==     10
      ^        ^      ^
  variable  operator  filterValue
In POST request to APIs, the quotation marks around the filterValue must be escaped, for example:
{
    "filter": "color == \"red\"",
    ...
}
## Data sources for filters An item feed is the source for searches and recommendations. The feed is generated from a catalog in Synerise or an external XML source. An item feed is indexed for the purpose of search and recommendation queries. In certain situations, the two indexes work differently. Those situations are described in this guide.
The indexes are updated periodically. An item that was recently added to the item feed is not immediately available in search/recommendation queries.
To learn more about configuring the item feed, see [AI Engine Configuration](/docs/settings/configuration/ai-engine-configuration). ## Item attributes An attribute name is used as a variable, and its value is compared to a filter value. For example, the following filter is true when an item's `brand` attribute is `abcd`: ``` brand == "abcd" ``` **Variables are case-sensitive**, but filter values are not. For example, the filter `brand == "ABCD"` is the same as `brand == "abcd"`, but `Brand == "abcd"` filters only by an attribute named `Brand`, not `brand`.
- In search requests, items can be filtered only by attributes which were defined as filterable when [configuring the search index](/docs/ai-hub/ai-search/define-attributes#filterable-attributes). - In recommendation requests, items can be filtered only by attributes which were defined as filterable when [configuring the AI model](/docs/settings/configuration/ai-engine-configuration/engine-configuration-for-recommendations).
Attributes with the following data type can be set as filterable: | type | example(s) | | --- | --- | | string | `"foo"` | | boolean | `true`;`false` | | numeric | `12`; `12.34` | | attributes in nested objects | `{"object":{"attr1":"value1","attr2":"value2"}}` | | array of strings, numerics

Arrays must be type-consistent. If different data types (for example, strings and numbers) are included in one array, a filter may not work correctly.| `["foo","bar"]`
`[12,45]`
`[12.34,53.18]` | ### Example items For the purpose of filter examples in this section, the following items are used:
[
    {
        "itemId": "s1",
        "brand": "Abcd",
        "size": {
            "width": 10,
            "height": 20
        },
        "available": true,
        "tags": ["New", "Winter sale"]
        "promoted": "T",
        "price": {
            "value": 129.99
        },
        "winterPromotion": true,
        "category": "X > Y > Z",
        "additionalCategories": ["hiking", "warm", "L > M > N"]
    },
    {
        "itemId": "m1",
        "brand": "Efgh",
        "size": {
            "width": 5,
            "height": 17
        },
        "available": true,
        "tags": ["Winter sale"],
        "price": {
            "value": 249.99
        },
        "category": "X > Y > V"
    }
]
### Top level attributes In order to access an attribute from the root level of the item's object, use the following syntax: ``` attributeName == filterValue ``` For example, `brand == "Abcd"` ### Nested attributes To access a nested value, use dot notation: ``` objectName.attributeName == filterValue ``` For example, `size.width == 5` ### Indexing attributes in arrays (recommendations only) When attributes are nested in arrays or arrays of objects, there is a difference in their indexing for the purposes of recommendation filters: - all values of a textual attribute are indexed - only the first value of a numeric attribute is indexed
This logic does **not** affect [context](/developers/iql/context#item-context) items. Context items are taken from the item feed, not the index.
**Example 1**: Consider the following item:
{
    "itemId": "s1",
    "tags": ["New", "Winter sale"],
    "sizes": [10, 15]
  }
- The `tags` variable contains the `New` and `Winter sale` values. - The `sizes` variable is `10`, because only the first number in an array is indexed. **Example 2**: Consider the following item:
{
    "itemId": "s1",
    "entries": [
        {
            "brand": "Abcd",
            "size": {
                "width": 10,
                "height": 20
            }
        },
        {
            "brand": "Xyz",
            "size": {
                "width": 15,
                "height": 25
            }
        }
    ]
  }
- The `entries.brand` variable contains the `Abcd` and `Xyz` values. - The `entries.size.width` variable is `10`, because it's the width defined in the first object of an array of objects which contain the numerical `width` attribute. ### Category `category` is a special type of attribute that describes a hierarchical structure. It is saved in the following format: ``` "X > Y > Z" ``` where X is the *top level category* and Z is a *leaf level category*. To filter items by category, use the following syntax: ``` category == CATEGORY("X > Y > Z", 0) ``` The above example finds items which are in the `"X > Y > Z"` category or its subcategories. For an explanation of the `0` argument and advanced operations on categories, see [the category function](/developers/iql/functions#category-function). #### Additional categories An item sometimes has a main *category* and a couple of additional categories to which it belongs, saved in the `additionalCategories` array. When the system creates a `category` filter, it combines the values from `category` (string) and `additionalCategories` (array of strings), hiding that complexity from the user. However, these categories are **not** combined in a [context](/developers/iql/context) item. If you want to use the context's additional categories in a filter, you must refer to them explicitly. For example, the following filter checks an item's category against the context's category and additional categories: ``` (category == CATEGORY(context.category, 0)) OR (category == CATEGORY(context.additionalCategories, 0)) ``` ### Metrics In IQL, you can use some pre-defined metrics which exist in all workspaces. Metrics are considered item attributes. The following example checks if the value of a metric for the tested item is more than 10. ``` extra.metrics.9 > 10 ``` The following metrics are available: | Metric | Attribute name | | --- | --- | | Number of page visits in last 7 days | `extra.metrics.9` | | Number of page visits in last 30 days | `extra.metrics.3` | | Number of item purchases yesterday | `extra.metrics.6` | | Number of item purchases in last 7 days | `extra.metrics.10` | | Number of item purchases in last 30 days | `extra.metrics.1` | | Number of item purchases on the same day last week | `extra.metrics.7` | | Total value of item sales in last 30 days, with tax | `extra.metrics.2` | ## Operators Operators are used to define the condition between the value of an attribute and the value to filter by. ### Filtering against strings Filter values are **not** case-sensitive. For example, `brand == "abcd"` is the same as `brand == "ABCD"`. #### equals The `==` operator checks if the strings are identical. ``` brand == "Abcd" ``` #### not equals The `!=` operator checks if the strings are not identical. ``` brand != "Abcd" ``` ### Filtering against numbers #### value comparisons The `<`, `<=`, `==`, `>=`, `>` operators compare the numbers. ``` size.width >= 10 ``` #### value in range The `FROM / TO` operator checks if a variable value is in a range between two values, including those values. ``` size.width FROM 6 TO 15 ```
An alternative way to build this filter is to [use the AND operator](/developers/iql/logic#and): ``` size.width >= 6 AND size.width <= 15 ```
### Filtering against arrays #### value in array **Example 1:** Checking if an item's attribute value exists in an array: ``` brand IN ["Abcd", "Efgh"] ```
An alternative way to build this filter is to [use the OR operator](/developers/iql/logic#or): ``` brand == "Abcd" OR brand == "Efgh" ```
**Example 2:** Checking if a value exists in an array, where the array is an item's attribute (`tags`): The `IN` operator checks if a filter value is included in an array-type attribute's value. ``` "New" IN tags ``` The filter value can only be a string. Note that in this case, the filter value is to the left of the operator, and the variable (item attribute) is on the right. #### array has value The `HAS` operator checks if an array includes a variable (this is an alternative to the `IN` operator). ``` [9, 15] HAS size.width ```
An alternative way to build this filter is to [use the OR operator](/developers/iql/logic#or): ``` size.width == 9 OR size.width == 15 ```
#### value not in array You can filter by checking if the value of a variable is NOT in an array. ``` brand NOT IN ["Abcd", "Efgh"] ```
This filter isn't available in AI Search. Instead, you can use the ['NOT' operator](/developers/iql/logic#not) with the ['IN' filter](#value-in-array), for example: ``` NOT brand IN ["Abcd", "Efgh"] ```
### Filtering against booleans #### equals The `==` operator checks if boolean values are identical. ``` available == true ``` #### not equals The `!=` operator checks if boolean values are not identical. ``` available != true ``` ## What happens if an attribute does not exist in the item? If an attribute does not exist in the item, its value is `null`. #### Check if an attribute exists The `IS DEFINED` operator allows you to check if an attribute exists and has a non-null value. ``` winterPromotion IS DEFINED ``` ### Public interfaces ## IDataApiCall --- IDataApiCall is a public interface used to execute requests with parameterized objects. **Java**:
public interface IDataApiCall<T> {
/**
     * It is recommended to call the {@link #cancel()} method before next execution.
     *
     * @param onSuccessListener callback with response
     * @param onFailureListener callback with Throwable instance
     */
    void execute(@NonNull DataActionListener<T> onSuccessListener, @NonNull DataActionListener<ApiError> onFailureListener);
    /**
     * Cancels the API request, therefore no response will be provided nor callback fired. <br>
     * It is recommended to call this method when an activity/fragment is being stopped.
     */
    void cancel();
    /**
     * Specify a reactive Scheduler for your request. <br>
     * By default, all internal methods use the {@link Schedulers#io()} scheduler.
     * See {@link io.reactivex.schedulers.Schedulers} factory for more info.
     *
     * @param scheduler reactive scheduler.
     */
    BasicDataApiCall<T> subscribeOn(Scheduler scheduler);
    /**
     * Specify your action when the request is being subscribed. This action will be fired just before calling the API.
     *
     * @param onSubscribeListener callback
     */
    BasicDataApiCall<T> onSubscribe(ActionListener onSubscribeListener);
    /**
     * Specify your action when the request succeeds, fails, or is cancelled.
     *
     * @param doFinallyListener callback
     */
    BasicDataApiCall<T> doFinally(ActionListener doFinallyListener);
    /**
     * Get the original reactive observable to chain your requests.<br>
     * Note that some of the SDK methods not only wrap observables in IDataApiCall,
     * but also add some extra logic, which shouldn't be skipped.<br>
     *
     * @return original reactive observable.
     */
    Observable<T> getObservable();
}
## IApiCall --- IApiCall is a public interface used to execute requests. **Java**:
public interface IApiCall<T> {
    /**
     * It is recommended to call the {@link #cancel()} method before next execution.
     *
     * @param onSuccessListener successful callback with no response
     * @param onFailureListener callback with Throwable instance
     */
    void execute(@NonNull ActionListener onSuccessListener, @NonNull DataActionListener<ApiError> onFailureListener);
    /**
     * Cancels the API request, therefore no response will be provided nor callback fired. <br>
     * It is recommended to call this method when an activity/fragment is being stopped.
     */
    void cancel();
    /**
     * Specify a reactive Scheduler for your request. <br>
     * By default, all internal methods use the {@link Schedulers#io()} scheduler.
     * See {@link io.reactivex.schedulers.Schedulers} factory for more info.
     *
     * @param scheduler reactive scheduler.
     */
    BasicApiCall<T> subscribeOn(Scheduler scheduler);
    /**
     * Specify your action when the request is being subscribed. This action will be fired just before calling API.
     *
     * @param onSubscribeListener callback.
     */
    BasicApiCall<T> onSubscribe(ActionListener onSubscribeListener);
    /**
     * Specify your action when the request succeeds, fails, or is cancelled.
     *
     * @param doFinallyListener callback.
     */
    BasicApiCall<T> doFinally(ActionListener doFinallyListener);
    /**
     * Get the original reactive observable to chain your requests.<br>
     * Note that some of SDK methods not only wrap observables in IApiCall,
     * but also add some extra logic, which shouldn't be skipped.<br>
     *
     * @return original reactive observable.
     */
    Observable<T> getObservable();
}
### Customer registration Customers can create accounts that let them authorize and perform operations such as redeeming coupons, making purchases, managing their own data, and more. The data is available for you to see and modify in the customer's profile; the primary unique identifier in Synerise is the email address (unless configured differently, see [Identifiers](/docs/settings/configuration/non-unique-emails)). A customer can also exist in the database if they don't have a self-managed account. For more details on profiles, see [Customer profiles](/developers/api/clients/profiles). ## Registering a customer with RaaS Registration as a Service (RaaS) creates an account in Synerise without any third-party integrations. It may be configured to require email confirmation. The basic request only requires an email, password, an UUID, but you can provide additional information. See [method reference](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/RegisterAClient). To authenticate this request, you need a [JWT of an anonymous profile](/developers/api/api-authorization/client-login#authenticating-as-an-anonymous-customer).
curl --location --request \
POST 'http://{SYNERISE_API_BASE_PATH}/sauth/clients/registered' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJhb...Ndo' \
--data-raw '{
    "email":"sampleclient@synerise.com",
    "password":"strongpassword",
    "uuid":"b3f56868-9667-4843-a8e5-0509456baa9b"
}'
Alternatively, you can use the [authentication endpoint](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/authenticateUsingPOST_v3). If an account doesn't exist, the authentication endpoint creates one. ## Account activation Synerise RaaS may be configured for three types of account confirmation: - Automatic: the account is ready to use immediately. The `snrs_email_confirmed` attribute in the customer is FALSE. - Email confirmation required: the account is ready to use, but confirmation is required to set the `snrs_email_confirmed` attribute in the customer profile to TRUE. - Email activation required: the account cannot be accessed until it is confirmed. Activation sets the `snrs_email_confirmed` attribute in the customer profile to TRUE. - PIN activation: the customer receives a PIN code instead of a confirmation link. Activation sets the `snrs_email_confirmed` attribute in the customer profile to TRUE. ### Setting the activation method
When changing the settings, any values you do not send are changed to default!
1. Get the current settings for your workspace. Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getGeneralConfigUsingGET).
curl --location --request GET 'https://{SYNERISE_API_BASE_PATH}/sauth/settings/general' \
   --header 'Authorization: Bearer eyJh...qU'
1. From the response, copy the current settings. 2. Change the copied settings and send an update request. Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateGeneralSettingsUsingPOST). The following is an example of enabling PIN activation.
Remember about additional settings for each confirmation type, such as PIN length or confirmation redirect link.
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/sauth/settings/general' \
--header 'Authorization: Bearer eyJ...JwqU' \
--header 'Content-Type: application/json' \
--data-raw '{
    "registrationType": "REQUIRE_PIN_CONFIRMATION",
    "tokenLifetimeInSeconds": 3600,
    "confirmationRedirectLink": null,
    "voucherPoolUuid": null,
    "allowOverwriteCustomIdentify": false,
    "allowEmailChangeFromWebForm": false,
    "pinConfirmationType": "ON_CONFLICT_WITH_EXTERNAL_ACCOUNT",
    "pinConfirmationLength": 6,
    "pinConfirmationValidInSeconds": 300,
    "allowPinResendFromDifferentDeviceId": false
}'
### Confirming the account by PIN Confirming the account by PIN has two modes, selected with the `pinConfirmationType` setting: - `ON_CONFLICT_WITH_EXTERNAL_ACCOUNT` (default setting) requires the PIN only if an account with the same unique identifier already exists and was registered with a third-party Identity Provider. - `EVERYONE` requires the PIN for all registrations. #### Activating/confirming the account Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/confirmByPinCodeUsingPOST). The activation request must always be sent from last device that requested a PIN. If you [re-send a PIN](#re-sending-an-activationconfirmation-pin) from a different device than the one that sent the registration request, the activation request must be made from the device that requested re-sending the PIN. **Prerequisites** - [Email sender integration](/docs/settings/tool/integrating-email-providers) must be enabled. - The [confirmation mail template](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getTemplateSettingsUsingGET) must include a `{{pin_code}}` insert. The PIN is sent to the customer's email automatically after registration.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/clients/activation/by-pin-code/confirmation 
  --header 'Authorization: Bearer eyJ...JwqU' 
  --header 'content-type: application/json' 
  --data '{
    "deviceId":"5966145e-412d-44db-b826-7d53e6cfd300",
    "email":"john.doe@synerise.com",
    "pinCode":"123456",
    "uuid":"07243772-008a-42e1-ba37-c3807cebde8f"
    }'
**Result:** The account is activated/confirmed and ready to use. #### Re-sending an activation/confirmation PIN Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/resendByPinCodeUsingPOST). If the PIN expired, re-send it. By default, you can only request the re-sending from the last device that requested a PIN previously. If you want to allow requesting a PIN from other devices, set `allowPinResendFromDifferentDeviceId` to TRUE. The activation request can only be sent from the last device that requested a PIN, regardless of the settings. **Prerequisites** - [Email sender integration](/docs/settings/tool/integrating-email-providers) must be enabled. - The [confirmation mail template](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getTemplateSettingsUsingGET) must include a `{{pin_code}}` insert.
curl --request POST 
    --url https://{SYNERISE_API_BASE_PATH}/sauth/clients/activation/by-pin-code/request 
    --header 'Authorization: Bearer eyJ...JwqU' 
    --header 'content-type: application/json' 
    --data '{
      "deviceId":"5966145e-412d-44db-b826-7d53e6cfd300",
      "email":"john.doe@synerise.com",
      "uuid":"07243772-008a-42e1-ba37-c3807cebde8f"
      }'
**Result:** The activation PIN is re-sent. ### Confirming the account by activation link #### Activating/confirming the account Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/ConfirmAClientAccount). **Prerequisites**: [Email sender integration](/docs/settings/tool/integrating-email-providers) must be enabled. The token is sent to the customer's email automatically after registration.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/clients/activation/confirmation 
  --header 'authorization: Bearer eyJh...JxkM5o' 
  --header 'content-type: application/json' 
  --data '{
      "token":"eyJh...JwcR4z"
    }'
**Result:** The account is activated/confirmed and ready to use. #### Requesting a new activation/confirmation token Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/resendUsingPOST). **Prerequisites**: [Email sender integration](/docs/settings/tool/integrating-email-providers) must be enabled. If the activation token expires or the message was not delivered, you can request a new token.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/clients/activation/request 
  --header 'authorization: Bearer eyJh...JxkM5o' 
  --header 'content-type: application/json' 
  --data '{
      "email":"sampleclient@synerise.com"
    }'
**Result:** The email with the token is re-sent. ## Registering customers with third-party mechanisms You can register a customer by using Facebook, Google sign-in, OAuth, or Sign in with Apple. - Registering a customer with Facebook Login requires that your application is integrated with Facebook. For more details, see the [Facebook Developer Documentation](https://developers.facebook.com/docs/). - Registering a customer with Sign in with Apple requires that your application is integrated with Sign in with Apple. For more details, see the [Apple Developer Documentation](https://developer.apple.com/documentation/). - Registering a customer with Google requires that your application is integrated with Google. For more details, see the [Google Identity documentation](https://developers.google.com/identity/protocols/oauth2). - Registering with OAuth creates a customer account in Synerise, but a customer account must also exist in your own database to serve as a basis for OAuth authentication.
This endpoint can be used for logging in - if an account already exists, the response is a Synerise JWT that can be used for authorizing further requests as the customer.
The following is a basic request for Facebook authentication, but you can provide more information or change the Identity Provider. See [method reference](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/authenticateUsingPOST_v3). `accessToken` is the token that is sent by Synerise backend to your OAuth implementation.
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/sauth/auth/v3/login/client' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
    "apiKey":"01234abc-1234-5678-9abc-def012345678",
    "identityProvider": "FACEBOOK",
    "identityProviderToken": "70fb8a02-0a6e-48ca-96d5-0212ee140eae"
}'
The response is an authentication token. ### Modules ### BaseModule Main module abstract class for inheriting classes. **Declared In:** lib/main/modules/BaseModule.js **Declaration:**
class BaseModule
--- --- ### Settings The module for managing the SDK settings. **Declared In:** lib/main/modules/SettingsModule.js **Inherits From:** [Module](/developers/mobile-sdk/class-reference/react-native/modules#basemodule) **Declaration:**
class SettingsModule extends Module
**Properties:** | Property | Type | Description | | --- | --- | --- | | **sdk** | ISettingsOptions | [General settings](/developers/mobile-sdk/settings#general) - This group contains options related to the general functioning of mobile SDK | | **notifications** | ISettingsOptions | [Notifications settings](/developers/mobile-sdk/settings#notifications) - This group contains options related to push notifications | | **tracker** | ISettingsOptions | [Tracker](/developers/mobile-sdk/settings#tracker) - This group contains options related to tracking the customer activities in a mobile application | | **inAppMessaging** | ISettingsOptions | [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** | ISettingsOptions | [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 The module for managing notifications. **Declared In:** lib/main/modules/NotificationsModule.js **Inherits From:** [Module](/developers/mobile-sdk/class-reference/react-native/modules#basemodule) **Declaration:**
class NotificationsModule extends Module
**Methods:** This method sets an object for Notifications listener methods.
public setListener(listener: INotificationsListener)
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener) --- This method passes the Firebase Token to Synerise for notifications.
public registerForNotifications(registrationToken: string, mobileAgreement: boolean | null, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#register-for-push-notifications) --- This method verifies if a notification was sent by Synerise.
public isSyneriseNotification(payload: object): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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
public isSyneriseSimplePush(payload: object): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 isSyneriseBanner(payload: object): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-a-banner-campaign) - **REMOVED in version 1.0.0** --- This method verifies if a notification's sender is Synerise and if the notification is a Silent Command.
public isSilentCommand(payload: object): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 isSilentSDKCommand(payload: object): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-a-silent-sdk-command) --- This method verifies if a notification is encrypted.
public isNotificationEncrypted(payload: object): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-encrypted) --- This method decrypts the notification payload.
public decryptNotification(payload: object): object | null
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#decrypt-push-notification) --- This method handles a notification payload with a user interaction and starts activity.
public handleNotification(payload: object, actionIdentifier: string | null)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#handle-synerise-push-notification) --- --- --- ### Client The module for managing customer account data, registration, and authorization. **Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAccountRegisterContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountregistercontext) [ClientIdentityProvider](/developers/mobile-sdk/class-reference/react-native/client#clientidentityprovider) [ClientAuthContext](/developers/mobile-sdk/class-reference/react-native/client#clientauthcontext) [ClientOAuthAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientoauthauthenticationcontext) [ClientFacebookAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientfacebookauthenticationcontext) [ClientAppleSignInAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientapplesigninauthenticationcontext) [ClientAccountInformation](/developers/mobile-sdk/class-reference/react-native/client#clientaccountinformation) [ClientAccountUpdateContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountupdatecontext) [Token](/developers/mobile-sdk/class-reference/react-native/client#token) **Inherits From:** [Module](/developers/mobile-sdk/class-reference/react-native/modules#basemodule) **Declaration:**
class ClientModule extends Module
**Methods:** This method sets an object for customer's state listener methods.
public setClientStateChangeListener(listener: IClientStateChangeListener)
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#client-state-listener) --- This method registers a new customer with an email, password, and optional data.
public registerAccount(context: ClientAccountRegisterContext, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#register-customer-account) --- This method confirms a customer account with the confirmation token.
public confirmAccountActivation(token: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#confirm-customer-account-activation) --- This method activates a customer with email.
public requestAccountActivation(email: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#request-customer-account-activation) --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests.
public signIn(email: string, password: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 signInConditionally(email: string, password: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#sign-in-a-customer-conditionally) --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
public authenticate(token: string, provider: ClientIdentityProvider, context: ClientAuthContext, onSuccess: (authResult: ClientConditionalAuthResult) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-identityprovider) --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise.
public authenticateConditionally(token: string, provider: ClientIdentityProvider, context: ClientAuthContext, onSuccess: (authResult: ClientConditionalAuthResult) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-conditionally-by-identityprovider) --- This method authenticates a customer with OAuth.
public authenticateByOAuth(accessToken: string, context: ClientOAuthAuthenticationContext, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-oauth-with-registration) - **REMOVED in version 1.0.0** --- This method authenticates a customer with OAuth.
public authenticateByOAuthIfRegistered(accessToken: string, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-oauth-without-registration) - **REMOVED in version 1.0.0** --- This method authenticates a customer with Facebook.
public authenticateByFacebook(facebookToken: string, context: ClientFacebookAuthenticationContext, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-facebook-with-registration) - **REMOVED in version 1.0.0** --- This method authenticates a customer with Facebook.
public authenticateByFacebookIfRegistered(facebookToken: string, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-facebook-without-registration) - **REMOVED in version 1.0.0** --- This method authenticates a customer with Sign In With Apple.
public authenticateByAppleSignIn(identityToken: string, context: ClientAppleSignInAuthenticationContext, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-sign-in-with-apple-with-registration) - **REMOVED in version 1.0.0** --- This method authenticates a customer with Sign In With Apple.
public authenticateByAppleSignInIfRegistered(identityToken: string, authID: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-sign-in-with-apple-without-registration) - **REMOVED in version 1.0.0** --- This method authenticates a customer with Simple Profile Authentication.
public simpleAuthentication(data: ClientSimpleAuthenticationData, authID: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 isSignedIn(): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 isSignedInViaSimpleAuthentication(): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#check-if-a-customer-is-signed-in-via-simple-profile-authentication) --- This method signs out a customer out.
public signOut()
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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
public signOutWithMode(mode: ClientSignOutMode, fromAllDevices: boolean, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#sign-out-customer-with-mode-or-from-all-devices) --- This method refreshes the customer’s current token.
public refreshToken(onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-session#refresh-customer-token) --- This method retrieves the customer’s current, active token.
public retrieveToken(onSuccess: (token: Token) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-session#retrieve-customer-token) --- This method retrieves the customer’s current UUID.
public getUUID(): string
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-session#get-current-customer-uuid) --- This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
public regenerateUUID()
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-session#regenerate-customer) --- This method regenerates the UUID and clears the authentication token, login session, custom email, and custom identifier.
public regenerateUUIDWithClientIdentifier(clientIdentifier: string)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-session#regenerate-customer-with-identifier) --- This method destroys the session completely.
public destroySession()
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-session#destroy-current-session) --- This method gets a customer’s account information.
public getAccount(onSuccess: (clientAccountInformation: ClientAccountInformation) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#get-customer-account-information) --- This method updates a customer’s account’s basic information (without identification data: uuid, customId, email).
public updateAccountBasicInformation(context: ClientAccountUpdateBasicInformationContext, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#update-customer-account-basic-information) --- This method updates a customer’s account information.
public updateAccount(context: ClientAccountUpdateContext, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#update-customer-account-information) --- This method requests a customer’s password reset with email.
public requestPasswordReset(email: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 confirmPasswordReset(password: string, token: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#confirm-password-reset-for-customer-account) --- This method changes a customer’s password.
public changePassword(oldPassword: string, newPassword: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#change-customers-account-password) --- This method requests a customer's email change.
public requestEmailChange(email: string, password: string | null, externalToken: string | null, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#request-email-change-for-customer-account) --- This method confirms an email change.
public confirmEmailChange(token: string, newsletterAgreement: boolean, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#confirm-email-change-for-customer-account) --- Requests a customer's phone update. A confirmation code is sent to the phone number.
public requestPhoneUpdate(phone: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 confirmPhoneUpdate(phone: string, confirmationCode: string, smsAgreement: boolean, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#confirm-phone-update-on-customer-account) --- This method requests a customer's account registration process with the PIN code.
public requestAccountActivationByPin(email: string, onSuccess: () => void, onError: (error: Error)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#request-customer-account-activation-by-pin) --- This method confirms a customer's account registration process with the PIN code.
public confirmAccountActivationByPin(pinCode: string, email: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-authentication#confirm-customer-account-activation-by-pin) --- This method deletes a customer's account.
public deleteAccountByIdentityProvider(clientAuthFactor: string, clientIdentityProvider: ClientIdentityProvider, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#delete-customer-account-by-identity-provider) --- This method deletes a customer's account.
public deleteAccount(password: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#delete-customer-account) --- This method deletes a customer's account by OAuth.
public deleteAccountByOAuth(password: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#delete-customer-account-by-oauth) --- This method deletes a customer's account by Facebook.
public deleteAccountByFacebook(password: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/client-account#delete-customer-account-by-facebook) --- --- ### 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:** lib/main/modules/TrackerModule.js **Related To:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Inherits From:** [Module](/developers/mobile-sdk/class-reference/react-native/modules#basemodule) **Declaration:**
class TrackerModule extends Module
**Methods:** This method sets a custom identifier in the parameters of every event.
public setCustomIdentifier(identifier: string)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/tracking#set-custom-identifier-for-events) --- This method sets a custom email in the parameters of every event.
public setCustomEmail(email: string)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/tracking#set-custom-email-for-events) --- This method sends an event.
public send(event: Event)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/tracking#send-event) --- This method forces sending the events from the queue to the server.
public flushEvents(onSuccess: () => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/tracking#flush-events-from-tracker) --- --- ### Injector The module for handling Synerise UI activities such as walkthrough, banner, simple push, and so on. **Declared In:** lib/main/modules/InjectorModule.js **Inherits From:** [Module](/developers/mobile-sdk/class-reference/react-native/modules#basemodule) **Declaration:**
class InjectorModule extends Module
**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 closeInAppMessage(campaignHash: string)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#close-in-app-message) --- This method sets an object for Injector listener methods.
public setListener(listener: IInjectorListener)
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-listener) --- This method sets an object for in-app message listener methods.
public setInAppMessageListener(listener: IInjectorInAppMessageListener)
[(Click for more details)](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-in-app-message-listener) --- This method sets if banners should be shown or not.
public setShouldBannerPresentFlag(shouldPresentBanner: boolean)
--- This method fetches banners set for mobile campaigns and caches the valid ones.
public fetchBanners(onSuccess: (banners: Array<Object>) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#fetch-banners) - **REMOVED in 0.12.0** --- This method provides valid banners directly from SDK cache.
public getBanners(): Array<Object>
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#get-banners) - **REMOVED in 0.12.0** --- This method shows a banner immediately.
public showBanner(banner: Object, markPresented: boolean)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#show-banner) - **REMOVED in 0.12.0** --- This method fetches a walkthrough.
public getWalkthrough()
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#get-walkthrough) - **REMOVED in version 1.0.0** --- This method shows a walkthrough when it is loaded.
public showWalkthrough()
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#show-walkthrough) - **REMOVED in version 1.0.0** --- This method checks if a walkthrough is loaded.
public isWalkthroughLoaded(): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-walkthrough-is-loaded) - **REMOVED in version 1.0.0** --- This method checks if the walkthrough is unique compared to the previous one.
public isLoadedWalkthroughUnique(): boolean
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-is-loaded-walkthrough-unique) - **REMOVED in version 1.0.0** --- --- ### Promotions The module for handling promotions and vouchers from Synerise SDK. **Declared In:** lib/main/modules/PromotionsModule.js **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionresponse) [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) [AssignVoucherResponse](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#assignvoucherresponse) [VoucherCodesResponse](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#vouchercodesresponse) **Inherits From:** [Module](/developers/mobile-sdk/class-reference/react-native/modules#basemodule) **Declaration:**
class PromotionsModule extends Module
**Methods:** This method retrieves all available promotions that are defined for a customer.
public getAllPromotions(onSuccess: (promotionResponse: PromotionResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#get-all-promotions-of-a-customer) --- This method retrieves promotions that match the parameters defined in an API query.
public getPromotions(apiQuery: PromotionsApiQuery, onSuccess: (promotionResponse: PromotionResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#get-promotions-with-query-parameters) --- This method retrieves the promotion with the specified UUID.
public getPromotionByUUID(uuid: string, onSuccess: (promotion: Promotion) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#get-promotion-by-uuid) --- This method retrieves the promotion with the specified code.
public getPromotionByCode(code: string, onSuccess: (promotion: Promotion) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#get-promotion-by-code) --- This method activates the promotion with the specified UUID.
public activatePromotionByUUID(uuid: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#activate-promotion-by-uuid) --- This method activates the promotion with the specified code.
public activatePromotionByCode(code: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#activate-promotion-by-code) --- This method activates promotions with a code or with UUID in a batch.
public activatePromotionsBatch(promotionsIdentifiers: Array<PromotionIdentifier>, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#activate-promotions-in-a-batch) --- This method deactivates the promotion with the specified UUID.
public deactivatePromotionByUUID(uuid: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#deactivate-promotion-by-uuid) --- This method deactivates the promotion with the specified code.
public deactivatePromotionByCode(code: string, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#deactivate-promotion-by-code) --- This method deactivates promotions with a code or with UUID in a batch.
public deactivatePromotionsBatch(promotionsIdentifiers: Array<PromotionIdentifier>, onSuccess: () => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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.
public getOrAssignVoucher(poolUuid: string, onSuccess: (assignVoucherRespone: AssignVoucherResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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 assignVoucherCode(poolUuid: string, onSuccess: (assignVoucherRespone: AssignVoucherResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/promotions#assign-voucher-code-from-pool) --- This method retrieves voucher codes for a customer.
public getAssignedVoucherCodes(onSuccess: (voucherCodesResponse: VoucherCodesResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/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/main/modules/ContentModule.js **Related To:** [RecommendationResponse](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#recommendationresponse) [Recommendation](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#recommendation) [DocumentApiQuery](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#documentapiquery) [ScreenViewApiQuery](/developers/mobile-sdk/class-reference/react-native/miscellaneous#screenviewapiquery) [BrickworksApiQuery](/developers/mobile-sdk/class-reference/react-native/miscellaneous#brickworksapiquery) **Inherits From:** [Module](/developers/mobile-sdk/class-reference/react-native/modules#basemodule) **Declaration:**
class ContentModule extends Module
**Methods:** --- This method generates the document assigned to a slug.
public getDocument(slug: string, onSuccess: (document: object) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#get-document) - **REMOVED in version 1.0.0** --- This method generates the document that is defined for the provided slug.
public generateDocument(slug: string, onSuccess: (document: Document) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#generate-document) --- This method generates the document that is defined for the provided slug.
public generateDocumentWithApiQuery(slug: string, onSuccess: (document: Document) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#generate-document-with-query-parameters) --- This method generates documents that are defined for parameters provided in the query object.
public getDocuments(apiQuery: DocumentsApiQuery, onSuccess: (documents: Array<object>) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#get-documents) - **REMOVED in version 1.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 getRecommendations(options: RecommendationOptions, onSuccess: (recommendationResponse: RecommendationResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#get-recommendations) - **REMOVED in version 1.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 getRecommendationsV2(options: RecommendationOptions, onSuccess: (recommendationResponse: RecommendationResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#get-recommendations-v2) --- This method generates the customer's highest-priority screen view campaign.
public getScreenView(onSuccess: (screenViewResponse: ScreenViewResponse) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#get-screen-view) - **REMOVED in version 1.0.0** --- This method generates a customer's highest-priority screen view campaign from the feed with the provided feed slug.
public generateScreenView(slug: String, onSuccess: (screenView: ScreenView) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#generate-screen-view) --- This method generates a customer's highest-priority screen view campaign from the feed with the provided feed slug.
public generateScreenViewWithApiQuery(apiQuery: ScreenViewApiQuery, onSuccess: (screenView: ScreenView) => void, onError: (error: Error) => void)
[(Click for more details)](/developers/mobile-sdk/method-reference/react-native/content#generate-screen-view-with-query-parameters) --- ### Profile authentication When authenticating as a profile, the following methods may be available (depending on the endpoint you're trying to access): - [Generating a JSON Web Token (JWT)](#jwt-authentication). For this you need a [profile API key](/docs/settings/tool/api). - [Using the tracker key from the tracking script](#tracker-key-authentication). - ~~Inserting an API key into the request headers.~~ - this is a legacy method which should not be used in new integrations. ## JWT authentication These methods of authentication generate a JWT, which is then added to the headers of API requests.
- Keep the API keys secret. A leaked key must be deactivated **immediately**! - When [creating the API key](/docs/settings/tool/api#adding-api-keys), you can use [allowlisting](/docs/settings/tool/api#allowlist) or [denylisting](/docs/settings/tool/api#denylist) to only allow the events you intend to use.
### Authenticating as a recognized customer You can use the following endpoints to authenticate as a customer: - [Registers an account (unless the account already exists) when logging in using Facebook, Google, Sign in with Apple, or OAuth](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/authenticateUsingPOST_v3) - [Does not register an account](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/authenticateConditionalUsingPOSTv3) Both endpoints accept the same payload. If you use Synerise RaaS authentication, none of the endpoints above can be used to register an account. See [Customer registration](/developers/api/clients/registration). #### Example: Synerise RaaS authentication The example includes only the fields that are required.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/v3/auth/login/client 
  --header 'content-type: application/json' 
  --data '{
      "apiKey": "1c586ac4-cb47-4c45-a7cf-e0fb74e8e5f4",
      "identityProvider": "SYNERISE",
      "password": "Pass1!",
      "uuid": "5f89a52f-e526-4c7d-a50c-3f5c744d3162",
  }'
The response is a JSON Web Token (JWT) that must be included in the `Authorization` header of further requests. By default, the token is valid for 60 minutes. #### Example: Facebook authentication, no registration if account does not exist The example includes only the fields that are required.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/v3/auth/login/client/conditional 
  --header 'content-type: application/json' 
  --data '{
      "apiKey": "1c586ac4-cb47-4c45-a7cf-e0fb74e8e5f4",
      "identityProvider": "FACEBOOK",
      "identityProviderToken": "EAAfsMmaWLW0BAJZC3BWUZBi0izUcN9YntYLOZCtTkoPDrkcugIubbwrcXPPUPGKR6q4rdJdaK1sgNg4ARxVBQfUab8hafhPc2sXafL4wHVpS5mnEqrFTKbSHqj3ZBjX6HzMXXZA6qYnfNlzOQvjCEabjqgUdNQE6SrtPNQ7s7gZAOzFP3Ad1QB5vqxb276JM9yhBjVRp5SCdwZDZD"
  }'
The response is a JSON Web Token (JWT) that must be included in the `Authorization` header of further requests. By default, the token is valid for 60 minutes. ### Authenticating as an anonymous customer You can find the method under the ["Authenticate Anonymously" section in the API reference](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/LogInAnonymouslyV3). You can generate a JWT for a customer who does not have an account.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/v3/auth/login/client/anonymous 
  --header 'content-type: application/json' 
  --data '{
    "apiKey":"1c586ac4-cb47-4c45-a7cf-e0fb74e8e5f4",
    "deviceId":"b8af0626-d5cf-44d6-b12a-ec72f946db6f",
    "uuid":"07243772-008a-42e1-ba37-c3807cebde8f"
  }'
The response is a JSON Web Token (JWT) that must be included in the `Authorization` header of further requests. By default, the token is valid for 60 minutes. ### Refreshing JWT You can find the method under the ["Refresh a Profile token" section in the API reference](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/RefreshAClientTokenV3). When the token is about to expire, you can obtain a new one without logging in again. This is not possible if the token has already expired.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/v3/auth/refresh/client 
  --header 'Authorization: Bearer _YOUR_JWT_TOKEN_' 
  --header 'content-type: application/json' 
  --data '{
    "apiKey":"1c586ac4-cb47-4c45-a7cf-e0fb74e8e5f4"
    }'
The response is a new token. ## Tracker key authentication This method is available for some endpoints that relate to the AI engine, such as search and recommendation endpoints. The tracker key is the same as in the [tracking code](/developers/web/installation-and-configuration#creating-a-tracking-code) of your website and is included in the `token` query parameter of a request. If needed, you can generate a new tracking code to have a separate authentication key for API requests made by your website. Example:
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns/DkhvrZoTKthD?token=98A5FC55-0000-0000-0000-98339BDECAE6&clientUUID=cf9e9b57-7776-51bc-b7bc-75cc75abdf59'
                                                                                              <-------------- tracker key ------------->
where: - `DkhvrZoTKthD` is an example campaign ID. - `98A5FC55-0000-0000-0000-98339BDECAE6` is an example tracker key. - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID. Example endpoint: [GET personalized recommendations](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#tag/Recommendations/operation/RecommendForUserV2) ### Recommendation API requests You can make requests for: - results of a [campaign created in the Synerise Portal](/docs/ai-hub/recommendations-v2/creating-recommendation-campaign). With this option, you can create a campaign with filters instead of defining them for each request. You can still tweak filters when making the request. This is the most commonly used method. - recommendations served [by a recommendation model](#requests-to-a-model) without creating a campaign. With this option, you can make requests without preparing a campaign first, but you need to send the settings that are normally part of the campaign. ## Before you begin - Ensure that the model for the type of recommendations you want to request is enabled in the [settings of an item feed](/docs/settings/configuration/ai-engine-configuration/engine-configuration-for-recommendations#selecting-recommendation-types-and-default-filters). - You should be familiar with recommendation types and filter types: - [Recommendation types](/docs/ai-hub/recommendations-v2/recommendation-types) - [Recommendation filter types](/docs/ai-hub/recommendations-v2/recommendation-filters#filter-types) ## Elements of the request ### Context Each recommendation is made in context of a Profile. The profile's attributes can be used in filters.
When making requests from a website, you can find the profile's UUID in the `_snrs_uuid` cookie.
You can also add item context to your requests, for example when generating complementary purchase recommendations for a product. The context item's attributes can be used in filters. In some recommendations, the item context is required. When it's not required, it can still be included in order to use the context item's attributes in filters. ### Address The domain of the recommendations API depends on your workspace. - `https://api.synerise.com` for Microsoft Azure EU environment - `https://api.azu.synerise.com` for Microsoft Azure USA environment - `https://api.geb.synerise.com` for Google Cloud Platform environment - If you have a [custom tracking domain](/developers/web/first-party-tracking) configured, use the custom domain (only for requests made from sites which have a [Tracking Code](/developers/web/installation-and-configuration)).
With the custom tracking domain, you must [add `/ai` before the endpoint path in addition to changing the domain](/developers/web/first-party-tracking#updating-your-synerise-api-requests).
### Authentication The requests can be authenticated in the following ways: - **Recommended method**: With the key from your [tracking code](/developers/web/installation-and-configuration). This tracker key is added to the request in the `token` query parameter. This method is used in most examples in this guide. - [With a Workspace JWT (Bearer auth) or Basic authentication](/developers/api/api-authorization/workspace-login).
Workspace JWTs and Basic Authentication can be used ONLY FOR SERVER-TO-SERVER communication. DO NOT use them in your mobile applications or websites.
The following examples show the two methods of authentication.
This is the recommended method. The tracker key is included in the `token` parameter.
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns/DkhvrZoTKthD?token=98A5FC55-0000-0000-0000-98339BDECAE6&clientUUID=cf9e9b57-7776-51bc-b7bc-75cc75abdf59'
                                                                                              <-------------- tracker key ------------->
where: - `DkhvrZoTKthD` is an example campaign ID. You can also refer to a campaign by its slug. - `98A5FC55-0000-0000-0000-98339BDECAE6` is an example tracker key. - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID.
The JWT is included in the `Authorization` header.
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns/DkhvrZoTKthD?clientUUID=cf9e9b57-7776-51bc-b7bc-75cc75abdf59' \
--header 'Authorization: Bearer eyJhbGciOiJSUzUx.edWIiOiIyYzU2Yjk5NmR...g7ToscgR9au6fQDhbs'
where: - `DkhvrZoTKthD` is an example campaign ID. You can also refer to a campaign by its slug. - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID.
## Making a request ### Campaign results You can use two HTTP methods: - GET: elements of the query are passed as query parameters. This method is recommended for making requests from a website. - POST: elements of the query are passed in the request body.
For details of all the parameters available for these endpoints, see the API Reference: - [GET](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#operation/GetRecommendationsByCampaignV2) - [POST](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#operation/PostRecommendationsByCampaignV2)
**Examples**:
In GET requests, the item context is sent in the `itemId` attribute. In campaigns which accept multiple items in the context (cart recommendations), send the attribute multiple times. See example:
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns/DkhvrZoTKthD?itemId=0196499479257&itemId=0000301448594&itemId=0000301826378&token=98A5FC55-0000-0000-0000-98339BDECAE6&clientUUID=cf9e9b57-7776-51bc-b7bc-75cc75abdf59'
where: - `DkhvrZoTKthD` is an example campaign ID. You can also refer to a campaign by its slug. - `itemId=0196499479257&itemId=0000301448594&itemId=0000301826378` are 3 example items for context. The `itemId` parameter must be sent multiple times to include multiple items. If the campaign doesn't require an item context and you don't want to use it in filters, skip the `itemId` parameter entirely. - `98A5FC55-0000-0000-0000-98339BDECAE6` is an example tracker key. - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID.
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns?token=98A5FC55-0000-0000-0000-98339BDECAE6' \
--header 'Content-Type: application/json' \
--data '{
    "clientUUID": "cf9e9b57-7776-51bc-b7bc-75cc75abdf59",
    "campaignId": "DkhvrZoTKthD"
}'
where: - `DkhvrZoTKthD` is an example campaign ID. You can also refer to a campaign by its slug. - `98A5FC55-0000-0000-0000-98339BDECAE6` is an example tracker key. - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID.
This example shows an XHR request with error handling.
var xhr = new XMLHttpRequest();

// Add an event listener for 'readystatechange' to handle the response
xhr.addEventListener("readystatechange", function() {
  if(this.readyState === XMLHttpRequest.DONE) {
    if (this.status >= 200 && this.status < 300) {
      // Successful response
      console.log(this.responseText);
    } else {
      // Handle errors
      console.error('Request failed with status:', this.status, 'and response:', this.responseText);
    }
  }
});

// Open a GET request
xhr.open("GET", "https://api.synerise.com/recommendations/v2/recommend/campaigns/DkhvrZoTKthD?token=98A5FC55-0000-0000-0000-98339BDECAE6&clientUUID=cf9e9b57-7776-51bc-b7bc-75cc75abdf59", true);

// Send the request
xhr.send();
where: - `DkhvrZoTKthD` is an example campaign ID. You can also refer to a campaign by its slug. - `98A5FC55-0000-0000-0000-98339BDECAE6` is an example tracker key. - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID.
### Requests to a model Instead of getting the results of a recommendation campaign, you can make ad-hoc requests to recommendation models. In this case, each model has separate endpoints (see [API Reference](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#tag/Recommendations) for a list).
- In these requests, you can pass a `campaignId` parameter. This parameter is added as `utm_campaign` to the links in the recommendation response for use in Decision Hub. It doesn't need to point to any existing recommendation campaign. - Some recommendation types require additional information, for example the "Recent interactions" model needs an aggregate that defines the interactions to take into account. For details, see the API reference of a particular recommendation type.
**Examples**:
This request fetches a personalized recommendation without any item context or filters.
curl --location 'https://api.synerise.com/recommendations/v2/recommend/items/users/cf9e9b57-7776-51bc-b7bc-75cc75abdf59?token=98A5FC55-0000-0000-0000-98339BDECAE6'
where: - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID - `98A5FC55-0000-0000-0000-98339BDECAE6` is an example tracker key For more details, see [API Reference](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#operation/RecommendForUserV2)
This request fetches a recommendation of complementary items for a cart. It lists two items (items in the cart) as the context and explicitly declares the catalog (if not declared, the catalog name is `default`)
curl --location 'https://api.synerise.com/recommendations/v2/recommend/items/complementary?clientUuid=cf9e9b57-7776-51bc-b7bc-75cc75abdf59&itemId=0000300395769&itemId=0000323544569&itemCatalogId=shoestore&token=98A5FC55-0000-0000-0000-98339BDECAE6&'
where: - `cf9e9b57-7776-51bc-b7bc-75cc75abdf59` is an example profile UUID - `itemId=0000300395769&itemId=0000323544569` are 2 example items for context (items in the cart) The `itemId` parameter must be sent multiple times to include multiple items. - `shoestore` is an example item catalog ID If the `itemCatalogId` parameter isn't included, it defaults to `default` - `98A5FC55-0000-0000-0000-98339BDECAE6` is an example tracker key For more details, see [API Reference](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#operation/ComplementItems)
## Learn more A comprehensive list of all endpoints, settings, and parameters is available in the [API Reference](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#tag/Recommendations). ### Event tracking Everything your customers do is recorded in the system. What pages they've opened, where they came from, and what they saw next. You will know when they hovered over a banner for a longer time than usual and when they clicked that banner. You can know when they logged in to your mobile application and what parts of that application they've clicked or interacted with - all events are monitored in real time. In addition to what is gathered automatically, you can declare many different types of events and gather as much data as you need by tagging fields in your web forms. All events have at least the following: + action - indicates the action type, in the form `context.activity`, so, for example, `page.visit` means that a page has been visited + time - the time when the event occurred + uuid - a reference to the customer that generated the activity + params - any additional parameters, some of them are required (depends on the activity context, for example, the url of the page for a `page.visit`) To see the parameters required by events which exist in Synerise by default, see the [API Reference](https://developers.synerise.com/DataManagement/DataManagement.html#tag/Events). ## Authentication Requests to the SDK may require customer authentication. For more details, see [this article](/developers/web/jwt-auth). ## Automatically tracked activities All page view events on your website are tracked automatically, unless configured otherwise (see [installation and configuration](/developers/web/installation-and-configuration)). The same applies to events related to the customer session. Each time a page is refreshed, the tracking code is initiated. At this moment, a `page.visit` event is generated, providing information about the page visited by the customer. This means that for single-page applications, which do not refresh between pages, the `page.visit` event must be sent on-demand, as described [here](/developers/web/methods-reference#send-a-pagevisit-event). ### List of automatically tracked activities | Action | Activity Tracked | Label | |:--------------|:------------------------------------------------|:----------------------------| | page.visit | All page views of your tracked domain | Visited page {{page title}} | | session.start | Information about a customer starting a session | Started session | | session.end | Information about a customer ending a session | Session end | ## Declarative tracking (custom events)
DO NOT use custom events for `transaction.charge` events. Transactions must be tracked as described in [Transactions and basket events](/developers/web/transactions-sdk).
Aside from automatically tracked activities, you can also create custom events that record customer actions. This could be the tracking of all product views, screen views, sign-up button clicks, call-center contacts, or anything else you may want.
When using the JS SDK, you can only send custom events that are defined in [**Data Modeling Hub > Events**](/docs/assets/events/event-definitions) and have at least the **Make this event available to anonymous profiles without JWT** option selected in their permission settings.
Events with action names that are not defined in the system are rejected.
Parameters that are not defined in the system are saved to a database, but their definitions are not added automatically to Data Modeling Hub and the parameters are not available in analytics and some APIs.
**Example:**
SR.event.trackCustomEvent(
    "entries.count", // event action name
    { // additional parameters
        "lat": "50.0937",
        "lon": "18.5429",
        "object": "Shopping center",
        "shopId": "S198",
        "shopName": "Chicago",
        "zipCode": "60639",
        "street": "W North Ave",
        "time": 1556474400000,
        "entries": 27
    }
)
The method takes two arguments: + The name of the action. (line 2) + An object that contains optional event parameters (lines 3-13)
- The action name must follow the `context.action` convention. For example: `screen.view`, `product.buy`, `social.share` - The action name must be up to 32 characters long and must match the following regular expression: ``` ^[a-zA-Z0-9\.\-_]+$ ```
### Synerise Authentication Synerise Authentication (also known as Registration as a Service) provides customer identity and account management features native to Synerise without any need for third party systems. To use RaaS, implement a set of methods listed below in your application.
For a full list of available methods, see the [method reference section](/developers/mobile-sdk/method-reference).
Additionally, in the Synerise platform (`app.synerise.com`) you can define the following settings: - [Registration mode](/docs/settings/tool/iam-for-apps/synerise#registration-mode) - [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) - [Custom ID overwriting](/docs/settings/tool/iam-for-apps/general#custom-id-overwriting) - [External ID overwriting](/docs/settings/tool/iam-for-apps/general#external-id-overwriting) - [Enabling email address change through a link in the email](/docs/settings/tool/iam-for-apps/general#email-address-change) - [Templates of email notifications](/docs/settings/tool/iam-for-apps/general#templates) such as account confirmation, email change request, PIN confirmation, and so on. - [Password policy](/docs/settings/tool/iam-for-apps/synerise#password-policy) ## Registration methods --- ### Register new customers This method lets you pass all customer information along with any agreements and attributes at once. The primary unique identifier used by Synerise is the email address. However, you may also define a `customId` as a unique identifier. You can read more [here](/docs/settings/configuration/non-unique-emails). | OS | Method | |--------------|-------------------------------------------------------------------------------------------------------------------------------------------| | Android | [Client.registerAccount(registerClient)](/developers/mobile-sdk/method-reference/android/client-authentication#register-customer-account) | | iOS | [Client.registerAccount(context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#register-customer-account) | | React Native | [Synerise.Client.registerAccount(context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#register-customer-account) | | Flutter | [Synerise.client.registerAccount(context)](/developers/mobile-sdk/method-reference/flutter/client-authentication#register-customer-account) | Depending on backend configuration at Synerise, the registration may or may not require email confirmations/ The following registration behaviors are supported: | Name | Description | |-----------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Automatic | The account is ready to use right after registration, no confirmations are required. Customer has the attribute `snrs_email_confirmed` set to `false`. | | Email Confirmation Required | The account is ready to use right after registration, but the email confirmation is required. The confirmation sets `snrs_email_confirmed` to `true`. | | Email Activation Required | An activation email is sent and the account cannot be used until the address is confirmed. Activation also means that `snrs_email_confirmed` is set to `true`. | | PIN Activation Required | An activation email is sent and the account cannot be used until the PIN sent in the email is provided ([Android](/developers/mobile-sdk/method-reference/android/client-authentication#request-customer-account-activation-by-pin), [iOS](/developers/mobile-sdk/method-reference/ios/client-authentication#request-customer-account-activation-by-pin), [React Native](/developers/mobile-sdk/method-reference/react-native/client-authentication#request-customer-account-activation-by-pin)). | ### Request customer account activation by email This method requests sending an email with a URL that confirms the registration and activates the account. | OS | Method | |--------------|-----------------------------------------------------------------------------------------------------------------------| | Android | [Client.requestAccountActivation(email)](/developers/mobile-sdk/method-reference/android/client-authentication#request-customer-account-activation) | | iOS | [Client.requestAccountActivation(email:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#request-customer-account-activation) | | React Native | [Synerise.Client.requestAccountActivation(email, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#request-customer-account-activation) | | Flutter | [Synerise.client.requestAccountActivation(email)](/developers/mobile-sdk/method-reference/flutter/client-authentication#request-customer-account-activation) | ### Confirm customer account activation This method confirms a customer account with the confirmation token. | OS | Method | |--------------|-----------------------------------------------------------------------------------------------------------------------| | Android | [Client.confirmAccountActivation(token)](/developers/mobile-sdk/method-reference/android/client-authentication#confirm-customer-account-activation) | | iOS | [Client.confirmAccountActivation(token:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#confirm-customer-account-activation) | | React Native | [Synerise.Client.confirmAccountActivation(token, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#confirm-customer-account-activation) | | Flutter | [Synerise.client.confirmAccountActivation(token)](/developers/mobile-sdk/method-reference/flutter/client-authentication#confirm-customer-account-activation) | ### Request customer account by pin This method requests sending an email to a customer with the PIN code needed during account registration process. | OS | Method | |--------------|-----------------------------------------------------------------------------------------------------------------------| | Android | [Client.requestAccountActivationByPin(email)](/developers/mobile-sdk/method-reference/android/client-authentication#request-customer-account-activation-by-pin) | | iOS | [Client.requestAccountActivationByPin(email:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#request-customer-account-activation-by-pin) | | React Native | [Synerise.Client.requestAccountActivationByPin(email, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#request-customer-account-activation-by-pin) | | Flutter | n/a | ### Confirm customer account activation by pin This method requires a customer to enter a PIN code during account registration process sent through an email. | OS | Method | |--------------|-----------------------------------------------------------------------------------------------------------------------| | Android | [Client.confirmAccountActivationByPin(pinCode, email)](/developers/mobile-sdk/method-reference/android/client-authentication#confirm-customer-account-activation-by-pin) | | iOS | [Client.confirmAccountActivationByPin(pinCode:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#confirm-customer-account-activation-by-pin) | | React Native | [Synerise.Client.confirmAccountActivationByPin(pinCode, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#confirm-customer-account-activation-by-pin) | | Flutter | n/a | ## Authentication methods --- Once a customer is registered, you can let users log in by implementing this method. After a successful log-in, the application receives a JWT token. The SDK refreshes that token while a customer is using the application and events are being sent (auto-refresh occurs only when the token is still valid).
Token longevity can be changed in the Synerise application. You can learn how to do it in [this article](/docs/settings/tool/iam-for-apps/general#jwt-lifetime).
| OS | Method | |--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Android | - [Client.signIn()](/developers/mobile-sdk/method-reference/android/client-authentication#sign-in-a-customer)
- [Client.signInConditionally](/developers/mobile-sdk/method-reference/android/client-authentication#sign-in-a-customer-conditionally) | | iOS | - [Client.signIn(email:password:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-in-a-customer)
- [Client.signInConditionally(email:password:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-in-a-customer-conditionally) | | React Native | [Synerise.Client.signIn()](/developers/mobile-sdk/method-reference/react-native/client-authentication#sign-in-a-customer)
[Synerise.Client.signInConditionally](/developers/mobile-sdk/method-reference/react-native/client-authentication#sign-in-a-customer-conditionally) | | Flutter | [Synerise.client.signIn()](/developers/mobile-sdk/method-reference/flutter/client-authentication#sign-in-a-customer) | ## Other methods --- ### Check if a customer is signed in This method checks if a customer is signed in through oAuth, Facebook, Sign in with Apple, or RaaS.
This method returns `false` if a customer is authenticated through [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication).
| OS | Method | |--------------|-------------------------------------------------------------------------------------------------------------------------------------------| | Android | [Client.isSignedIn()](/developers/mobile-sdk/method-reference/android/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | iOS | [Client.isSignedIn()](/developers/mobile-sdk/method-reference/ios/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | React Native | [Synerise.Client.isSignedIn()](/developers/mobile-sdk/method-reference/react-native/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | Flutter | [Synerise.client.isSignedIn()](/developers/mobile-sdk/method-reference/flutter/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | ### 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 account is registered and/or they are 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). ### Customer authentication --- ## Set Client State listener --- This method sets callbacks for a customer's state changes. **Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientStateChangeListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#client-state-listener) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public setClientStateChangeListener(listener: IClientStateChangeListener)
**Discussion:** Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#client-state-listener). ## Register customer account --- This method registers a new customer with an email, password, and optional data. This method requires the context object with a customer’s email, password, and optional data. Omitted fields are not modified. Depending on the backend configuration, the account may require activation. For details, see [customer registration](/developers/mobile-sdk/user-identification-and-authorization/overview). Do not allow signing in again (or signing up) when a customer is already signed in. Sign the customer out first. Do not create multiple instances nor call this method multiple times before execution. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_REGISTER_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAccountRegisterContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountregistercontext) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public registerAccount(context: ClientAccountRegisterContext, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountRegisterContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountregistercontext) | yes | - | Object with the customer's email, password, and other optional data | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let email = "EMAIL"; let password = "PASSWORD"; let context = new ClientAccountRegisterContext(email, password); context.phone = '123456789'; context.customId = '000111'; context.firstName = 'John'; context.lastName = 'Rise'; context.sex = ClientSex.Male; context.company = 'Synerise'; context.address = 'Marszałkowska'; context.city = 'Warszawa'; context.province = 'Mazowieckie'; context.zipCode = '00-000'; context.countryCode = 'PL'; context.agreements = new ClientAgreements({ email: true, sms: false, push: true, bluetooth: false, rfid: true, wifi: false }); context.attributes = { ATTRIBUTE_1: 'ATTRIBUTE_1' } context.tags = ['TAG_1', 'TAG_2'] Synerise.Client.registerAccount(context, function() { // success }, function(error) { // failure }); ```
## Request customer account activation --- This method requests sending an email with a URL that confirms the registration and activates the account. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public requestAccountActivation(email: string, onSuccess: () => void, onError: (error: Error) => void)
Before version 1.0.0, this method was called `activateAccount`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | string | yes | - | Customer's email | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```TypeScript Synerise.Client.requestAccountActivation("EMAIL", function() { // success }, function(error) { // failure }); ```
## Confirm customer account activation --- This method confirms a customer account with the confirmation token. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 400 status code if the account is already confirmed or 404 if the account does not exist.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public confirmAccountActivation(token: string, onSuccess: () => void, onError: (error: Error) => void)
Before version 1.0.0, this method was called `confirmAccount`.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | string | yes | - | Customer's token provided by email | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.confirmAccountActivation("TOKEN", function() { // success }, function(error) { // failure }); ```
## Request customer account activation by pin --- This method requests a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public requestAccountActivationByPin(email: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | string | yes | - | Customer's email | | **onSuccess** | Function | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. ## Confirm customer account activation by pin --- This method confirms a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public confirmAccountActivationByPin(pinCode: string, email: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pinCode** | string | yes | - | Code sent to a customer's email | | **email** | string | yes | - | Customer's email | | **onSuccess** | Function | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. ## Sign in a customer --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public signIn(email: string, password: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | string | yes | - | Customer's email | | **password** | string | yes | - | Customer's password | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let email = "EMAIL"; let password = "PASSWORD"; Synerise.Client.signIn(email, password, function() { // success }, function(error) { // failure }); ```
## Sign in a customer conditionally --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public signInConditionally(email: string, password: string, onSuccess: (authResult: ClientConditionalAuthResult) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | string | yes | - | Customer's email | | **password** | string | yes | - | Customer's password | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let email = "EMAIL"; let password = "PASSWORD"; Synerise.Client.signInConditionally(email, password, function(clientConditionalAuthResult) { // success }, function(error) { // failure }); ```
## Authenticate customer by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. If an account for the customer does not exist and the identity provider is different than Synerise, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | 0.3.0 | **Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAuthContext](/developers/mobile-sdk/class-reference/react-native/client#clientauthcontext) [ClientIdentityProvider](/developers/mobile-sdk/class-reference/react-native/client#clientidentityprovider) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticate(token: string, provider: ClientIdentityProvider, context: ClientAuthContext, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | string | yes | - | Token retrieved from provider | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/react-native/client#clientidentityprovider) | yes | - | Provider of your token | | **context** | [ClientAuthContext](/developers/mobile-sdk/class-reference/react-native/client#clientauthcontext) | yes | - | Object which wraps around agreements, attributes and authId | | **onSuccess** | Function | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.authenticate(token, ClientIdentityProvider.Oauth, context, function() { // success }, function(error) { // failure }) ```
## Authenticate customer conditionally by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAuthContext](/developers/mobile-sdk/class-reference/react-native/client#clientauthcontext) [ClientIdentityProvider](/developers/mobile-sdk/class-reference/react-native/client#clientidentityprovider) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticateConditionally(token: string, provider: ClientIdentityProvider, context: ClientAuthContext, onSuccess: (authResult: ClientConditionalAuthResult) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | string | yes | - | Token retrieved from provider | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/react-native/client#clientidentityprovider) | yes | - | Provider of your token | | **context** | [ClientAuthContext](/developers/mobile-sdk/class-reference/react-native/client#clientauthcontext) | no | - | Object which contains agreements, attributes, and identifier of authorization | | **onSuccess** | Function | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.authenticateConditionally(token, ClientIdentityProvider.Oauth, context, function(clientConditionalAuthResult) { // success }, function(error) { // failure }) ```
## Authenticate customer via Simple Profile Authentication --- This method authenticates a customer with Simple Profile Authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 |
When you use this method, you must set a request validation salt by using the `Synerise.setRequestValidationSalt(_:)` method (if salt is enabled for Simple Profile Authentication).
The API key must have the `SAUTH_SIMPLE_AUTH_CREATE` from the **Auth** group.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientSimpleAuthenticationData](/developers/mobile-sdk/class-reference/react-native/client#clientsimpleauthenticationdata) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public simpleAuthentication(data: ClientSimpleAuthenticationData, authID: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **data** | [ClientSimpleAuthenticationData](/developers/mobile-sdk/class-reference/react-native/client#clientsimpleauthenticationdata) | yes | - | Object which contains customer data | | **authID** | string | yes | - | Required identifier of authorization | | **onSuccess** | Function | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```TypeScript let data: ClientSimpleAuthenticationData = new ClientSimpleAuthenticationData(); context.email = "EMAIL"; context.firstName = "FIRST_NAME"; let authID: String = "AUTH_ID" Synerise.Client.simpleAuthentication(data, authID, function() { // success }, function(error) { // failure }) ```
## Check if a customer is signed in (via RaaS, OAuth, Facebook, Apple) --- This method checks if a customer is signed in (via Synerise Authentication - RaaS, OAuth, Facebook, Apple). **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public isSignedIn(): boolean
**Return Value:** **true** if the customer is signed in, otherwise returns **false**. **Example:**
```JavaScript let isSignedIn = Synerise.Client.isSignedIn(); ```
## Check if a customer is signed in (via Simple Profile Authentication) --- This method checks if a customer is signed in (via Simple Profile Authentication). | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 | **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public isSignedInViaSimpleAuthentication(): boolean
**Return Value:** **true** if the customer is signed in (via Simple Profile Authentication), otherwise returns **false**. **Example:**
```JavaScript let isSignedIn = Synerise.Client.isSignedInViaSimpleAuthentication(); ```
## Sign out a customer --- This method signs out a customer out.
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public signOut()
**Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.signOut(); ```
## Sign out customer with mode or from all devices --- This method signs out a customer out with a chosen mode and Determines if the method should sign out all devices. Available modes: - `.signOut` mode signs out the customer. - `.signOutWithSessionDestroy` mode signs out the customer and additionally, clears the anonymous session and regenerates the customer UUID. The `fromAllDevices` parameter determines whether the method should notify the backend to sign out all devices. **IMPORTANT: It is an asynchronous method.** | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.11.0 | 5.1.0 | 0.14.0 | 1.0.0 |
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientSignOutMode](/developers/mobile-sdk/class-reference/react-native/client#clientsignoutmode) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public signOutWithMode(mode: ClientSignOutMode, fromAllDevices: boolean, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **mode** | [ClientSignOutMode](/developers/mobile-sdk/class-reference/react-native/client#clientsignoutmode) | yes | - | Mode of signing out | | **fromAllDevices** | Bool | yes | - | Determines if the method should sign out all devices | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.signOutWithMode( ClientSignOutMode.SignOutWithSessionDestroy, true, () => { this.setState({ isLoading: false, isSignedIn: true, }) }, (error) => { this.setState({ isLoading: false, isSignedIn: false, }) console.log('ERROR: ' + error.message); } ) ```
## Deprecated methods ### Authenticate customer by OAuth with registration --- This method authenticates a customer with OAuth. If an account for the customer does not exist, this request creates an account. | Available on | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided access token and/or API Key is invalid.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientOAuthAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientoauthauthenticationcontext) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticateByOAuth(accessToken: string, context: ClientOAuthAuthenticationContext, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | string | yes | - | OAuth Access Token | | **clientOAuthContext** | [ClientOAuthAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientoauthauthenticationcontext) | yes | - | Object which contains agreements, attributes, and identifier of authorization | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.authenticateByOAuth(token, context, function() { // success }, function(error) { // failure }) ```
### Authenticate customer by OAuth without registration --- This method authenticates a customer with OAuth. | Available on | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided access token and/or API Key is invalid.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticateByOAuthIfRegistered(accessToken: string, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | string | yes | - | OAuth Access Token | | **authID** | string | no | null | Optional identifier of authorization | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.authenticateByOAuthIfRegistered(accessToken, authID, function() { // success }, function(error) { // failure }) ```
### Authenticate customer by Facebook with registration --- This method authenticates a customer with Facebook. If an account for the customer does not exist, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided Facebook token and/or API Key is invalid.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientFacebookAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientfacebookauthenticationcontext) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticateByFacebook(facebookToken: string, context: ClientFacebookAuthenticationContext, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | string | yes | - | Facebook Access Token | | **clientFacebookAuthenticationContext** | [ClientFacebookAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientfacebookauthenticationcontext) | yes | - | Object which contains agreements, attributes, and identifier of authorization | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.authenticateByFacebook(token, clientFacebookAuthenticationContext, function(clientConditionalAuthResult) { // success }, function(error) { // failure }) ```
### Authenticate customer by Facebook without registration --- This method authenticates a customer with Facebook. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided Facebook token and/or API Key is invalid.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticateByFacebookIfRegistered(facebookToken: string, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | string | yes | - | Facebook Access Token | | **authID** | string | no | null | Optional identifier of authorization | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.authenticateByFacebookIfRegistered(facebookToken, authID, function() { // success }, function(error) { // failure }) ```
### Authenticate customer by Sign in with Apple with registration --- This method authenticates a customer with Sign In With Apple. If an account for the customer does not exist, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | n/a | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | n/a | 0.9.19 | n/a | | Removed in: | 5.0.0 | n/a | 1.0.0 | n/a | **Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAppleSignInAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientapplesigninauthenticationcontext) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticateByAppleSignIn(identityToken: string, context: ClientAppleSignInAuthenticationContext, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identityToken** | string | yes | - | Apple Identity Token | | **context** | [ClientAppleSignInAuthenticationContext](/developers/mobile-sdk/class-reference/react-native/client#clientapplesigninauthenticationcontext) | yes | - | Object which contains agreements, attributes, and identifier of authorization | | **success** | Function | no | - | Function to be executed when the operation is completed successfully | | **failure** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. ### Authenticate customer by Sign in with Apple without registration --- This method authenticates a customer with Sign In With Apple. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public authenticateByAppleSignInIfRegistered(identityToken: string, authID: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identityToken** | string | yes | - | Apple Identity Token | | **authID** | string | no | null | Optional identifier of authorization | | **success** | Function | no | - | Function to be executed when the operation is completed successfully | | **failure** | Function | no | - | Function to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. ### Insert usage # Insert usage examples This section presents some practical examples and mechanisms of inserts. In inserts, you use: - Jinjava elements (values), inserted in the following way: `{{ ... }}` Such a value will be printed in the place where it's used. - tags, which are statements that allow you to use functions and build logic. They are inserted in the following ways: `{% ... %}`, `{%- ... -%}` (see ["Tag delimiters"](/developers/inserts/tag#tag-delimiters))
If you use Visual Studio Code as your editor, you can use code snippets to speed up working with inserts. You can find the snippets in our Github repository: [https://github.com/Synerise/jinja-code-snippet](https://github.com/Synerise/jinja-code-snippet)
## Operators Operators let you compare and manipulate values or add more complex logic. ### Logic operators See ["If, else if, else: Combining conditions"](/developers/inserts/tag#combining-conditions). ### Math operators | Operator | Description | Example | | --- | --- | --- | | `+` | Adds numbers, lists, objects, or strings.1 | `{{ 1 + 2 }}` = 3| | `-` | Subtracts numbers. | `{{ 2 - 1 }}` = 1| | `/` | Divides numbers, returns a floating point number. | `{{ 5 / 2 }}` = 2.5 | | `//` | Divides numbers, rounds to an integer. | `{{ 5 // 2 }}` = 2 | | `%` | Returns the remainder of a division. | `{{ 5 % 2 }}` = 1 | | `*` | Multiplies numbers. | `{{ 3 * 2 }}` = 6 | | `**` | Raises to a power. | `{{ 2 ** 3 }}` = 8 | | `()` | Groups formulas. | `{{ (2 + 2) * 2 }}` = 8| 1 The recommended way to concatenate strings is the `~` operator (see ["Other"](#other-operators)). ### Comparison operators | Operator | Description | Example | | --- | --- | --- | | `==`1 | L(eft) is equal to R(ight) | `{{ 2 == 2 }}` = true | | `!=`1 | L is not equal to R| `{{ 2 != 3 }}` = true | | `>` | L is greater than R | `{{ 2 > 1 }}` = true | | `>=` | L is greater than or equal to R | `{{ 3 >= 3 }}` = true | | `<` | L is lower than R | `{{ 1 < 2 }}` = true | | `<=` | L is lower than or equal to R | `{{ 3 <= 3 }}` = true | 1Can be used to compare strings, objects, and lists. ### Other operators | Operator | Description | Example | | --- | --- | --- | | `in` | Checks if a value is in a list. | `{{ 2 in [1,2,3] }}` = true | | `is` | Performs a [test](/developers/inserts/exptest). | `{{ 4 is divisibleby 2 }}` = true | | `~` | Converts L and R into strings and concatenates them. |
{%- set p = "world" -%}{{ "Hello, " ~ p ~ "!" }}
= Hello, world! | ## Objects and arrays ### Object properties You can access object properties in the following ways: - `object.get('property')` - accepts special characters in property names. - `object.property` - doesn't accept special characters in property names. - `object['property']` - accepts special characters in property names. If there is a chance that a property doesn't exist, you need to verify if it's defined, using tests such as [`is defined`](/developers/inserts/exptest#isdefined). Otherwise, rendering might fail or there might be nulls or whitespaces in rendered output. **Examples**:
{% set exampleProduct = {'size':12,'prop:title':'Item'} %}

{{ exampleProduct.get('size') }}       {# renders successfully #}
{{ exampleProduct['size'] }}           {# renders successfully #}
{{ exampleProduct.size }}              {# renders successfully #}

{{ exampleProduct.get('prop:title') }} {# renders successfully #}
{{ exampleProduct['prop:title'] }}     {# renders successfully #}
{{ exampleProduct.prop:title }}        {# error in rendering the template (special character in name) #}

{% if exampleProduct.get('color') is defined %} {# verify if property exists to avoid unexpected behavior #}
    {{ exampleProduct.get('color') }}      
    {{ exampleProduct['color'] }}          
    {{ exampleProduct.color }}             
{% endif %}
### Arrays You can access values from an array by referring to the index:
{% set exampleArray = [1,2,3] %}

{{ exampleArray[0] }} {# output: 1 #}
{{ exampleArray[2] }} {# output: 3 #}
{% if exampleArray | length > 4 %}  {#RECOMMENDED: to avoid errors, verify array size before accessing an index #}
    {{ exampleArray[4] }} 
{% else %}
  Index 4 is out of range
{% endif %}
### Nested arrays and objects An object can contain objects and arrays:
{% set exampleObject = {'nestedObject':{'size':12}} %}

{{ exampleObject.nestedObject }}     {# output: {size=12} #}
{{ exampleObject.nestedObject.size}} {# output: 12 #}
An array can contain objects and arrays:
{% set exampleArray = [{'size':12,'prop:title':'Item'},{'size':14,'prop:title':'Item2'}] %}

{{ exampleArray[0] }}      {# output: {size=12, prop:title=Item} #}
{{ exampleArray[1].size }} {# output: 14 #}
## Expressions To find out what expressions are and how to create them, read [this article](/docs/analytics/expressions).
{% expression %} expression-hash {% endexpression %}
**Example:** An expression that holds the value of an abandoned cart.
<h1>
  Total amount: {% expression %} 4085025a-313e-4a63-a6b4-d19820853912 {% endexpression %}$
</h1>
Output:
<h1>
  Total amount: 345$
</h1>
You can also use the expression result as a variable:
{% expressionvar expression-hash %}
    {{ expression_result }} {# the result of the expression is stored in this variable #}
{% endexpressionvar %}
**Example**: The result of an expression that is a number can be rounded:
{% expressionvar 0abc195a-548e-460d-a904-1e285b8adb96 %}
    You have {{ expression_result|round }} loyalty points.
{% endexpressionvar %}
## Aggregates To find out what aggregates are and how to create them, read [this article](/docs/analytics/aggregates/creating-aggregates).
If an aggregate has dynamic elements (such as values from another aggregate or expression), then instead of using the `aggregate` tag: 1. Create an expression that includes the aggregate with dynamic values. 2. Insert this expression by using the [`expression` tag](#expressions).
**Syntax:**
{% aggregate aggregate-hash %}
  {{ aggregate_result[0] }}
{% endaggregate %}
The aggregate result is always returned as a list. To use the data, use [loops](/developers/inserts/tag#for) or access a [specific index](/developers/inserts/insert-usage#arrays) in the result.
**Example:** An aggregate that holds a list of categories that have recently been added to the cart.
{% aggregate 0b352529-497e-3cbd-bf3d-fcb6072cef9e %}
<ul>
  {%- for item in aggregate_result -%}
  <li>{{ item }}</li>
  {%- endfor -%}
</ul>
{% endaggregate %}
Output:
<ul>
  <li>Home</li>
  <li>Sports</li>
  <li>Toys</li>
  <li>Electronics</li>
</ul>
Troubleshooting common problems: - If your template fails to render, verify that all referenced aggregates exist. - If the output is empty, use [try/catch](/developers/inserts/tag#trycatch) to handle empty aggregate results.
## Promotions
YouTube video
--- You can use an insert to retrieve promotions assigned to a profile, including anonymous profiles.
This tag is currently only available in Experience and Automation Hubs.
**Syntax:**
{%- set getFields=["code"] -%}
{%- promotions fields=getFields [optional arguments] -%}
{{ promotions_result }}
{%- endpromotions -%}
where: - `getFields` is a variable that declares the promotion properties you want to include in the result. In this example, only one property is retrieved.
Available fields
  • uuid
  • code
  • status
  • type
  • redeemLimitPerClient
  • redeemQuantityPerActivation
  • currentRedeemedQuantity
  • currentRedeemLimit
  • activationCounter
  • possibleRedeems
  • details
  • discountType
  • discountValue
  • discountMode
  • discountModeDetails
  • requireRedeemedPoints
  • name
  • headline
  • description
  • images
  • startAt
  • expireAt
  • displayFrom
  • displayTo
  • assignedAt
  • lastingTime
  • lastingAt
  • catalogIndexItems
  • params
  • price
  • priority
  • maxBasketValue
  • minBasketValue
  • itemScope
  • tags
  • handbillUuid
- the `fields` argument (required, non-empty) uses the `getFields` variable in the function. This is the only way of using an array-type argument in a function. - `optional arguments` can be used to filter the results. See ["Optional arguments"](#optional-arguments). - `promotions_result` is an object with all promotions assigned to a profile. You can retrieve up to 100 promotions. This can be changed by contacting Synerise Support. **Example:**
{%- set getFields=["code","discountValue","images"] -%}
{%- promotions fields=getFields -%}
You have available promotions!<br>
{%- for i in promotions_result -%}
    Code: {{ i.code }}<br>
    Discount: {{ i.discountValue }} USD<br>
    <img src="{{ i.images[0].url }}"><br>
    <br>
{%- endfor -%}
{%- endpromotions -%}
You have available promotions!<br>
Code: d139125e-88a2-4146-a1b3-d766b94d859d<br>
Discount: 100 USD<br>
<img src="https://upload.snrcdn.net/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/f8fa57fa59egrhfgh11987845c19c5c.png"><br>
<br>Code: 501000d9-5f96-4362-9350-eccf592e4e4b<br>
Discount: 20 USD<br>
<img src="https://upload.snrcdn.net/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/50d289eff4234tr78a900cdf3bee.png"><br>
<br>Code: 089a9ab2-0171-4eb4-93a5-8d2e12822be1<br>
Discount: 15 USD<br>
<img src="https://upload.snrcdn.net/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/7af3145sdffgh3acd0124a25a91.png"><br>
<br>
### Optional arguments You can manipulate the results of the `{% promotions %}` insert with the following optional arguments: | Name | Type | Default | Description | | ----------------- | ---------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `limit` | Integer | 20 | The maximum number of promotions to retrieve. | | `status` | String | No filtering | Filter results by status: `ACTIVE`, `ASSIGNED`, `REDEEMED`. | | `sort` | Array of strings | See description | Sort results by field, choose direction with `asc` and `desc`, for example: `priority,desc`. You can also use fields that aren't declared in the `fields` argument.
If not defined, the promotions are sorted by our AI. If the AI model isn't trained, they are sorted by creation date, ascending.
This argument must be declared with `{% set %}` and used as a variable - the variable is an array with one string that consists of the field name and direction (see example below the table). | | `tagNames` | Array of strings | No filtering | Filter results to promotions with certain tags. Must be declared with `{% set %}` and used as a variable. | | `presentOnly` | Boolean | No filtering | When `true`, only promotions with `startAt later than now` and `expireAt earlier than now` are retrieved. | | `displayableOnly` | Boolean | No filtering | When `true`, only promotions with `displayFrom later than now` and `displayTo earlier than now` are retrieved. | | `uuids` | Array of strings | No filtering | Filter results to promotions with certain UUIDs. Must be declared with `{% set %}` and used as a variable. | **Example:** Retrieve promotions that are currently displayable, filter by tags, and sort by creation date:
{%- set getFields = ["code"] -%}
{%- set filterTags = ["foo","bar"] -%}
{%- set sort = ["createdAt,desc"] -%}
{%- promotions fields=getFields displayableOnly=true tagNames=filterTags sort=sort -%}
{{ promotions_result }}
{%- endpromotions -%}
## Personalized promotions
YouTube video
This insert can only be used in Experience and Automation Hubs.
The `handbills` insert assigns [personalized promotions](/docs/ai-hub/personalized-promotions) to a profile and returns a list of promotions assigned to the profile, including promotions with type other than `HANDBILL`. By default, the insert returns up to 20 promotions of all types, with any status. You can change this with optional parameters. **Syntax**:
{%- set handbillUuidVar=["UUID"] -%}
{%- handbills handbillUuids=handbillUuidVar [optional arguments] -%}
{{ handbills_result }}
{%- endhandbills -%}
where: - `handbillUuids` is a list of personalized promotions (handbills) to assign and retrieve. The value must be stored in a variable (`handbillUuidVar` in the snippet above). - `optional arguments` can be used to filter the results. See ["Optional arguments"](#optional-arguments-2). - `handbills_result` is an array of retrieved promotions. To learn about the returned parameters, see the response of the ["Generate batch handbill for Profile and get Profile promotions" endpoint in the API reference documentation](https://developers.synerise.com/LoyaltyandEngagement/LoyaltyandEngagement.html#tag/Handbills/operation/getAssignHandbillsForClient_GET).
See example raw output

This output shows 2 promotions.

[{handbillUuid=3f56de5a-b560-456d-8c94-cb63bc0c53be, currentRedeemedQuantity=0, headline=, name=test1, priority=250, discountType=NONE, discountValue=0, redeemQuantityPerActivation=1, description=, currentRedeemLimit=0, tags=null, uuid=86c67c62-0b70-4144-a986-688510d00332, redeemLimitPerClient=1000, price=1, params=null, possibleRedeems=0, assignedAt=2025-07-29T14:23:14.057Z, discountMode=STATIC, maxBasketValue=null, activationCounter=0, expireAt=null, code=d98cca9b-e7c0-4639-8bdc-a1d0441068cc, itemScope=LINE_ITEM, displayFrom=null, startAt=null, status=ASSIGNED, lastingAt=2025-07-30T14:23:14.046Z, catalogIndexItems=[Ljava.lang.Object;@75377931, details=null, displayTo=null, lastingTime=0, type=HANDBILL, requireRedeemedPoints=0, minBasketValue=null, images=[Ljava.lang.Object;@2b3c4cdf, discountModeDetails=null}, {currentRedeemedQuantity=0, headline=null, name=test2, priority=250, discountType=AMOUNT, discountValue=0, redeemQuantityPerActivation=null, description=null, currentRedeemLimit=null, tags=null, uuid=01caa294-5d81-4130-ab44-a7427f0ff779, redeemLimitPerClient=324, price=0, params=null, possibleRedeems=1, discountMode=STEP, maxBasketValue=null, activationCounter=0, expireAt=null, code=1067d8f5-1460-4387-abeb-8a4a3e97ec35, itemScope=LINE_ITEM, displayFrom=null, startAt=null, status=ASSIGNED, lastingAt=null, catalogIndexItems=null, details=null, displayTo=null, lastingTime=0, type=GENERAL, requireRedeemedPoints=0, minBasketValue=null, images=null, discountModeDetails={discountUsageTrigger=REDEEM, steps=[Ljava.lang.Object;@41e37d59}}]

**Example**: You can iterate over the returned promotions and retrieve only the parameters that you need.
{%- set handbillUuidVar=["3f56de5a-b560-456d-8c94-cb63bc0c53be","c35d0a9-08b1-4c4f-a8cd-0732b1c00b7f"] -%}
{%- handbills handbillUuids=handbillUuidVar -%}
You have available promotions!<br>
{%- for i in handbills_result -%}
    {{ i.name }}<br>
    <img src="{{ i.images[0].url }}"><br>
    <br>
{%- endfor -%}
{%- endhandbills -%}
You have available promotions!<br>
Hot dog + soda<br>
<img src="https://upload.snrcdn.net/f2afa4d45c19c5c.png"><br>
Cheeseburger 50% off<br>
<img src="https://upload.snrcdn.net/fr78a900cdf3bee.png"><br>
Apple pie + coffee<br>
<img src="https://upload.snrcdn.net/f2afd0124a25a91.png"><br>
<br>
### Optional arguments {#optional-arguments-2} You can filter the results of the `{% handbills %}` insert with these optional arguments: - `type`: a list of promotion types. Must be declared as a variable. The allowed values are: `GENERAL`, `CUSTOM`, `MEMBERS_ONLY`, `HANDBILL` - `status`: a list of promotion statuses. Must be declared as a variable. The allowed values are: `ACTIVE`, `ASSIGNED`, `REDEEMED` - `limit`: the maximum number of results to retrieve. If not defined, 20 results are returned. By default, you can't set the limit to more than 100. To change this, contact Synerise Support. **Example** Retrieve 5 handbill-type promotions that are active or assigned.
{%- set handbillUuidVar=["3f56de5a-b560-456d-8c94-cb63bc0c53be"] -%}
{%- set typeFilterVar=["HANDBILL"] -%}
{%- set statusFilterVar=["ACTIVE","ASSIGNED"] -%}
{%- handbills handbillUuids=handbillUuidVar type=typeFilterVar status=statusFilterVar limit=5 -%}
{%- for i in handbills_result -%}
    <img src="{{ i.images[0].url }}"><br>
{%- endfor -%}
{%- endhandbills -%}
## Recommendations ### Recommendations as Jinjava variable
This insert can't be used in Screen Views and Documents.
This insert can be used to retrieve recommendations in HTML. If you need an insert that can be used in JSON requests (for example, generating a document), see [Screen views and Documents inserts](/developers/inserts/screen-views-documents#recommendations).
{% recommendations3 campaignId=campaignId %}
    {{recommended_products3}} 
{% endrecommendations3 %}
You can find more information, examples, and advanced scenarios in [Inserting recommendations](/developers/inserts/recommendations-v2). ### Recommendations as JSON This insert is only available in [Screen Views and Documents](/developers/inserts/screen-views-documents#recommendations). ## Catalogs To find out what catalogs are and how to create them, read [this article](/docs/assets/catalogs). ### Extracting values from catalogs The following method lets you obtain a single value from a catalog. **Syntax:**
{% catalog.catalogName(itemKey).columnName %}
Or as a variable that you can modify:
{% catalogvar.catalogName(itemKey).columnName %}
  {{ catalog_result }}
{% endcatalogvar %}
where: - `catalogName` is the name of the catalog - `itemKey` is the value of the unique identifier of the item in the catalog. This is the value from the column which you selected as **itemKey** (for data imports by API) or **Primary key** (when importing data into the catalog in the Synerise Portal or with Automation Hub). - `columnName` is the name of the column (attribute) in the item whose value you want to retrieve.
`itemKey` must always be entered as a variable.
CORRECT:
{% set myitemKey = "1234" %}
    {% catalog.catalogName(myitemKey).columnName %}
WRONG:
{% catalog.catalogName("1234").columnName %}
**Example:**
<ul>
    {% aggregate 0b352529-497e-3cbd-bf3d-fcb6072cef9e %}
    {%- for sku_value in aggregate_result -%}
    <li id="{% catalog.myCatalog(sku_value).product:retailer_part_no %}">
        <a href="{% catalog.myCatalog(sku_value).og:url %}" title="{% catalog.myCatalog(sku_value).og:title %}">
            <img src="{% catalog.myCatalog(sku_value).og:image %}">
        </a>
    </li>
    {%- endfor -%}
    {% endaggregate %}
</ul>
1. An [aggregate](#aggregates) (line 2) returns a list of 10 SKUs of recently viewed products. The SKUs will be used as identifiers to retrieve more data about those products from a catalog and display them on a website. 2. On line 3, a loop starts that runs for each SKU in that list. - `sku_value` is an example name of the iterator variable. You can change it. The value of the iterator is the SKU from the aggregate result. - `aggregate_result` is the name of the iterable. The `aggregate` insert from line 2 creates this iterable, always under this name. 3. On lines 4-6, attributes from the `myCatalog` catalog are accessed: 1. SKU was set to be the unique item identifier in the catalog when data was imported into `myCatalog`. 2. `sku_value` is replaced with the current iterator value in each iteration of the loop, so the item identified by the SKU is accessed. 3. The values of the following columns are retrieved: - `product:retailer_part_no` - `og:url` - `og:title` - `og:image` Output:
<ul>
    <li id="000097">
        <a href="https://example.com/accessories-for-shaver/cleaner-contribution-to-shavers,id-2369"
            title="Cleaning insert for shavers">
            <img src="https://example.com/temp/thumbs-new/2/other/cd1c73e35b1db186e79e8a0039b27293_250x200w50.jpg">
        </a>
    </li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
    <li>...</li>
</ul>
### Extracting items from catalogs as objects You can retrieve an entire item as an object and extract values of multiple columns at once using the following syntax:
{% set key = 'itemKey' %}
{% catalogitemv2.catalogName(key) allowEmpty=False %}
    {% set object = catalog_result %}
    {{ object.get("objectColumn").propertyName }}
    {{ object.get("stringColumn") }}
{% endcatalogitemv2 %}
where: - `itemKey` is the unique key of the item in the catalog - `catalogName` is the catalog name - `objectColumn` is the name of the column that stores an object - `propertyName` is the name of a property in the object - `stringColumn` is the name of the column that stores a string - `allowEmpty` is an optional parameter that [manages the handling of non-existing items](#handling-non-existing-items-in-catalogs). The above code, without any changes, will return `foo` and `bar` for the following catalog:
Screenshot of a catalog with one column that stores a string and one column that stores an object
Example of a catalog with one column that stores a string and one column that stores an object
To extract more values, add more `object.get()` statements. #### Handling non-existing items in catalogs By default, when a requested item does not exist in the catalog, the `catalogitemv2` insert is not executed at all (communication is not sent). You can change this behavior by setting the optional `allowEmpty` parameter to `True`. With this setting, the insert returns nulls as the values of the item's parameters. You should always verify if property exists before accessing it in order to avoid errors. The following code returns the string `No item` if the requested `itemKey` does not exist in the catalog and the requested `name` parameter is empty:
{% set key = 'itemKey' %}
{% catalogitemv2.catalogName(key) allowEmpty=True%}
  {% set object = catalog_result %}
  {%- if object.get("name") is defined -%}
    {{ object.get("name") }}
  {%- else -%}
    No item
  {%- endif -%}
{% endcatalogitemv2 %}
## Metrics To find out what metrics are and how to create them, read [this article](/docs/analytics/metrics). **Syntax:**
{% metrics %} metrics-hash {% endmetrics %}
Or as a variable that you can modify:
{% metricsvar metric_id:metrics-hash %}
    {{ metric_result }}
{% endmetricsvar %}
**Example:** A metric that holds the value of products sold in the last 30 days.
{% metricsvar metric_id:07e93207-4dd4-4239-ab1a-9267118276b0 %}

  {% set result = metric_result|int %}

  {%- if result > 4500 -%}
  Bravo! we achieved the set goal
  {%- else -%}
  {{ 4500 - result }} USD more to get a goal
  {%- endif -%}

{% endmetricsvar %}
Output (the metric result is 2400):
2100 USD more to get a goal
## Customer attributes You can access customer attributes, such as the name, surname, email, phone number, and more and use them as variables. By means of those variables, you can personalize the content, for example you can use the name of the customer in the greeting at the beginning of an email. **Syntax:**
{% customer attr-name %}
**Example:** A welcome message.
<div class="snrs-wrapper">
  <div id="snrsCornerMessage" class="snrs-corner-message-wrap">
    <div class="snrs-corner-message">
      <div class="snrs-corner-main">
        <div class="snrs-corner-message-text">
            Hello {% customer firstname %}!
        </div>
      </div>
    </div>
  </div>
</div>
Output (the result of the variable is "John"):
<div class="snrs-wrapper">
  <div id="snrsCornerMessage" class="snrs-corner-message-wrap">
    <div class="snrs-corner-message">
      <div class="snrs-corner-main">
        <div class="snrs-corner-message-text">
            Hello John!
        </div>
      </div>
    </div>
  </div>
</div>
### Inserting attributes conditionally If you're not sure if an attribute is present in the profiles of all target customers, you can use conditional logic. For example:
Hello {%- if customer.get('firstname') -%}{{ customer.firstname }}{%- else -%}user{%- endif -%}!
Output: - If the `firstname` attribute is `John`: `Hello John!` - If the `firstname` attribute does not exist: `Hello user!`
You can also use the [try/catch](/developers/inserts/tag#trycatch) tag and the [default value](/developers/inserts/filter#default) filter.
#### Advanced use You can check if a customer has an attribute set and act accordingly. For example, this can be used to set up a single campaign for customers who have an attribute and those who don't. Without the check, you would need to create two separate campaigns. **Example 1:** Check if a customer belongs to a loyalty club and what kind of membership they have:
{%- if "club_member" in customer.keySet() -%} {# checks if the club_member attribute exists #}
  {%- if customer["club_member"] == "highPriority" -%}
    {#  insert HTML code  #}
  {%- elif customer["club_member"] == "mediumPriority" -%}
    {#  insert HTML code  #}
  {%- elif customer["club_member"] == "lowPriority" -%}
    {#  insert HTML code  #}
  {%- endif -%}
{%- endif -%}
**Example 2:** Check if the customer profile includes an entry about the city of residence:
{%- if "city" in customer.keySet() -%}
  Check the best prices in {{ customer["city"] }}!
{%- else -%}
  Check the best prices in your city!
{%- endif -%}
## Code pools To find out what code pools are and how to create them, read [this article](/docs/assets/code-pools). Normally, each code can only be retrieved once. You can override this behavior by [binding the code to a profile](#retrieving-the-same-code-every-time). This code is stored separately, so you can bind a code and still assign other codes (only one code can be bound to a profile). For example, you can bind a code and use it to identify a profile, and still retrieve codes from other pools to use in marketing campaigns. When a code is assigned or bound to a profile, a [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is generated.
If your code pool is limited, testing email or dynamic content templates (including as a preview in the creator) consumes codes from the pool in the same way as when the communication is sent out to customers. You should use a separate pool for testing.
### Assigning a code to a profile **Syntax:**
{% voucher %} pool-uuid {% endvoucher %}
If the code pool is empty, doesn't exist, or no more codes are available, the insert fails to render. You can use [try/catch statements](/developers/inserts/tag#trycatch) to handle such cases. **Example:** A promotion code from a selected code pool:
<div class="snrs-wrapper">
  <div id="snrsCornerMessage" class="snrs-corner-message-wrap">
    <div class="snrs-corner-message">
      <div class="snrs-corner-main">
        <div class="snrs-corner-message-text">
            Take your promotional code and use it durning the transaction to get a 50% discount!
            <strong>{% voucher %} 274a18d5-e8bd-4fec-82d1-cea0af19af01 {% endvoucher %}</strong>
        </div>
      </div>
    </div>
  </div>
</div>
Output (voucher result is "5510018091219"):
<div class="snrs-wrapper">
  <div id="snrsCornerMessage" class="snrs-corner-message-wrap">
    <div class="snrs-corner-message">
      <div class="snrs-corner-main">
        <div class="snrs-corner-message-text">
            Take your promotional code and use it during the transaction to get a 50% discount!
            <strong>5510018091219</strong>
        </div>
      </div>
    </div>
  </div>
</div>
### Using the code as a variable By using the `vouchervar` tag, you can create a block of code in which the code can be accessed as the `voucher_result` variable. If the code pool is empty, doesn't exist, or no more codes are available, the insert fails to render. You can use [try/catch statements](/developers/inserts/tag#trycatch) to handle such cases. **Syntax:**
{% vouchervar id=pool-uuid %}
  {{ voucher_result }}
{% endvouchervar %}
**Example:** In this example, the voucher's value is accessible as a variable and can be converted to capital letters.
{% vouchervar id=5fae8aba-b48e-4144-8d28-db24b1570ab0 %}
<ul>
  <li>The voucher value is {{ voucher_result }}.</li>
  <li>When capitalized, it becomes {{ voucher_result|capitalize }}.</li>
</ul>
{% endvouchervar %}
The output (the voucher's value is "CapitalizeMe") is:
<ul>
  <li>The voucher value is CapitalizeMe.</li>
  <li>When capitalized, it becomes CAPITALIZEME.</li>
</ul>
### Retrieving the same code every time Setting the `assign` variable to `false` binds a code from a pool to a profile (unless one is already bound) and retrieves that same code for this profile every time. This can be used, for example, to create unique codes that can be used to identify a profile. Binding codes doesn't have any influence on assigning codes (described earlier).
{% voucher assign=false %} pool-uuid {% endvoucher %}
### Barcodes To add a barcode of a voucher to an email template, paste the following code:
{% vouchervar id=pool-uuid  %} 
{% barcode code= {{voucher_result}}, gray=true, type=EAN_13, hrp=BOTTOM %}
{% endvouchervar %}
The result of that insert will be the HTML code for the image of the barcode. If you want to get only the URL of the barcode, use the following code:
{% vouchervar id=pool-uuid  %}
{% barcodeurl code= {{voucher_result}}, gray=true, type=EAN_13, hrp=BOTTOM %}
{% endvouchervar %}
**Explanation of parameters**: - `pool-uuid` is the UUID of a voucher pool available on the platform (**Data Modeling Hub > Voucher pools**). - `gray` defines the color of the barcode. Parameter values: - `TRUE` - The code is generated in grayscale. - `FALSE` - The code consists of black and white pixels. - `type` defines the type of barcode. Parameter values: - `EAN_13` - `EAN_8` - `EAN_128` - `CODE_39` - `CODE_128` - `ITF_14` - `POSTNET` - `UPC-A` - `UPC-E` - `hrp` (*human readable part*) defines the position of the readable part of the code for customers (usually it takes the form of a string of numbers). Parameter values: - `NONE` - There is no readable part of the code. - `BOTTOM` - The readable string is at the bottom of the barcode. - `resolution` defines the resolution of a bar code in dpi and indirectly affects the width of the narrowest bar. ## Snippets You can reference a [snippet](/docs/assets/snippets). The content generated from such a reference is updated when the referenced definition changes. Print the contents of the referenced snippet:
{% snippet %} 6197adde-e1da-4ef1-be40-aa411e2fbdff {% endsnippet %}
Save the referenced snippet to a variable:
{% snippetvar id=6197adde-e1da-4ef1-be40-aa411e2fbdff %}
{{ snippet_result }}
{% endsnippetvar %}
Such a variable can be used in functions. For example, if the referenced snippet contains a number, you can add it to another number:
{% snippetvar id=6197adde-e1da-4ef1-be40-aa411e2fbdff %}
{{ snippet_result|add(5) }}
{% endsnippetvar %}
## Communication campaign metadata You can access the ID and variant ID of the communication campaign. Thanks to this, you don't need to manually edit those details after cloning a campaign or copying content between templates. | Jijava | Example result | Description | | --- | --- | --- | | `{{campaignContext.id}}` | `f3ac122e-9305-441c-9081-79d32b5cf06d` | The ID of the communication campaign | | `{{campaignContext.variantId}}` | `15761220` | ID of the variant. Can be used in all campaign types except for landing pages. | | `{{campaignContext.version}}` | `2025-06-23T10:36:51.927532232` | Version number. Can only be used in landing pages. | ## Stopping communication from rendering You can use the `{% terminate [message] %}` insert to completely stop the message from rendering, which means an email is not sent at all, a dynamic content is not displayed, and so on. When this tag is triggered, a `notSent` ([message](/docs/assets/events/event-reference/email#messagenotsent), [sms](/docs/assets/events/event-reference/sms#smsnotsent), [push](/docs/assets/events/event-reference/mobile-push#pushnotsent), [webpush](/docs/assets/events/event-reference/webpush#webpushnotsent)) or `renderFail` ([inApp](/docs/assets/events/event-reference/inapp#inapprenderfail), [landingpage](/docs/assets/events/event-reference/landing-page#landingpagerenderfail)) is generated. In the event: - the `exception` (SMS, email, push, web push) or `error` (in-app, landing page) parameter is added, with the value set to `TerminateRenderingException` - if you added the `message` parameter to the insert, it's saved in the `info` parameter. Otherwise, the default message is `Jinja rendering terminated by user`. The message doesn't support Jinjava. This can be useful when you want to terminate a communication when a certain condition is met. For example, the following communication: - is terminated for customers whose result of an expression is less than 100. - informs a customer about the result of the expression if it's 100 or more. - adds "Expression result too low" as the `info` parameter in the "not sent" event.
{% expressionvar expression-hash %}
    {%- if expression_result < 100 -%}
      {% terminate Expression result too low %}
    {%- else -%}
      You have {{ expression_result }} loyalty points.
    {%- endif -%}
  {% endexpressionvar %}
This insert used to be known as `kill` and `killit`. They are now deprecated and may be removed in the future.
## Brickworks Use Brickworks content in templates across the Synerise platform with dedicated JinJava tags. JinJava tags work consistently across all Synerise modules that support JinJava rendering, creating a unified content experience throughout your platform: - **Experience Hub channels** – Email campaigns, SMS messaging, mobile push notifications, and web push notifications with dynamic, personalized content - **Automation Hub workflows** – Sophisticated automation sequences with content that adapts based on customer actions and behavioral triggers - **Screen views and Documents** – Interactive displays, personalized mobile applications content - **In-App Messaging**– Contextual experiences that respond to customer behavior in real-time ### Generate record This tag can't be used in Brickworks schemas or records. In Documents and Screen Views, if you want to display an entire object instead of just one property, you need to use `{{ brickworks_result|tojson }}` In singleton schemas, use the API name (`appName`) or UUID of the schema in place of the record identifier. The `brickworksgenerate` tag generates a an object from a record with all references resolved and Jinja templates rendered:
{% set myFieldContext = {"oneToManyRelation": {"page":2, "limit": 50}} %}
{% set myContext={
    "example1":"value1",
    "example2":"value2"
    } 
%}

{% brickworksgenerate schemaId=SCHEMA_ID/APP_ID recordId=RECORD_ID/SLUG context=myContext fieldContext=myFieldContext %}
where: - The values for the `context` and `fieldContext` arguments must be variables created with `set` (as shown above). - `myFieldContext` provides paging data for a relation field named `oneToManyRelation`. You can skip this argument if you don't need it. - `myContext` provides values for two inserts used in the record (regardless of field names): `{{ context.example1 }}` and `{{ context.example2 }}`. You can skip this argument if you don't need it. Alternatively, you can use `brickworksgeneratevar` to create a `{{ brickworks_result }}` variable for reuse in a template:
{% brickworksgeneratevar schemaId=SCHEMA_ID/APP_ID recordId=RECORD_ID/SLUG context=myContext fieldContext=myFieldContext %}
  {{ brickworks_result }}            {# prints out the entire record #}
  {{ brickworks_result.someString }} {# prints out the value of the someString field #}
{% endbrickworksgeneratevar %}
### Fetch raw record This tag can't be used in Brickworks schemas or records. In Documents and Screen Views, if you want to display an entire object instead of just one property, you need to use `{{ brickworks_result|tojson }}` In singleton schemas, use the API name (`appName`) or UUID of the schema in place of the record identifier. - The following tag fetches a raw record as defined in the database:
{% brickworks schemaId=SCHEMA_ID/APP_ID recordId=OBJECT_ID/SLUG %}
- The following tag fetches a raw record as defined in the database, but saves the result to a variable for reuse in your template:
{% brickworksvar schemaId=SCHEMA_ID/APP_ID recordId=OBJECT_ID/SLUG %}
    {{ brickworks_result }}
  {% endbrickworksvar %}
### Fetch raw records This tag lets you retrieve multiple records (raw content) from a schema and access the result as an iterable. This tag can't be used in Brickworks schemas or records. In Documents and Screen Views, if you want to display an entire object instead of just one property, you need to use `{{ brickworks_result|tojson }}`
{% brickworksrecordsvar schemaId=ID/APPID [optional parameters] %}

{# example logic: iterate through result and return record IDs #}
{% for record in brickworks_result %}
{{ record.id }} 
{% endfor %}
{# end example logic #}
{% endbrickworksrecordsvar %}
where: - `schemaId` is the App ID or UUID of a schema. - `optional parameters` can be used to sort and filter the retrieved records: - The parameters can be applied in two ways (see [examples](#filtering-examples)): - as arguments in the tag. In this case, `slugs`, `ids`, and `filters` must be declared with `set` first. - as a `filteringParams` object. If you insert the same parameter in both ways, `filteringParams` takes precedence. - You can use these parameters: - `sortBy`: a record attribute to sort by and the sorting direction. **This parameter can't be added to `filteringParams`** For a list of sorting attributes, see the [/v1/schemas/{schemaIdentifier}/records (Get records) endpoint](https://developers.synerise.com/Brickworks/Brickworks.html#tag/Brickworks:-Records/operation/getRecordsFromSchema). - `search`: a string to search for in the values of fields which are [configured as searchable in the schema](/docs/assets/brickworks/schema-field-types#common-field-properties). - `filters`: an RSQL string to filter the records. These following system parameter names must include the `__` prefix: `__id`, `__schemaId`, `__name`, `__slug`, `__status`, `__createdAt`, `__updatedAt`, `__publishedAt`, `__recordVersion` - `slugs`: a list of record slugs. Looks for exact matches. - `ids`: a list of record IDs. Looks for exact matches.
You can collect the filters in an object and provide that object as an argument in the tag. Example:
{% set parametersVar = {
    search: "string",
    filters: "status==PUBLISHED",
    slugs: ["string","string"],
    ids: ["uuid","uuid"]
} %}
{% brickworksrecordsvar
    schemaId=string
    filteringParams=parametersVar %}
{{ brickworks_result }}
{% endbrickworksrecordsvar %}
You can enter the filters as arguments of the tag. Some of them must first be declared as variables with `set`, as shown in the example:
{% set filtersVar = "status==PUBLISHED" %}
{% set slugsVar = ["string","string"] %}
{% set idsVar = ["uuid","uuid"] %}
{% brickworksrecordsvar 
    schemaId=string
    search=string
    sortBy=createdAt:asc
    filters=filtersVar
    slugs=slugsVar
    ids=idsVar
%}
{{ brickworks_result }}
{% endbrickworksrecordsvar %}
### Customer authentication ## Set Client State delegate --- This method sets an object for a customer's state delegate methods. **Declared In:** Headers/SNRClient.h **Related To:** [ClientStateDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#client-state-delegate) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func setClientStateDelegate(_ delegate: ClientStateDelegate) ```
```Objective-C + (void)setClientStateDelegate:(SNRClientStateDelegate *)delegate ```
**Discussion:** Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#client-state-delegate). ## Register customer account --- This method registers a new customer with an email, password, and optional data. This method requires the context object with a customer’s email, password, and optional data. Omitted fields are not modified. Depending on the backend configuration, the account may require activation. For details, see [customer registration](/developers/mobile-sdk/user-identification-and-authorization/overview). Do not allow signing in again (or signing up) when a customer is already signed in. Sign the customer out first. Do not create multiple instances nor call this method multiple times before execution. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_REGISTER_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Related To:** [ClientRegisterAccountContext](/developers/mobile-sdk/class-reference/ios/client#clientregisteraccountcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func registerAccount(context: ClientRegisterAccountContext, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)registerAccount:(nonnull SNRClientRegisterAccountContext *)context success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientRegisterAccountContext](/developers/mobile-sdk/class-reference/ios/client#clientregisteraccountcontext) | yes | - | Object with the customer's email, password, and other optional data | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let agreements: ClientAgreements = ClientAgreements() agreements.email = true agreements.sms = true agreements.push = true agreements.bluetooth = true agreements.rfid = true agreements.wifi = true let email: String = "YOUR_EMAIL" let password: String = "YOUR_PASSWORD" let context: ClientRegisterAccountContext = ClientRegisterAccountContext(email: email, password: password) context.firstName = "FIRST_NAME" context.lastName = "LAST_NAME" context.customId = "CUSTOM_ID" context.sex = .male context.phone = "123-456-789" context.company = "Synerise" context.address = "Lubostroń 1" context.city = "Kraków" context.province = "Małopolskie" context.zipCode = "30-383" context.countryCode = "+48" context.agreements = agreements context.attributes = ["attribute1": "value1", "attribute2": "value2"] context.tags = ["tag1", "tag2" "tag3"] Client.registerAccount(context: context, success: { // success }, failure: { (error) in // failure }) ```
```Objective-C SNRClientAgreements *agreements = [SNRClientAgreements new]; agreements.email = true; agreements.sms = true; agreements.push = true; agreements.bluetooth = true; agreements.rfid = true; agreements.wifi = true; NSString *email = @"EMAIL"; NSString *password = @"PASSWORD"; SNRClientRegisterAccountContext *context = [SNRClientRegisterAccountContext alloc] initWithEmail:email andPassword:password]; context.firstName = @"FIRST_NAME"; context.lastName = @"LAST_NAME"; context.customId = @"CUSTOM_ID"; context.sex = SNRClientSexMale; context.phone = @"123-456-789"; context.company = @"Synerise"; context.address = @"Lubostroń 1"; context.city = @"Kraków"; context.province = @"Małopolskie"; context.zipCode = @"30-383"; context.countryCode = @"+48"; context.agreements = agreements; context.attributes = @{@"attribute": @"value"}; context.tags = @[@"tag1", @"tag2" @"tag3"]; [SNRClient registerAccount:context success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Request customer account activation --- This method requests sending an email with a URL that confirms the registration and activates the account. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func requestAccountActivation(email: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)requestAccountActivationWithEmail:(nonnull NSString *)email success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's email | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Before version 5.0.0, this method was called `Synerise.activateAccount(email:success:failure:)`.
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let email: String = "EMAIL" Client.requestAccountActivation(email: email, success: { // success }) { (error) in // failure } ```
```Objective-C NSString *email = @"EMAIL"; [SNRClient requestAccountActivationWithEmail:email success:^() { // success } failure:^(NSError * error) { // failure }]; ```
## Confirm customer account activation --- This method confirms a customer account with the confirmation token. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 400 status code if the account is already confirmed or 404 if the account does not exist.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func confirmAccountActivation(token: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)confirmAccountActivationByToken:(nonnull NSString *)token success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Confirmation token | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Before version 5.0.0, this method was called `Synerise.confirmAccount(token:success:failure:)`.
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let token: String = "TOKEN" Client.confirmAccountActivation(token: token, success: { // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *token = @"TOKEN"; [SNRClient confirmAccountActivationByToken:token success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Request customer account activation by pin --- This method requests a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func requestAccountActivationByPin(email: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)requestAccountActivationByPinWithEmail:(nonnull NSString *)email success:(nonnull void (^)(void))success failure:(nonnull void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's email | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let email: String = "EMAIL" Client.requestAccountActivationByPin(email: email, success: { // success }) { (error) in // failure } ```
```Objective-C NSString *email = @"EMAIL"; [SNRClient requestAccountActivationByPinWithEmail:email success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Confirm customer account activation by pin --- This method confirms a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func confirmAccountActivationByPin(pinCode: String, email: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)confirmAccountActivationByPin:(nonnull NSString *)pinCode email:(nonnull NSString *)email success:(nonnull void (^)(void))success failure:(nonnull void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pinCode** | String | yes | - | Code sent to a customer's email | | **email** | String | yes | - | Customer's email | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let pinCode: String = "PIN_CODE" let email: String = "EMAIL" Client.confirmAccountActivationByPin(pinCode: pinCode, email: email, success: { // success }) { (error) in // failure } ```
```Objective-C NSString *pinCode = @"PIN_CODE"; NSString *email = @"EMAIL"; [SNRClient confirmAccountActivationByPin:pinCode email:email success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Sign in a customer --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func signIn(email: String, password: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)signInWithEmail:(nonnull NSString *)email password:(nonnull NSString *)password success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's email | | **password** | String | yes | - | Customer's password | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let email: String = "EMAIL" let password: String = "PASSWORD" Client.signIn(email: email, password: password, success: { // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *email = @"EMAIL"; NSString *password = @"PASSWORD"; [SNRClient signInWithEmail:email password:password success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Sign in a customer conditionally --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func signInConditionally(email: String, password: String, success: ((ClientAuthenticationResult) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)signInConditionallyWithEmail:(nonnull NSString *)email password:(nonnull NSString *)password success:(nonnull void (^)(SNRClientAuthenticationResult *result))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's email | | **password** | String | yes | - | Customer's password | | **success** | ((ClientAuthenticationResult) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let email: String = "EMAIL" let password: String = "PASSWORD" Client.signInConditionally(email: email, password: password, success: { (result) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *email = @"EMAIL"; NSString *password = @"PASSWORD"; [SNRClient signInConditionallyWithEmail:email password:password success:^(SNRClientAuthenticationResult *result) { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Authenticate customer by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. If an account for the customer does not exist and the identity provider is different than Synerise, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | 0.3.0 | **Declared In:** Headers/SNRClient.h **Related To:** [ClientAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientauthenticationcontext) [ClientIdentityProivider](/developers/mobile-sdk/class-reference/ios/client#clientidentityprovider) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticate(token: AnyObject, clientIdentityProvider: ClientIdentityProvider, authID: String?, context: ClientAuthenticationContext?, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateWithToken:(id)token clientIdentityProvider:(SNRClientIdentityProvider)clientIdentityProvider authID:(nullable NSString *)authID context:(nullable SNRClientAuthenticationContext *)context success:(void (^)(void))success failure:(void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | AnyObject | yes | - | Token retrieved from provider | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/ios/client#clientidentityprovider) | yes | - | Provider of your token | | **authID** | String | no | nil | Optional identifier of authorization | | **context** | [ClientAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientauthenticationcontext) | no | nil | Object which contains agreements and attributes | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let agreements: ClientAgreements = ClientAgreements() agreements.email = true agreements.sms = true agreements.push = true agreements.bluetooth = true agreements.rfid = true agreements.wifi = true let context: ClientAuthenticationContext = ClientAuthenticationContext() context.agreements = agreements context.attributes = ["attribute1": "value1", "attribute2": "value2"] let accessToken: String = "ACCESS_TOKEN" let authID: String = "AUTH_ID" Client.authenticate(token: token, authID: authID, context: context, success: { // success }) { (error) in // failure } ```
```Objective-C SNRClientAgreements *agreements = [SNRClientAgreements new]; agreements.email = true; agreements.sms = true; agreements.push = true; agreements.bluetooth = true; agreements.rfid = true; agreements.wifi = true; SNRClientAuthenticationContext *context = [SNRClientAuthenticationContext new]; context.agreements = agreements; context.attributes = @{"attribute1": "value1", "attribute2": "value2"}; NSString *accessToken = @"ACCESS_TOKEN"; NSString *authID = @"AUTH_ID"; [SNRClient authenticateWithToken:token authID:authID context:context success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Authenticate customer conditionally by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Declared In:** Headers/SNRClient.h **Related To:** [ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/ios/client#clientconditionalauthresult) [ClientIdentityProvider](/developers/mobile-sdk/class-reference/ios/client#clientidentityprovider) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/client) **Declaration:**
```Swift static func authenticateConditionally(token: AnyObject, clientIdentityProvider: ClientIdentityProvider, authID: String?, context: ClientConditionalAuthenticationContext?, success: ((ClientAuthenticationResult) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateConditionallyWithToken:(id)token clientIdentityProvider:(SNRClientIdentityProvider)clientIdentityProvider authID:(nullable NSString *)authID context:(nullable SNRClientConditionalAuthenticationContext *)context success:(void (^)(SNRClientAuthenticationResult *authenticationResult))success failure:(void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | AnyObject | yes | - | Token retrieved from provider | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/ios/client#clientidentityprovider) | yes | - | Provider of your token | | **authID** | String | no | nil | Optional identifier of authorization | | **context** | [ClientConditionalAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientconditionalauthenticationcontext) | no | nil | Object which contains agreements and attributes | | **success** | (([ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/ios/client#clientconditionalauthenticationcontext)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
```Swift let agreements: ClientAgreements = ClientAgreements() agreements.email = true agreements.sms = true agreements.push = true agreements.bluetooth = true agreements.rfid = true agreements.wifi = true let context: ClientConditionalAuthenticationContext = ClientConditionalAuthenticationContext() context.agreements = agreements context.attributes = ["attribute1": "value1", "attribute2": "value2"] let accessToken: String = "ACCESS_TOKEN" let authID: String = "AUTH_ID" Client.authenticateConditionally(token: token, authID: authID, context: context, success: { (success) in // success }) { (error) in // failure } ```
```Objective-C SNRClientAgreements *agreements = [SNRClientAgreements new]; agreements.email = true; agreements.sms = true; agreements.push = true; agreements.bluetooth = true; agreements.rfid = true; agreements.wifi = true; SNRClientConditionalAuthenticationContext *context = [SNRClientConditionalAuthenticationContext new]; context.agreements = agreements; context.attributes = @{"attribute1": "value1", "attribute2": "value2"}; NSString *accessToken = @"ACCESS_TOKEN"; NSString *authID = @"AUTH_ID"; [SNRClient authenticateConditionallyWithToken:token authID:authID context:context success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Authenticate customer with token payload --- This method signs in a customer in with the provided token payload. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.15.0 | 5.15.0 | n/a | n/a | **Declared In:** Headers/SNRClient.h **Related To:** [TokenPayload](/developers/mobile-sdk/class-reference/ios/client#tokenpayload) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticate(tokenPayload: TokenPayload, authID: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateWithTokenPayload:(SNRTokenPayload *)tokenPayload authID:(NSString *)authID success:(void (^)(void))success failure:(void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **tokenPayload** | [TokenPayload](/developers/mobile-sdk/class-reference/ios/client#tokenpayload) | yes | - | Object which contains a token's payload | | **authID** | String | yes | - | Required customer's identifier of authorization | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasion the number of UUID refreshes so it must be unique for every customer.
**Return Value:** No value is returned. ## Authenticate customer via Simple Profile Authentication --- This method authenticates a customer with Simple Profile Authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 |
When you use this method, you must set a request validation salt by using the `Synerise.setRequestValidationSalt(_:)` method (if salt is enabled for Simple Profile Authentication).
The API key must have the `SAUTH_SIMPLE_AUTH_CREATE` from the **Auth** group.
**Declared In:** Headers/SNRClient.h **Related To:** [ClientSimpleAuthenticationData](/developers/mobile-sdk/class-reference/ios/client#clientsimpleauthenticationdata) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func simpleAuthentication(data: ClientSimpleAuthenticationData, authID: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)simpleAuthentication:(SNRClientSimpleAuthenticationData *)data authID:(NSString *)authID success:(void (^)(void))success failure:(void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **data** | [ClientSimpleAuthenticationData](/developers/mobile-sdk/class-reference/ios/client#clientsimpleauthenticationdata) | yes | - | Object which contains customer data | | **authID** | String | yes | - | Required identifier of authorization | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. ## Check if a customer is signed in (via RaaS, OAuth, Facebook, Apple) --- This method checks if a customer is signed in (via Synerise Authentication - RaaS, OAuth, Facebook, Apple). **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func isSignedIn() -> Bool ```
```Objective-C + (BOOL)isSignedIn ```
**Return Value:** **true** if the customer is signed in, otherwise returns **false**. **Example:**
```Swift let isSignedIn: Bool = Client.isSignedIn() ```
```Objective-C BOOL isSignedIn = [SNRClient isSignedIn]; ```
## Check if a customer is signed in (via Simple Profile Authentication) --- This method checks if a customer is signed in (via Simple Profile Authentication). | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 | **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func isSignedInViaSimpleAuthentication() -> Bool ```
```Objective-C + (BOOL)isSignedInViaSimpleAuthentication ```
**Return Value:** **true** if the customer is signed in (via Simple Profile Authentication), otherwise returns **false**. ## Sign out customer --- This method signs out a customer out.
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func signOut() -> Void ```
```Objective-C + (void)signOut ```
**Return Value:** No value is returned. **Example:**
```Swift Client.signOut() ```
```Objective-C [SNRClient signOut]; ```
## Sign out customer with mode or from all devices --- This method signs out a customer out with a chosen mode and Determines if the method should sign out all devices. Available modes: - `.signOut` mode signs out the customer. - `.signOutWithSessionDestroy` mode signs out the customer and additionally, clears the anonymous session and regenerates the customer UUID. The `fromAllDevices` parameter determines whether the method should notify the backend to sign out all devices. **IMPORTANT: It is an asynchronous method.** | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.11.0 | 5.1.0 | 0.14.0 | 1.0.0 |
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func signOut(mode: ClientSignOutMode, fromAllDevices: Bool, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)signOutWithmode:(SNRClientSignOutMode)mode fromAllDevices:(BOOL)fromAllDevices success:(void (^)(void))success failure:(void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **mode** | [ClientSignOutMode](/developers/mobile-sdk/class-reference/ios/client#clientsignoutmode) | yes | - | Mode of signing out | | **fromAllDevices** | Bool | yes | - | Determines if the method should sign out all devices | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift Client.signOut(mode: .signOutWithSessionDestroy, fromAllDevices: true, success: { // success }) { (error) in // failure } ```
```Objective-C [SNRClient signOutWithMode:SNRClientSignOutModeSignOutWithSessionDestroy fromAllDevices:YES success:^{ // success } failure:^(SNRApiError *error) { // failure }]; ```
## Removed methods ### Authenticate customer by OAuth with registration {#authenticate-customer-by-oauth-with-registration} --- This method authenticates a customer with OAuth. If an account for the customer does not exist, this request creates an account. | Available on | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided access token and/or API Key is invalid.
**Replaced By:** [Authenticate customer by IdentityProvider](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-identityprovider) **Declared In:** Headers/SNRClient.h **Related To:** [ClientOAuthAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientoauthauthenticationcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticateByOAuth(accessToken: String, authID: String?, context: ClientOAuthAuthenticationContext?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateByOAuthWithAccessToken:(NSString *)accessToken authID:(nullable NSString *)authID context:(nullable SNRClientOAuthAuthenticationContext *)context success:(nullable void (^)(BOOL isSuccess))success failure:(nullable void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | String | yes | - | OAuth Access Token | | **authID** | String | no | nil | Optional identifier of authorization | | **context** | [ClientOAuthAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientoauthauthenticationcontext) | no | nil | Object which contains agreements and attributes | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
```Swift let agreements: ClientAgreements = ClientAgreements() agreements.email = true agreements.sms = true agreements.push = true agreements.bluetooth = true agreements.rfid = true agreements.wifi = true let context: ClientOAuthContext = ClientOAuthContext() context.agreements = agreements context.attributes = ["attribute1": "value1", "attribute2": "value2"] let accessToken: String = "ACCESS_TOKEN" let authID: String = "AUTH_ID" Client.authenticateByOAuth(accessToken: accessToken, authID: authID, context: context, success: { (success) in // success }) { (error) in // failure } ```
```Objective-C SNRClientAgreements *agreements = [SNRClientAgreements new]; agreements.email = true; agreements.sms = true; agreements.push = true; agreements.bluetooth = true; agreements.rfid = true; agreements.wifi = true; SNRClientOAuthContext *context = [SNRClientOAuthContext new]; context.agreements = agreements; context.attributes = @{"attribute1": "value1", "attribute2": "value2"}; NSString *accessToken = @"ACCESS_TOKEN"; NSString *authID = @"AUTH_ID"; [SNRClient authenticateByOAuthWithAccessToken:accessToken authID:authID context:context success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Authenticate customer by OAuth without registration {#authenticate-customer-by-oauth-without-registration} --- This method authenticates a customer with OAuth. | Available on | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided access token and/or API Key is invalid.
**Replaced By:** [Authenticate customer conditionally by IdentityProvider](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticateByOAuthIfRegistered(accessToken: String, authID: String?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateByOAuthIfRegisteredWithAccessToken:(nonnull NSString *)accessToken authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | String | yes | - | OAuth Access Token | | **authID** | String | no | nil | Optional identifier of authorization | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. ### Authenticate customer by Facebook with registration {#authenticate-customer-by-facebook-with-registration} --- This method authenticates a customer with Facebook. If an account for the customer does not exist, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided Facebook token and/or API Key is invalid.
**Replaced By:** [Authenticate customer by IdentityProvider](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-identityprovider) **Declared In:** Headers/SNRClient.h **Related To:** [ClientFacebookAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientfacebookauthenticationcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticateByFacebook(facebookToken: String, authID: String?, context: ClientFacebookAuthenticationContext?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateByFacebookWithFacebookToken:(nonnull NSString *)facebookToken authID:(nullable NSString *)authID context:(nullable SNRClientFacebookAuthenticationContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | String | yes | - | Facebook Access Token | | **authID** | String | no | nil | Optional identifier of authorization | | **context** | [ClientFacebookAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientfacebookauthenticationcontext) | no | nil | Object which contains agreements and attributes | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
```Swift let agreements: ClientAgreements = ClientAgreements() agreements.email = true agreements.sms = true agreements.push = true agreements.bluetooth = true agreements.rfid = true agreements.wifi = true let context: ClientFacebookAuthenticationContext = ClientFacebookAuthenticationContext() context.agreements = agreements context.attributes = ["attribute1": "value1", "attribute2": "value2"] guard let facebookToken = FBSDKAccessToken.current()?.tokenString else { return } let authID: String = "AUTH_ID" Client.authenticateByFacebook(facebookToken: fa, authID: authID, context: context, success: { (success) in // success }) { (error) in // failure } ```
```Objective-C SNRClientAgreements *agreements = [SNRClientAgreements new]; agreements.email = true; agreements.sms = true; agreements.push = true; agreements.bluetooth = true; agreements.rfid = true; agreements.wifi = true; SNRClientFacebookAuthenticationContext *context = [SNRClientFacebookAuthenticationContext new]; context.agreements = agreements; context.attributes = @{"attribute1": "value1", "attribute2": "value2"}; NSString *facebookToken = [FBSDKAccessToken currentAccessToken].tokenString; NSString *authID = @"AUTH_ID"; [SNRClient authenticateByFacebookWithFacebookToken:facebookToken authID:authID context:context success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Authenticate customer by Facebook without registration {#authenticate-customer-by-facebook-without-registration} --- This method authenticates a customer with Facebook. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided Facebook token and/or API Key is invalid.
**Replaced By:** [Authenticate customer conditionally by IdentityProvider](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticateByFacebookIfRegistered(facebookToken: String, authID: String?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateByFacebookIfRegisteredWithFacebookToken:(nonnull NSString *)facebookToken authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | String | yes | - | Facebook Access Token | | **authID** | String | no | nil | Optional identifier of authorization | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
```Swift guard let facebookToken = FBSDKAccessToken.current()?.tokenString else { return } let authID: String = "AUTH_ID" Client.authenticateByFacebookIfRegistered(facebookToken: facebookToken, success: { (success) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *facebookToken = [FBSDKAccessToken currentAccessToken].tokenString; NSString *authID = @"AUTH_ID"; [SNRClient authenticateByFacebookIfRegisteredWithFacebookToken:facebookToken authID:authID success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Authenticate customer by Sign in with Apple with registration {#authenticate-customer-by-sign-in-with-apple-with-registration} --- This method authenticates a customer with Sign In With Apple. If an account for the customer does not exist, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | n/a | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | n/a | 0.9.19 | n/a | | Removed in: | 5.0.0 | n/a | 1.0.0 | n/a | **Replaced By:** [Authenticate customer by IdentityProvider](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-identityprovider) **Declared In:** Headers/SNRClient.h **Related To:** [ClientAppleSignInAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientapplesigninauthenticationcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticateByAppleSignIn(identityToken: Data, authID: String?, context: ClientAppleSignInAuthenticationContext?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateByAppleSignInWithIdentityToken:(nonnull NSData *)identityToken authID:(nullable NSString *)authID context:(nullable SNRClientAppleSignInAuthenticationContext *)context success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identityToken** | Data | yes | - | Apple Identity Token | | **context** | [ClientAppleSignInAuthenticationContext](/developers/mobile-sdk/class-reference/ios/client#clientapplesigninauthenticationcontext) | no | nil | Object which contains agreements and attributes | | **authID** | String | no | nil | Optional identifier of authorization | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
```Swift extension LoginViewController: ASAuthorizationControllerDelegate { func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) { if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential { let agreements: ClientAgreements = ClientAgreements() agreements.email = true agreements.sms = true agreements.push = true agreements.bluetooth = true agreements.rfid = true agreements.wifi = true let context: ClientAppleSignInAuthenticationContext = ClientAppleSignInAuthenticationContext(identityToken: appleIdCredential.identityToken!) context.agreements = agreements context.attributes = ["param": "value"] Client.authenticateByAppleSignIn(context: context, authID: authID, success: { (success) in // success }) { (error) in // failure } } } } ```
```Objective-C #pragma mark - ASAuthorizationControllerDelegate - (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization { id credential = authorization.credential; if (credential != nil) { SNRClientAgreements *agreements = [SNRClientAgreements new]; agreements.email = true; agreements.sms = true; agreements.push = true; agreements.bluetooth = true; agreements.rfid = true; agreements.wifi = true; SNRClientAppleSignInAuthenticationContext*context = [[SNRClientAppleSignInAuthenticationContext alloc] initWithIdentityToken:credential.identityToken]; context.agreements = agreements; context.attributes = @{"attribute1": "value1", "attribute2": "value2"}; [SNRClient authenticateByAppleSignInWithContext:context authID:authID success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; } } ```
### Authenticate customer by Sign in with Apple without registration {#authenticate-customer-by-sign-in-with-apple-without-registration} --- This method authenticates a customer with Sign In With Apple. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Replaced By:** [Authenticate customer conditionally by IdentityProvider](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func authenticateByAppleSignInIfRegistered(identityToken: String, authID: String?, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)authenticateByAppleSignInIfRegisteredWithIdentityToken:(nonnull NSData *)identityToken authID:(nullable NSString *)authID success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identityToken** | String | yes | - | Apple Identity Token | | **authID** | String | no | nil | Optional identifier of authorization | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. ### Sign out customer with mode {#sign-out-customer-with-mode} --- This method signs out a customer out with a chosen mode: - `.signOut` mode notifies the backend that the customer is signed out. - `.signOutWithSessionDestroy` mode notifies the backend that the customer is signed out and additionally, clears the anonymous session and regenerates the customer UUID. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.4.0 | 4.6.0 | 0.12.0 | 0.7.0 | | Deprecated in: | 4.11.0 | 5.1.0 | - | - | | Removed in: | 5.0.0 | 6.0.0 | 0.14.0 | 1.0.0 |
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Replaced By:** [Sign out with mode or from all devices](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-out-customer-with-mode-or-from-all-devices) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func signOut(mode: ClientSignOutMode) -> Void ```
```Objective-C + (void)signOutWithmode:(SNRClientSignOutMode)mode ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **mode** | [ClientSignOutMode](/developers/mobile-sdk/class-reference/ios/client#clientsignoutmode) | yes | - | Mode of signing out | **Return Value:** No value is returned. **Example:**
```Swift Client.signOut(mode: .signOutWithSessionDestroy) ```
```Objective-C [SNRClient signOutWithMode:SNRClientSignOutModeSignOutWithSessionDestroy]; ```
### Modules ### BaseModule **Declared In:** lib/modules/base/base_module.dart **Declaration:**
class BaseModule
--- --- ### Settings **Declared In:** lib/modules/notifications/settings_impl.dart **Declaration:**
class SettingsImpl
**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.
Future<void> registerForNotifications(String registrationToken, {bool? mobileAgreement, required void Function() onSuccess, required void Function(SyneriseError error) onError})
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#register-for-push-notifications) --- This method handles a notification payload and starts activity.
Future<bool> handleNotification(Map notification) async
[(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.
Future<bool> handleNotificationClick(Map notification) async
[(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.
Future<bool> isSyneriseNotification(Map notification) async
[(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
Future<bool> isSyneriseSimplePush(Map notification) async
[(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.
Future<bool> isSyneriseBanner(Map notification) async
[(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.
Future<bool> isSilentCommand(Map notification) async
[(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.
Future<bool> isSilentSDKCommand(Map notification) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/campaigns#check-if-push-notification-is-a-silent-sdk-command) --- --- ### Client **Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientAccountRegisterContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountregistercontext) [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) [ClientAuthContext](/developers/mobile-sdk/class-reference/flutter/client#clientauthcontext) [ClientConditionalAuthContext](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthcontext) [ClientAccountInformation](/developers/mobile-sdk/class-reference/flutter/client#clientaccountinformation) [ClientAccountUpdateContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountupdatecontext) [ClientConditionalAuthResult](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthresult) [ClientPasswordResetRequestContext](/developers/mobile-sdk/method-reference/flutter/client-account#request-password-reset-for-customer-account) [ClientPasswordResetConfirmationContext](/developers/mobile-sdk/method-reference/flutter/client-account#confirm-password-reset-for-customer-account) [Token](/developers/mobile-sdk/class-reference/flutter/client#token) **Inherits From:** [BaseModule](/developers/mobile-sdk/class-reference/flutter/modules#basemodule) **Declaration:**
class ClientImpl extends BaseModule
**Methods:** This method registers a new customer with an email, password, and optional data.
Future<void> registerAccount(ClientAccountRegisterContext context, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> confirmAccountActivation(String token, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-authentication#confirm-customer-account-activation) --- This method activates a customer with email.
Future<void> requestAccountActivation(String email, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> requestAccountActivationByPin(String email, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> confirmAccountActivationByPin(String email, String pinCode, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> signIn(String email, String password, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> signInConditionally(String email, String password, {required void Function(ClientConditionalAuthResult) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> authenticate(ClientAuthContext clientAuthContext, IdentityProvider identityProvider, String tokenString, {required void Function(bool) onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> authenticateConditionally(ClientConditionalAuthContext clientAuthContext, IdentityProvider identityProvider, String tokenString, {String? authID, required void Function(ClientConditionalAuthResult) onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> simpleAuthentication(ClientSimpleAuthenticationData data, String authID, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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).
Future<bool> isSignedInViaSimpleAuthentication() async
[(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
Future<void> signOutWithMode(ClientSignOutMode mode, bool fromAllDevices, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> refreshToken({required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#refresh-customer-token) --- This method retrieves the customer’s current, active token.
Future<void> retrieveToken({required void Function(Token) onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> regenerateUUIDWithClientIdentifier(String clientIdentifier) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#regenerate-customer-with-identifier) --- This method destroys the session completely.
Future<void> destroySession({required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-session#destroy-current-session) --- This method gets a customer’s account information.
Future<void> getAccount({required void Function(ClientAccountInformation) onSuccess, required void Function(SyneriseError) onError}) async
[(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).
Future<void> updateAccountBasicInformation(ClientAccountUpdateBasicInformationContext context, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> updateAccount(ClientAccountUpdateContext context, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> requestPasswordReset(String email, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> confirmPasswordReset(String password, String token, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> changePassword(String oldPassword, String newPassword, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#change-customers-account-password) --- This method requests a customer's email change.
Future<void> requestEmailChange(String email, String password, {String? externalToken, String? authID, required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#request-email-change-for-customer-account) --- This method confirms an email change.
Future<void> confirmEmailChange(String token, bool newsletterAgreement, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> requestPhoneUpdate(String phone, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> confirmPhoneUpdate(String phone, String confirmationCode, bool smsAgreement, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(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.
Future<void> deleteAccount(String clientAuthFactor, IdentityProvider identityProvider, {String? authId, required void Function() onSuccess, required void Function(SyneriseError) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/client-account#delete-customer-account) --- --- --- ### Tracker **Declared In:** lib/modules/tracker/tracker_impl.dart **Related To:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Inherits From:** [BaseModule](/developers/mobile-sdk/class-reference/flutter/modules#basemodule) **Declaration:**
class TrackerImpl extends BaseModule
**Methods:** This method sets a custom identifier in the parameters of every event.
Future<void> setCustomIdentifier(String customIdentifier) async
[(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.
Future<void> setCustomEmail(String customEmail) async
[(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.
Future<void> getAllPromotions({required void Function(PromotionResponse promotionResponse) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> getPromotions(PromotionsApiQuery apiQuery, {required void Function(PromotionResponse promotionResponse) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> getPromotionByUUID(String uuid, {required void Function(Promotion promotion) onSuccess, required void Function(SyneriseError error) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-promotion-by-uuid) --- This method retrieves the promotion with the specified code.
Future<void> getPromotionByCode(String code, {required void Function(Promotion promotion) onSuccess, required void Function(SyneriseError error) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#get-promotion-by-code) --- This method activates the promotion with the specified UUID.
Future<void> activatePromotionByUUID(String uuid, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#activate-promotion-by-uuid) --- This method activates the promotion with the specified code.
Future<void> activatePromotionByCode(String code, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> activatePromotionsBatch(List<PromotionIdentifier> promotionsToActivate, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> deactivatePromotionByUUID(String uuid, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#deactivate-promotion-by-uuid) --- This method deactivates the promotion with the specified code.
Future<void> deactivatePromotionByCode(String code, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> deactivatePromotionsBatch(List<PromotionIdentifier> promotionsToDeactivate, {required void Function() onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> getOrAssignVoucher(String poolUuid, {required void Function(AssignVoucherResponse assignVoucherResponse) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> assignVoucherCode(String poolUuid, {required void Function(AssignVoucherResponse response) onSuccess, required void Function(SyneriseError error) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/promotions#assign-voucher-code-from-pool) --- This method retrieves voucher codes for a customer.
Future<void> getAssignedVoucherCodes({required void Function(VoucherCodesResponse voucherCodesResponse) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> getDocuments(DocumentsApiQuery documentsApiQuery, {required void Function(List<Map<String, Object>> documentsList) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> generateDocument(String slug, {required void Function(Document document) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> generateDocumentWithApiQuery(DocumentApiQuery apiQuery, {required void Function(Document document) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<List<Map<String, Object>>> getDocuments(DocumentsApiQuery documentsApiQueryModel) async
[(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).
Future<void> getRecommendations(RecommendationOptions recommendationOptions, {required void Function(RecommendationResponse recommendationResponse) onSuccess, required void Function(SyneriseError error) onError}) async
[(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).
Future<void> getRecommendationsV2(RecommendationOptions recommendationOptions, {required void Function(RecommendationResponse recommendationResponse) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> getScreenView({required void Function(ScreenViewResponse screenViewResponse) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> generateScreenView(String feedSlug, {required void Function(ScreenView screenView) onSuccess, required void Function(SyneriseError error) onError}) async
[(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.
Future<void> generateScreenViewWithApiQuery(ScreenViewApiQuery apiQuery, {required void Function(ScreenView screenView) onSuccess, required void Function(SyneriseError error) onError}) async
[(Click for more details)](/developers/mobile-sdk/method-reference/flutter/content#generate-screen-view-with-query-parameters) --- ### Client ## ClientIdentityProvider **Declared In:** lib/classes/models/Client/ClientIdentityProvider.js **Declaration:**
enum ClientIdentityProvider {
  Facebook = 'FACEBOOK',
  Google = 'GOOGLE',
  Oauth = 'OAUTH',
  Synerise = 'SYNERISE',
  Unknown = 'UNKNOWN',
}
**Functions:** Converts from `ClientIdentityProvider` to string.
function ClientIdentityProviderToString(clientIdentityProvider: ClientIdentityProvider): string
--- Converts from string to `ClientIdentityProvider`.
function ClientIdentityProviderFromString(string: string): ClientIdentityProvider
--- --- ## ClientAuthContext **Declared In:** lib/classes/models/Client/ClientAuthContext.js **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
interface IClientAuthContext {
  authID?: string;
  agreements?: IClientAgreements;
  attributes?: object;
}
class ClientAuthContext extends BaseModel
**Properties:** Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | yes | nil | Object that stores all agreements of a customer | | **attributes** | object | yes | [] | Additional custom attributes of a customer | | **authID** | string | yes | [] | Optional identifier of authorization |
**authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Initializers:**
constructor(modelObject?: IClientAuthContext)
--- --- ## ClientSimpleAuthenticationData **Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class ClientSimpleAuthenticationData extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | string | yes | Customer's email | | **phone** | string | yes | Customer's phone | | **customId** | string | yes | Customer's custom ID | | **uuid** | string | yes | Customer's UUID | | **firstName** | string | yes | Customer's first name | | **lastName** | string | yes | Customer's last name | | **displayName** | string | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) | yes | Customer's sex | | **company** | string | yes | Customer's company | | **address** | string | yes | Customer's address | | **city** | string | yes | Customer's city | | **province** | string | yes | Customer's province | | **zipCode** | string | yes | Customer's ZIP code | | **countryCode** | string | yes | Customer's country code | | **birthDate** | string | yes | Customer's birthdate | | **avatarUrl** | string | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | yes | Customer's agreements | | **attributes** | object | yes | Customer's attributes | --- --- ## ClientSessionEndReason **Declared In:** lib/classes/models/Client/ClientSessionEndReason.js **Declaration:**
enum ClientSessionEndReason {
  NotSpecified = 'NOT_SPECIFIED',
  SessionExpiration = 'SESSION_EXPIRATION',
  SecurityException = 'SECURITY_EXCEPTION',
  UserSignOut = 'USER_SIGN_OUT',
  SystemSignOut = 'SYSTEM_SIGN_OUT',
  SessionDestroyed = 'SESSION_DESTROYED',
  ClientRejected = 'CLIENT_REJECTED',
  UserAccountDeleted = 'USER_ACCOUNT_DELETED'
}
**Functions:** Converts from **ClientSessionEndReason** to **string**.
function ClientSessionEndReasonToString(reason: ClientSessionEndReason): string
--- Converts from **string** to **ClientSessionEndReason**.
function ClientSessionEndReasonFromString(string: string): ClientSessionEndReason
--- --- ## ClientSignOutMode **Declared In:** lib/classes/models/Client/ClientSignOutMode.js **Declaration:**
enum ClientSignOutMode {
  SignOut = 'SIGN_OUT',
  SignOutWithSessionDestroy = 'SIGN_OUT_WITH_SESSION_DESTROY'
}
**Functions:** Converts from **ClientSignOutMode** to **string**.
function ClientSignOutModeToString(mode: ClientSignOutMode): string
--- --- ## ClientAccountInformation Model representating the customer information.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/classes/models/Client/ClientAccountInformation.js **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class ClientAccountInformation extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **clientId** | number | no | Customer's ID | | **email** | string | no | Customer's email | | **phone** | string | yes | Customer's phone | | **customId** | string | yes | Customer's custom ID | | **uuid** | string | no | Customer's UUID | | **firstName** | string | yes | Customer's first name | | **lastName** | string | yes | Customer's last name | | **displayName** | string | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) | no | Customer's sex | | **company** | string | yes | Customer's company | | **address** | string | yes | Customer's address | | **city** | string | yes | Customer's city | | **province** | string | yes | Customer's province | | **zipCode** | string | yes | Customer's ZIP code | | **countryCode** | string | yes | Customer's country code | | **birthDate** | string | yes | Customer's birthdate | | **lastActivityDate** | Date | no | Customer's last activity date | | **avatarUrl** | string | yes | Customer's avatar URL | | **anonymous** | boolean | no | Customer's anonymous flag | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | no | Customer's agreements | | **attributes** | Array | yes | Customer's attributes | | **tags** | Array | yes | Customer's tags | --- --- ## ClientAccountUpdateBasicInformationContext **Declared In:** lib/classes/models/Client/ClientAccountUpdateBasicInformationContext.js **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class ClientAccountUpdateBasicInformationContext extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **firstName** | string | yes | Customer's first name | | **lastName** | string | yes | Customer's last name | | **displayName** | string | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) | yes | Customer's sex | | **phone** | string | yes | Customer's phone number | | **company** | string | yes | Customer's company | | **address** | string | yes | Customer's address | | **city** | string | yes | Customer's city | | **province** | string | yes | Customer's province | | **zipCode** | string | yes | Customer's ZIP code | | **countryCode** | string | yes | Customer's country code | | **birthDate** | string | yes | Customer's birthdate | | **avatarUrl** | string | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | no | Customer's agreements | | **attributes** | object | yes | Customer's attributes | **Initializers:**
constructor(modelObject?: IClientAccountUpdateBasicInformationContext)
--- --- ## ClientAccountUpdateContext **Declared In:** lib/classes/models/Client/ClientAccountUpdateContext.js **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class ClientAccountUpdateContext extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | string | yes | Customer's email | | **customId** | string | yes | Customer's custom ID | | **uuid** | string | yes | Customer's UUID | | **firstName** | string | yes | Customer's first name | | **lastName** | string | yes | Customer's last name | | **displayName** | string | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) | yes | Customer's sex | | **phone** | string | yes | Customer's phone number | | **company** | string | yes | Customer's company | | **address** | string | yes | Customer's address | | **city** | string | yes | Customer's city | | **province** | string | yes | Customer's province | | **zipCode** | string | yes | Customer's ZIP code | | **countryCode** | string | yes | Customer's country code | | **birthDate** | string | yes | Customer's birthdate | | **avatarUrl** | string | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | no | Customer's agreements | | **attributes** | object | yes | Customer's attributes | **Initializers:**
constructor(modelObject?: IClientAccountUpdateContext)
--- --- ## ClientAccountRegisterContext **Declared In:** lib/classes/models/Client/ClientAccountRegisterContext.js **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class ClientAccountRegisterContext extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | string | no | Customer's email | | **password** | string | no | Customer's password | | **firstName** | string | yes | Customer's first name | | **lastName** | string | yes | Customer's last name | | **customId** | string | yes | Customer's custom ID | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/react-native/client#clientsex) | yes | Customer's sex | | **phone** | string | yes | Customer's phone | | **company** | string | yes | Customer's company | | **address** | string | yes | Customer's address | | **city** | string | yes | Customer's city | | **province** | string | yes | Customer's province code | | **zipCode** | string | yes | Customer's ZIP code | | **countryCode** | string | yes | Customer's country code | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | yes | Customer's agreements | | **attributes** | object | yes | Customer's attributes | **Initializers:**
constructor(email: string, password: string, modelObject?: IClientAccountRegisterContext)
--- --- ## ClientSex **Declared In:** lib/classes/models/Client/ClientSex.js **Declaration:**
enum ClientSex {
  NotSpecified = 'NOT_SPECIFIED',
  Male = 'MALE',
  Female = 'FEMALE',
  Other = 'OTHER'
}
**Functions:** Converts from **ClientSex** to **string**.
function ClientSexToString(clientSex: ClientSex): string
--- Converts from **string** to **ClientSex**.
function ClientSexFromString(string: string): ClientSex
--- --- ## ClientAgreements **Declared In:** lib/classes/models/Client/ClientAgreements.js **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
interface IClientAgreements {
  email?: boolean;
  sms?: boolean;
  push?: boolean;
  bluetooth?: boolean;
  rfid?: boolean;
  wifi?: boolean;
}
class ClientAgreements extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | boolean | no | Email agreement | | **sms** | boolean | no | SMS agreement | | **push** | boolean | no | Push notifications agreement | | **bluetooth** | boolean | no | Bluetooth agreement | | **rfid** | boolean | no | RFID agreement | | **wifi** | boolean | no | WIFI agreement | **Initializers:**
constructor()
constructor(modelObject?: IClientAgreements)
--- --- ## Token **Declared In:** lib/classes/models/Token/Token.js **Related To:** [TokenOrigin](/developers/mobile-sdk/class-reference/react-native/client#tokenorigin) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class Token extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **tokenString** | string | no | Token as a raw string | | **tokenOrigin** | [TokenOrigin](/developers/mobile-sdk/class-reference/react-native/client#tokenorigin) | no | Token's origin | | **expirationDate** | string | yes | Token's expiration time | --- --- ## TokenOrigin **Declared In:** lib/classes/models/Token/TokenOrigin.js **Declaration:**
enum TokenOrigin {
  Unknown = 'UNKNOWN',
  Synerise = 'SYNERISE',
  Facebook = 'FACEBOOK',
  Oauth = 'OAUTH',
}
**Functions:** Converts from **TokenOrigin** to **string**.
function TokenOriginToString(tokenOrigin: TokenOrigin): string
--- Converts from **string** to **TokenOrigin**.
function TokenOriginFromString(string: string): TokenOrigin
--- --- ## Removed symbols --- ### ClientOAuthAuthenticationContext{#clientoauthauthenticationcontext} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** lib/classes/models/Client/ClientOAuthAuthenticationContext.js **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
interface IClientOAuthAuthenticationContext {
  authID?: string;
  agreements?: IClientAgreements;
  attributes?: object;
}
class ClientOAuthAuthenticationContext extends BaseModel
**Properties:** Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | yes | nil | Object that stores all agreements of a customer | | **attributes** | object | yes | [] | Additional custom attributes of a customer | **Initializers:**
constructor()
constructor(modelObject?: IClientOAuthAuthenticationContext)
--- --- ### ClientFacebookAuthenticationContext{#clientfacebookauthenticationcontext} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** lib/classes/models/Client/ClientOAuthAuthenticationContext.js **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
interface IClientOAuthAuthenticationContext {
  authID?: string;
  agreements?: IClientAgreements;
  attributes?: object;
}
class ClientOAuthAuthenticationContext extends BaseModel
**Properties:** Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | yes | nil | Object that stores all agreements of a customer | | **attributes** | object | yes | [] | Additional custom attributes of a customer | **Initializers:**
constructor()
constructor(modelObject?: IClientOAuthAuthenticationContext)
--- --- ### ClientAppleSignInAuthenticationContext{#clientapplesigninauthenticationcontext} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | n/a | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | n/a | 0.9.19 | n/a | | Removed in: | 5.0.0 | n/a | 1.0.0 | n/a | **Declared In:** lib/classes/models/Client/ClientAppleSignInAuthenticationContext.js **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
interface IClientAppleSignInAuthenticationContext {
  authID?: string;
  agreements?: IClientAgreements;
  attributes?: object;
}
class ClientAppleSignInAuthenticationContext extends BaseModel
**Properties:** Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/react-native/client#clientagreements) | yes | nil | Object that stores all agreements of a customer | | **attributes** | object | yes | [] | Additional custom attributes of a customer | **Initializers:**
constructor()
---
constructor(modelObject?: IClientAppleSignInAuthenticationContext)
### 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
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.
Expanded simple push notification
Simple push notification presented on Android 10
{
  "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",
    "category": "[YOUR CATEGORY]",
    "mutable-content": 1
  },
  "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_APP"
      }
    },
    "buttons": [{
      "identifier": "check",
      "text": "Check",
      "action": {
        "type": "OPEN_URL",
        "item": "http://www.synerise.com"
      }
    },
    {
      "identifier": "view_similiar",
      "text": "View similiar",
      "action": {
        "type": "OPEN_URL",
        "item": "http://www.synerise.com"
      }
    }]
  }
}
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
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}
{
  "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",
    "category": "synerise.notifications.category.single-media",
    "mutable-content": 1
  },
  "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_APP"
      }
    },
    "buttons": [{
      "identifier": "check",
      "text": "Check",
      "action": {
        "type": "OPEN_URL",
        "item": "http://www.synerise.com"
      }
    },
    {
      "identifier": "view_similiar",
      "text": "View similiar",
      "action": {
        "type": "OPEN_URL",
        "item": "http://www.synerise.com"
      }
    }],
    "rich-media": {
      "type": "single-image",
      "single-image": {
        "image": "https://upload.snrcdn.net/f2afa4d4d7af216196047d1f7f0613f22a50a8c8/default/origin/7eba69de2d4dab3a9388b9d72abd91eb.png"
      }
    }
  }
}
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
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
Simple Push campaign presented on iOS 14
### Authorization Synerise uses [JSON Web Token (JWT)](https://jwt.io/) as the authorization method in most of the API endpoints (some may require only the API key or no authorization at all). ### iOS # Installation and configuration (iOS) In this article, you will find out how to install and initialize the Synerise SDK in an iOS application. While performing the actions from this guide, keep the presented order.
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/business-profile) * 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. * One of the following dependency managers: - [CocoaPods](https://guides.cocoapods.org/using/getting-started.html) - CocoaPods is a dependency manager for iOS projects. - [Carthage](https://github.com/Carthage/Carthage) - Carthage is a simple, decentralized dependency manager for iOS projects. - [Swift Package Manager](https://www.swift.org/package-manager/) - Swift Package Manager (SPM) is a dependency manager built into Xcode. * Recommended environment: - Xcode 16 - iOS SDK 18 * Target deployment: - **iOS 13.0+** for SDK versions 5.0.0 and higher - **iOS 9.0+** for SDK versions lower than 5.0.0
Bitcode is not supported in SDK version 5.0.0 and higher. Xcode ignores bitcode.
### Apple Frameworks The Synerise SDK references the following Apple frameworks: - `Foundation.framework` - `UIKit.framework` - `CoreGraphics.framework` - `SystemConfiguration.framework` - `MobileCoreServices.framework` - `CoreTelephony.framework` - `Security.framework` - `CommonCrypto.framework` - `WebKit.framework` - `UserNotifications.framework` ### 3rd Party Frameworks - [AFNetworking (fork)](https://github.com/AFNetworking/AFNetworking) - [TrustKit](https://github.com/datatheorem/TrustKit) - [Aspects](https://github.com/steipete/Aspects) ## Installation --- ### CocoaPods 1. Add CocoaPods dependency to **Synerise SDK** into your `Podfile`:
use_frameworks!

       target YOUR_PROJECT_TARGET do
         pod 'SyneriseSDK'
       end
2. Execute the following shell command in the directory depending on your project configuration:
pod repo update  
       pod install
### Swift Package Manager (SPM) 1. Go to Xcode project’s settings and navigate to the Package Dependencies tab. 2. Below the packages list, click the Add button. 3. Enter the URL of Synerise SDK repository **(https://github.com/Synerise/synerise-ios-sdk)** in the search text field. 4. Under the Dependency Rule section, select the SDK version. Finally, click **Add Package**. 5. Select the package that best suits your needs and click **Add Package**. ### Carthage 1. Add the Carthage dependency to **Synerise SDK** into your `Cartfile`:
github "synerise/ios-sdk"
2. Execute the shell command in directory depending on your project configuration:
carthage update
3. Go to Xcode project target's **General** section. 4. In Finder, open `/Carthage/Build/iOS` 5. Drag `SyneriseSDK.framework` to **Embedded Binaries**. 6. Make sure the **Copy items if needed** option is selected. 7. Click **Finish**. ## Initialization --- ### Setting up 1. Go to Xcode project target's **General** section. 2. Find the **Other Linker Flags** property and add the ***-ObjC*** flag. 2. If you are going to use push notifications: 1. Go to `Info.plist` 2. Add a row for **Required background mode** with the following array type value: `App downloads content in response to push notifications` or add the code below directly:
<key>UIBackgroundModes</key>
           <array>
               <string>remote-notification</string>
           </array>
3. If you are going to use HTTP addresses (instead of only HTTPS), change the allowlist domains in your app by adding configuration to `Info.plist` in one of the following ways: - Add configured domain/domains that you need.
<key>NSAppTransportSecurity</key>
          <dict>
              <key>NSExceptionDomains</key>
              <dict>
                  <key>yourdomain.com</key>
                  <dict>
                  <!--Include to allow subdomains-->
                  <key>NSIncludesSubdomains</key>
                  <true/>
                  <!--Include to allow HTTP requests-->
                  <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                  <true/>
                  <!--Include to specify minimum TLS version-->
                  <key>NSTemporaryExceptionMinimumTLSVersion</key>
                  <string>TLSv1.1</string>
                  </dict>
              </dict>
          </dict>
- Give permission for all domains.
<key>NSAppTransportSecurity</key>
          <dict>
              <key>NSAllowsArbitraryLoads</key><true/>
          </dict>
### Importing Synerise SDK Import the **Synerise SDK** header into the files that contain code relating to SDK.
```Swift import SyneriseSDK ```
```Objective-C #import ```
In Objective-C, you can include it in your Prefix Header (PCH) and Synerise SDK will be imported to all files automatically.
### Basic initialization Initialize Synerise SDK and provide the [Profile API Key](/docs/settings/tool/api). You may initialize it wherever you want and when you need.
```Swift Synerise.initialize(apiKey: "YOUR_PROFILE_API_KEY") // 1 Synerise.setDebugModeEnabled(false) // 2 Synerise.setCrashHandlingEnabled(true) // 3 Synerise.setDelegate(self) // 4 ```
```Objective-C [SNRSynerise initializeWithApiKey:@"YOUR_PROFILE_API_KEY"]; // 1 [SNRSynerise setDebugModeEnabled:NO]; // 2 [SNRSynerise setCrashHandlingEnabled:YES]; // 3 [SNRSynerise setDelegate:self]; // 4 ```
Basic methods you need: 1. [`Synerise.initialize(apiKey:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#initialization) - Initializes Synerise SDK. 2. [`Synerise.setDebugModeEnabled(_:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#enable-debug-mode) - Enables debug mode for Synerise SDK. See [Debug mode](/developers/mobile-sdk/installation-and-configuration/ios#debug-mode) section for more information. 3. [`Synerise.setCrashHandlingEnabled(_:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#enable-crash-handling) - Enables crash handling. Synerise SDK sends a crash event automatically when an uncaught exception occurs. 4. [`Synerise.setDelegate(_:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#set-synerise-delegate)- Sets delegate to handle main actions from Synerise SDK. See [`SyneriseDelegate`](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate) section for more information. ### Initialization with custom API environment To change API base URL for on-premise installations, use the following initialization method:
```Swift Synerise.initialize(apiKey: "YOUR_PROFILE_API_KEY", baseUrl: "YOUR_API_BASE_URL") ```
```Objective-C [SNRSynerise initializeWithClientApiKey:@"YOUR_PROFILE_API_KEY" andBaseUrl:@"YOUR_API_BASE_URL"]; ```
### Advanced initialization This is an example of advanced initialization with: - custom API base URL for on-premise installations - request validation salt configured - debug mode enabled - crash handling enabled - most of the settings options available - main delegate [`SyneriseDelegate`](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate) - client's state delegate [`ClientStateDelegate`](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#client-state-delegate)
We highly recommend to configure settings when Synerise SDK is initialized, before invoking the [`Synerise.initialize(apiKey:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#initialization) method. See [Settings](/developers/mobile-sdk/settings) section for more details about settings options.
Secure sensitive keys (for example, `apiKey` and `requestValidationSalt`) with mechanisms like string obfuscation or encryption.
You can find more information about all [Synerise iOS SDK delegates here](/developers/mobile-sdk/listeners-and-delegates/ios-delegates).
```Swift Synerise.settings.sdk.enabled = true Synerise.settings.sdk.appGroupIdentifier = "YOUR_APP_GROUP_IDENTIFIER" Synerise.settings.sdk.keychainGroupIdentifier = "YOUR_KEYCHAIN_GROUP_IDENTIFIER" Synerise.settings.sdk.minTokenRefreshInterval = 1800 Synerise.settings.sdk.shouldDestroySessionOnApiKeyChange = false Synerise.settings.notifications.enabled = true Synerise.settings.notifications.disableInAppAlerts = true Synerise.settings.notifications.encryption = false Synerise.settings.tracker.autotracking.enabled = true Synerise.settings.tracker.autotracking.mode = AutoTrackMode.Fine Synerise.settings.tracker.autotracking.excludedClasses = [SampleViewController.self] Synerise.settings.tracker.autotracking.excludedViewTags = [0, 1, 2] Synerise.settings.tracker.tracking.enabled = true Synerise.settings.tracker.minBatchSize = 10 Synerise.settings.tracker.maxBatchSize = 100 Synerise.settings.tracker.autoFlushTimeout = 5.0 Synerise.settings.tracker.autoTracking.mode = .fine Synerise.settings.tracker.locationAutomatic = true Synerise.settings.injector.automatic = true Synerise.initialize(apiKey: "YOUR_PROFILE_API_KEY", baseUrl: "YOUR_API_BASE_URL") Synerise.setRequestValidationSalt("YOUR_REQUEST_VALIDATION_SALT") Synerise.setDebugModeEnabled(false) Synerise.setCrashHandlingEnabled(true) Synerise.setDelegate(self) Client.setClientStateDelegate(self) ```
```Objective-C SNRSynerise.settings.sdk.enabled = @YES; SNRSynerise.settings.sdk.appGroupIdentifier = @"YOUR_APP_GROUP_IDENTIFIER"; SNRSynerise.settings.sdk.keychainGroupIdentifier = @"YOUR_KEYCHAIN_GROUP_IDENTIFIER"; SNRSynerise.settings.sdk.minTokenRefreshInterval = 1800; SNRSynerise.settings.sdk.shouldDestroySessionOnApiKeyChange = NO; SNRSynerise.settings.notifications.enabled = YES; SNRSynerise.settings.notifications.disableInAppAlerts = YES; SNRSynerise.settings.notifications.encryption = NO; SNRSynerise.settings.tracker.autotracking.enabled = YES; SNRSynerise.settings.tracker.autotracking.mode = SNRTrackerAutoTrackModeFine; SNRSynerise.settings.tracker.autotracking.excludedClasses = [SampleViewController.class]; SNRSynerise.settings.tracker.autotracking.excludedViewTags = [@0, @2, @3]; SNRSynerise.settings.tracker.tracking.enabled = YES; SNRSynerise.settings.tracker.minBatchSize = 10; SNRSynerise.settings.tracker.maxBatchSize = 100; SNRSynerise.settings.tracker.autoFlushTimeout = 5.0; SNRSynerise.settings.tracker.autoTracking.mode = SNRTrackerAutoTrackModeFine; SNRSynerise.settings.tracker.locationAutomatic = YES; SNRSynerise.settings.injector.automatic = YES; [SNRSynerise initializeWithApiKey:@"YOUR_PROFILE_API_KEY" andBaseUrl:@"YOUR_API_BASE_URL"]; [SNRSynerise setRequestValidationSalt:@"YOUR_REQUEST_VALIDATION_SALT"]; [SNRSynerise setDebugModeEnabled:NO]; [SNRSynerise setCrashHandlingEnabled:YES]; [SNRSynerise setDelegate:self]; [SNRClient setClientStateDelegate:self]; ```
### Initialization process During initialization, the library starts and when it is ready or an error occurs, the SDK notifies you. When the delegate method is called, Synerise is ready to use.
```Swift // MARK: - SyneriseDelegate // This method is called when the Synerise SDK is initialized. func snr_initialized() { //... } // This method is called when an error occurs while initializing the Synerise SDK. func snr_initializationError(error: Error) { //... } ```
```Objective-C #pragma mark - SNRSyneriseDelegate // This method is called when the Synerise SDK is initialized. - (void)SNR_initialized { //... } // This method is called when an error occurs while initializing the Synerise SDK. - (void)SNR_initializationError:(NSError *)error { //... } ```
## Debug Mode --- You can enable debug logs for Synerise SDK by method [`Synerise.setDebugModeEnabled(_:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#enable-debug-mode).
Do not use Debug Mode in a release version of your application.
```Swift Synerise.setDebugModeEnabled(true) // Enables logging for all modules ```
```Objective-C [SNRSynerise setDebugModeEnabled:YES]; // Enables logging for all modules ```
You can receive some logs about: - **Core**: push notifications - **Tracker**: auto-tracked events, declarative events, sending process - **Client**: customer state, authorization - **Injector**: campaigns, UI - **Promotions**: promotions, vouchers - **Content**: content widget, documents, recommendations ## Background Tasks --- [Background Tasks](https://developer.apple.com/documentation/backgroundtasks) is a mechanism to schedule and run code in the background to keep your app up to date. Synerise supports using Background Tasks since SDK version **4.23.0**. You can pass configured identifiers for Synerise SDK by using the [`Synerise.setBackgroundTaskIdentifiers(_:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#set-background-task-identifiers) method. The identifiers that you are going to pass have to be configured properly in the host app. #### 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 [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. #### Setting up To configure Background Tasks in your app: 1. Go to Xcode project's target's **Signing & Capabilities** section. 2. In the **Background Modes** capability (you may need to add it), enable **Background fetch** and **Background processing**. 3. Go to `Info.plist`. 4. Add a row with the following array type value: `Permitted background task scheduler identifiers`. 5. Add string identifiers, each as a separate item to declare possible Background Tasks identifiers in your app. 6. Pass these Background Tasks identifiers to SDK by using the [`Synerise.setBackgroundTaskIdentifiers(_:)`](/developers/mobile-sdk/method-reference/ios/lifecycle#set-background-task-identifiers) method. You must invoke the method **BEFORE** your app is launched (before the `application(_ application:didFinishLaunchingWithOptions launchOptions:)` method finishes). Sample `\*.plist` configuration for Background Tasks:
Sample *.plist configuration for Background Tasks
Sample *.plist configuration for Background Tasks
Example code for passing Background Tasks identifiers to the SDK:
```Swift func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // ... Synerise.setBackgroundTaskIdentifiers(["YOUR_BACKGROUND_TASK_IDENTIFIER"]) return true } ```
```Objective-C - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // ... [SNRSynerise setBackgroundTaskIdentifiers:@[@"YOUR_BACKGROUND_TASK_IDENTIFIER"]]; return YES; } ```
The method's parameter is an array because of possible future purposes.
Do not use those identifiers for other Background Tasks in your app.
Documentation is available at [Apple Developer - Using background tasks to update your app](https://developer.apple.com/documentation/uikit/app_and_environment/scenes/preparing_your_ui_to_run_in_the_background/using_background_tasks_to_update_your_app). **IMPORTANT: To configure Background Tasks properly, you must set `SyneriseDelegate` before the SDK initialization.**
```Swift Synerise.setDelegate(self) Synerise.initialize(apiKey: "YOUR_PROFILE_API_KEY") // ... ```
```Objective-C [SNRSynerise setDelegate:self]; [SNRSynerise initializeWithApiKey:@"YOUR_PROFILE_API_KEY"]; // ... ```
## Privacy manifest --- From **1 May 2024**, Apple requires you to add a privacy manifest. It's a file in your project that describes your reason and method for collecting data. Third-party frameworks that track data should have a privacy manifest. When you create the application privacy report, these privacy manifest files are automatically aggregated into a single file. Synerise supports privacy manifests since SDK version **4.17.0**. When you use an SDK version older than **4.17.0**, refer to the Synerise API usage requirements defined below when creating an Apple privacy manifest. #### APIs usage | API | Reason | Description | | --- | --- | --- | | User defaults APIs | **CA92.1**
**1C8F.1** | Synerise uses User Defaults to persist the SDK data and share them between the application and extensions | #### Tracking Synerise does not track any data that is protected by the [App Tracking Transparency](https://developer.apple.com/documentation/apptrackingtransparency) framework. #### Collected Data | Data type | Value | Purpose | | --- | --- | --- | | User ID | **NSPrivacyCollectedDataTypeUserID** | Analytics, Product Personalization | | Other usage data | **NSPrivacyCollectedDataTypeOtherUsageData** | Analytics, Product Personalization, App Functionality | | Product interaction | **NSPrivacyCollectedDataTypeProductInteraction** | Analytics | | Advertising data | **NSPrivacyCollectedDataTypeAdvertisingData** | Other Purposes, App Functionality | | Crash data | **NSPrivacyCollectedDataTypeOtherUserContent** | Analytics | ## Warnings and limitations --- Be careful with keychain deletion operations due to the possibility of deleting Synerise data. All the SDK library data keys are named `snr.[KEY_NAME]`. ### 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:
```Swift Synerise.settings.sdk.keychainGroupIdentifier = "YOUR_KEYCHAIN_GROUP_IDENTIFIER" Synerise.settings.notifications.encryption = true ```
```Objective-C SNRSynerise.settings.sdk.keychainGroupIdentifier = @"YOUR_KEYCHAIN_GROUP_IDENTIFIER"; SNRSynerise.settings.notifications.encryption = YES; ```
**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.
### Implementation {id=synerise-notification-service-extension-implementation}
```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.
```Swift override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) //... NotificationServiceExtension.setDebugModeEnabled(true) //... } ```
```Objective-C - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; //... [SNRNotificationServiceExtension setDebugModeEnabled:YES]; //... } ```
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) } } } ```
```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]; NSDictionary *userInfo = notification.request.content.userInfo; BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo]; if (isSyneriseNotification == YES) { //... } else { BOOL isNotificationEncrypted = [SNRSynerise isNotificationEncrypted:userInfo]; if (isNotificationEncrypted == YES) { NSDictionary *userInfoDecrypted = [SNRSynerise decryptNotification:userInfo]; if (userInfoDecrypted != nil) { 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" } } } self.contentHandler(self.bestAttemptContent); } @end ```
### '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)).
`Content-Available` option in 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
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)).
`Mutable-Content` option in 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
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]) ```
```Objective-C SNRSynerise.settings.notifications.appGroupIdentifier = @"YOUR_APP_GROUP_IDENTIFIER"; SNRSynerise.settings.sdk.keychainGroupIdentifier = @"YOUR_KEYCHAIN_GROUP_IDENTIFIER"; UNNotificationCategory *singleMediaCategory = [UNNotificationCategory categoryWithIdentifier:SNRSingleMediaContentExtensionViewControllerCategoryIdentifier actions:@[] intentIdentifiers:@[] options:0]; UNNotificationAction *carouselPreviousAction = [UNNotificationAction actionWithIdentifier:SNRCarouselContentExtensionViewControllerPreviousItemIdentifier title:@"Previous" options:0]; UNNotificationAction *carouselGoAction = [UNNotificationAction actionWithIdentifier:SNRCarouselContentExtensionViewControllerChooseItemIdentifier title:@"Go" options:0]; UNNotificationAction *carouselNextAction = [UNNotificationAction actionWithIdentifier:SNRCarouselContentExtensionViewControllerNextItemIdentifier title:@"Next" options:0]; UNNotificationCategory *carouselCategory = [UNNotificationCategory categoryWithIdentifier:SNRCarouselContentExtensionViewControllerCategoryIdentifier actions:@[carouselPreviousAction, carouselGoAction, carouselNextAction] intentIdentifiers:@[] options:0]; [[UNUserNotificationCenter currentNotificationCenter] setNotificationCategories:[NSSet setWithObjects:singleMediaCategory, carouselCategory, nil]]; ```
| 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}
```Swift import UIKit import UserNotifications import UserNotificationsUI import SyneriseSDK class NotificationViewController: SingleMediaContentExtensionViewController, UNNotificationContentExtension { func didReceive(_ notification: UNNotification) { Synerise.settings.sdk.appGroupIdentifier = "YOUR_APP_GROUP_IDENTIFIER" Synerise.settings.sdk.keychainGroupIdentifier = "YOUR_KEYCHAIN_GROUP_IDENTIFIER" self.contentViewIsScrollable = false self.imageContentMode = .scaleAspectFit setSyneriseNotification(notification) } func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) { setSyneriseNotificationResponse(response, completionHandler: completion) } } ```
```Objective-C #import #import #import #import @interface SingleMediaNotificationViewController : SNRSingleMediaContentExtensionViewController @end #import "SingleMediaNotificationViewController.h" @implementation SingleMediaNotificationViewController - (void)didReceiveNotification:(UNNotification *)notification { SNRSynerise.settings.notifications.appGroupIdentifier = @"YOUR_APP_GROUP_IDENTIFIER"; SNRSynerise.settings.sdk.keychainGroupIdentifier = @"YOUR_KEYCHAIN_GROUP_IDENTIFIER"; self.contentViewIsScrollable = NO; self.imageContentMode = UIViewContentModeScaleAspectFit; [self setSyneriseNotification:notification]; } - (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption))completion { [self setSyneriseNotificationResponse:response completionHandler:completion]; } @end ```
#### 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
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}
```Swift import UIKit import UserNotifications import UserNotificationsUI import SyneriseSDK class NotificationViewController: CarouselContentExtensionViewController, UNNotificationContentExtension { func didReceive(_ notification: UNNotification) { Synerise.settings.sdk.appGroupIdentifier = "YOUR_APP_GROUP_IDENTIFIER" Synerise.settings.sdk.keychainGroupIdentifier = "YOUR_KEYCHAIN_GROUP_IDENTIFIER" self.imageContentMode = .scaleAspectFit setSyneriseNotification(notification) } func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) { setSyneriseNotificationResponse(response, completionHandler: completion) } } ```
```Objective-C #import #import #import #import @interface CarouselNotificationViewController : SNRCarouselContentExtensionViewController @end #import "CarouselNotificationViewController.h" @implementation CarouselNotificationViewController - (void)didReceiveNotification:(UNNotification *)notification { SNRSynerise.settings.notifications.appGroupIdentifier = @"YOUR_APP_GROUP_IDENTIFIER"; SNRSynerise.settings.sdk.keychainGroupIdentifier = @"YOUR_KEYCHAIN_GROUP_IDENTIFIER"; [self setSyneriseNotification:notification]; } - (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption))completion { [self setSyneriseNotificationResponse:response completionHandler:completion]; } @end ```
#### 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
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) ### Installation and configuration In this section, you will find out how to install, configure, and initialize SDK in the Android, iOS and React Native mobile applications. ## Contents ### Sending events Synerise uses two APIs to send events, depending on the event type: - the [`v4/events` API](https://developers.synerise.com/DataManagement/DataManagement.html#tag/Events) is used to send most events, including custom ones. This API offers multiple endpoints specific to a particular event type. In this article, we will take a closer look at using the "Send Custom Event" endpoint and at the "Batch send events" endpoint. - the `v4/transactions` API (for [single transactions](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) and [batches](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions)) is used to record `transaction.charge` events and automatically creates `product.buy` events for each transaction. ## "Send Custom Event" endpoint
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
API reference available [here](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CustomEvent). This endpoint can be used to send custom events required by your integration. When you use this endpoint to send an event whose [definition](/docs/assets/events/event-definitions) doesn't exist in the system, a definition is created automatically. The request body must contain the following properties: - `action` is the type of event, for example `page.visit` (default event), `dog.bark` (custom event). When you use a dedicated endpoint for an event type, this parameter is not used. - `client` is an object with profile identifiers. It must contain at least one of the following identifiers: - `id` - `customId` - `uuid` - `email` - `label` must be a non-empty string. It is a legacy property, currently not used by Synerise and not saved in persistent storage. The following properties are optional: - `params` is an object with additional event parameters that you want to add to the request. Some names are reserved for system use (see API reference for details). - `time` is the time when the event occurred (for example, the time when a customer clicked a button), formatted according to [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). **Example**: If your timezone is UTC-4 and your local time is 09:00:00, May 23, 2022: - You can send the time as UTC: `2022-05-23T13:00:00Z` - You can send the same time with your timezone: `2022-05-23T09:00:00-04:00` - You can send the same time with a different timezone, if necessary: `2022-05-23T07:00:00-06:00` All the above examples indicate the same date and time, written in different ways. You can include milliseconds, for example `2022-05-23T13:00:00.176Z` The time sent in this parameter is not affected by the time zone of your workspace. You can use any timezone or the UTC standard. When you retrieve an event later, the time is always returned as UTC.
- If no time is provided, the time when the event was received by Synerise is saved as the occurrence time. - **If the provided time is in the future, it is rejected** and the time when the event was received by Synerise is saved as the occurrence time. In the above example, future times would be: - later than `2022-05-23T13:00:00Z` - later than `2022-05-23T09:00:00-04:00` - later than `2022-05-23T07:00:00-06:00`
- `eventSalt` is a special parameter. Its usage is described in [Overwriting events](/developers/api/events/overwriting-events). The request can be authorized with a JWT of a profile (formerly called a client) or a workspace (formerly called a business profile). #### Example The following cURL request is an example of a custom `dog.bark` event with a few custom properties: `loudness`, `mood`, and `mailmanScared`:
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/custom' \
--header 'Authorization: Bearer ey...RtH_g' \
--header 'Api-Version: 4.4' \
--header 'Content-Type: application/json' \
--data-raw '{
    "action": "dog.bark",
    "client": {
        "id": 5092159999
    },
    "time": "2022-11-28T12:18:27Z",
    "params": {
        "loudness": 3,
        "mood": "happy",
        "mailmanScared": true
    },
    "label": "bark"
}'
### Sending a batch of events You can also send a number of events at once. A batch can include different event types saved to different profiles. The request body is an array of events similar to when sending a single events, with the following modification: - if the event is custom, add the `"type": "custom"` parameter - if the event has a dedicated endpoint: - add the `type` parameter with the value that corresponds to the name of the dedicated endpoint. For example, if the endpoint of the event is `/v4/events/shared`, the type is `shared`. - remove the `action` parameter. #### Example The following cURL request is a batch of two events: - the same `dog.bark` event from the [previous example](#send-custom-event-endpoint) - a `client.hitTimer` event (the dedicated endpoint is `/v4/events/hit-timer`), sent to a different profile
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/batch' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Api-Version: 4.4' \
  --header 'Authorization: Bearer ey...RtH_g' \
  --data-raw '[
      {
          "action": "dog.bark",
          "type": "custom",
          "client": {
              "id": 5092159999
          },
          "time": "2022-11-28T12:18:27Z",
          "params": {
              "loudness": 3,
              "mood": "happy",
              "mailmanScared": true
          },
          "label": "bark"
      },
      {
          "type": "hit-timer",
          "time": "2022-11-26T13:13:48Z",
          "client": {
              "id": 267498412
          },
          "label": "string"
      }
  ]'
### Sending form data with JS SDK ## Introduction If you have embedded the Synerise [tracking code](/developers/web/installation-and-configuration) in your website, you will see anonymous customers in the Synerise Dashboard. In this section, you will learn how to track forms on your website. Capturing forms is crucial, as the data used there automatically updates an anonymous customer's information and turns them into a known contact. The data is saved in a [form.submit event](/docs/assets/events/event-reference/web-and-app#formsubmit). The event contains all data from the form.
By default, tracking a form requires authentication and cannot be used by anonymous customers. To change this, modify the event authentication settings: 1. Add `form.submit` to the [list of events which do not require JWT authentication](/docs/assets/events/event-settings#events-which-change-customer-data-and-dont-require-authentication). 2. Remove `form.submit` from the [list of events which require JWT authentication](/docs/assets/events/event-settings#events-which-change-customers-data-and-require-authentication).
You probably have several types of forms on your page, such as a login, contact, or registration form, or one for leaving comments. This provides a variety of data, from a customer's first name to their comment about a product or your business. Synerise needs to know what type of data is sent in each input, so it can update the customer's personal data properly. ## Managing user context Sending form data allows you to manage user context (UUID) in the browser. You can choose which identifying attribute (`email` or `custom_identfy`) to use for managing user context. The available identifiers differ depending on the selected configuration for email address uniqueness (see [Identifiers](/docs/settings/configuration/non-unique-emails)). If you use: - unique emails - then you can [define the identifier for managing user context](/docs/settings/configuration/non-unique-emails#managing-user-context). Once selected, you must consistently use it when sending form data.
If you send an identifying attribute that isn’t set as the context manager, it will be treated like a custom attribute and added or overwritten. For example, if `custom_identify` is set as the user context identifier and you send a different email address, the email will update but the user context remains unchanged.
- non-unique emails - then `custom_identify` is the only available identifying attribute.
You can decide how the user context is handled [when a link contains user-identifying parameters (snrs_cl and snrs_he)](/developers/web/user-identification#recognizing-customers-from-link-parameters).
### Context managing behavior - **For an anonymous user** - sending form data with an identifying attribute will recognize the user without changing their UUID. If a profile with that identifier already exists, the UUID will be [merged into the existing profile](/docs/crm/profile-merge). - **For a recognized user** (different from the one provided in the form data): the user’s UUID is reset, and the browser context is updated to match the data sent in the form. If a profile with the given identifier already exists, the UUID will be [merged into that profile](/docs/crm/profile-merge). ## Sending data to Synerise with HTML form attributes To send data from a form to Synerise, the form's fields must have the `data-synerise` attributes added to them.
The SDK does not validate the data. For example, if the customer makes an error in their identifier and sends the form, a new profile with that identifier is created. This may cause the event history of an anonymous customer to be merged into a recognized profile with an error in the identifier, even if the user re-sends the form again with the right identifier. To avoid this, validate the entered data before sending the form.
**Example:**
<form action="" method="post" data-synerise="contact">
    <input type="text" name="email" data-synerise="email" placeholder="Email" value="john.doe@synerise.com" />
    <input type="text" name="name" data-synerise="firstname" placeholder="Name" value="John" />
    <input type="text" name="surname" data-synerise="lastname" placeholder="Surname" value="Doe" />
    <input type="text" name="customParam2" data-synerise="customAttribute1" value="customValue2" />
    <input type="hidden" name="customParam2" data-synerise="customAttribute2" value="customValue2" />
    <input type="submit" value="Save" />
</form>
In the `form` tag, in the `data-synerise` attribute, you can send several values, separated by commas (`data-synerise="value1,value2,value3"`). The values will be saved in the event data as `formType` and as tags in the customer's card in **Behavioral Data Hub > Profiles**. You can add additional attributes (see `customAttribute` in the example). They are saved to the `attributes` object in a customer's profile. When the form above is sent, the following call to the SDK is made **automatically**:
SR.event.sendFormData('contact',
    { //form data
        "surname": "Doe",
        "name": "John",
        "email": "john.doe@synerise.com",
        "customParam1": "customValue1",
        "customParam2": "customValue2"
    },
    { //field mapping
        "lastname": "surname",
        "firstname": "name",
        "email": "email",
        "customAttribute1": "customParam1",
        "customAttribute2": "customParam2"
    }
)
**Explanation**: + Form data: _object_, HTML form field values. These are the collected values that are sent to Synerise and potentially stored as customer information in the customer card in **Behavioral Data Hub > Profiles**, depending on the mapping. + Field mapping: _object_. This object provides the mapping between the `name` attributes of your HTML form fields and the predefined fields of the customer object in the Synerise system. ### Delayed data forms If an HTML form with `data-synerise` attributes appears after the tracking code has been initialized (for example, in a pop-up window), you have to explicitly initialize another search for the attributes on the page, using the following SDK method:
SyneriseTC.initFormCatch()
## Calling the SDK directly If you use the SDK method directly, you do not need to include the mapping object. You can refer to the fields directly by their Synerise names:
- If you use the non-unique email feature, use `custom_identify` instead of `email`. See [non-unique email feature configuration](/docs/settings/configuration/non-unique-emails). - The SDK does not validate the data. For example, if the customer makes an error in their identifier and sends the form, a new profile with that identifier is created. This may cause the event history of an anonymous customer to be merged into a recognized profile with an error in the identifier, even if the user re-sends the form again with the right identifier. To avoid this, validate the entered data before sending the form.
SR.event.sendFormData('formType', {
    lastname: "Doe",
    firstname: "John",
    email: "john.doe@synerise.com",
    customAttribute: "customAttributeValue" // saved in the `attributes` object of a Profile
    // more attributes and custom attributes
})
You can replace `formType` with another value or a number of comma-separated values (no spaces). These values are saved as `formType` in the event and as tags in the customer's Profile. ### Sending multiple events When calling the SDK directly, you may want to send more events with the `form.submit` event. To ensure that those additional events are saved after `form.submit` identifies the profile, use the `then` function. For example, if you want to add a `review.send` event to the `form.submit` event:
SR.event.sendFormData('formType', {
    lastname: "Doe",
    firstname: "John",
    email: "john.doe@synerise.com",
}).then(function () {
    SR.event.trackCustomEvent("review.send",
        {
            "stars": 5
        });
});
## Marketing agreements See [Newsletter agreements](/developers/web/newsletter-agreements). ## Recognizing already logged users You can automatically recognize users who have logged in previously and their session is still active. ### Requirements ID of a currently logged-in user: - if you use unique emails: `email` or `custom_identify` - if you use [non-unique emails](/docs/settings/configuration/non-unique-emails): `custom_identify` ### Methods Execute the following methods in a given order: 1. [Get IdentityHash](/developers/web/methods-reference#get-identityhash) - This method generates and saves automatically `IdentityHash` based on: - ` email ` or `custom_identify` (for unique emails), - ` custom_identify ` (for non-unique emails). 2. [Calculate IdentityHash](/developers/web/methods-reference#calculate-identityhash) - This method calculates `IdentityHash` for any string. 3. [Send form data](/developers/web/methods-reference#send-form-data) - This method recognizes a user. ### Responses
SR.client.getIdentityHash(): String //if there is no identity hash, an empty string is returned
SR.client.hashIdentity(email): Number
### Example implementation The following code snippet compares the data about the currently tracked user with an email of a logged user. It checks whether the user is unidentified in Synerise or if the logged account is different from the one associated with the provided email. If either condition is met, the code proceeds to send form data for a login event, including the captured email, along with any additional parameters as key-value pairs.
//capture logged user email
const email="john.doe@synerise.com"

//user logged but unidentified in Synerise or logged identified as different account
if(email && (SR.client.getIdentityHash()==='' || SR.client.getIdentityHash()!==SR.client.hashIdentity(email))){
    SR.event.sendFormData('login', {
        email: email
        //additional parameters as key-value pairs
    })
}
### Client ### ClientIdentityProvider This enum contains values which set the provider for deleting a profile (a profile itself and their account). **Declared In:** `com.synerise.sdk.client.model.ClientIdentityProvider` **Declaration:**
```Java public enum ClientIdentityProvider ```
```Kotlin public enum ClientIdentityProvider ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **FACEBOOK** | "FACEBOOK" | Facebook provider | | **GOOGLE** | "GOOGLE" | Google provider | | **OAUTH** | "OAUTH" | Oauth provider | | **SYNERISE** | "SYNERISE" | Synerise provider | | **SIMPLE_AUTH** | "SIMPLE_AUTH" | Simple Profile Authentication provider | **Methods:** Get a provider.
public static ClientIdentityProvider getByProvider(String provider)
--- --- --- ### AuthConditions Auth conditions model. Model passes status and conditions. **Declared In:** `com.synerise.sdk.client.model` **Declaration:**
```Java public class AuthConditions ```
```Kotlin class AuthConditions ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **status** | [ConditionalAuthenticationStatus](/developers/mobile-sdk/class-reference/android/client#conditionalauthenticationstatus) | no | - | Status of authentication | | **conditions** | ArrayList | no | - | List of conditions |
All of the properties above are accessible by using getters.
**Methods:** There are getters and setters for the above properties. --- --- --- ### ConditionalAuthenticationStatus This enum contains values which describe the status of an after a log-in attempt. **Declared In:** `com.synerise.sdk.client.model.ConditionalAuthenticationStatus` **Declaration:**
```Java public enum ConditionalAuthenticationStatus ```
```Kotlin public enum ConditionalAuthenticationStatus ```
**Values:** | Property | Description | | --- | -- | | **SUCCESS** | Authentication successful | | **UNAUTHORIZED** | Currently unused | | **ACTIVATION_REQUIRED** |Currently unused | | **REGISTRATION_REQUIRED** | Currently unused | | **APPROVAL_REQUIRED** | Currently unused | | **TERMS_ACCEPTANCE_REQUIRED** | Currently unused | | **MFA_REQUIRED** | Currently unused | **Methods:** There are no methods. --- --- ### ClientData **Declared In:** `com.synerise.sdk.client.model.simpleAuth` **Declaration:**
```Java public final class ClientData extends ClientDataInformation ```
```Kotlin class ClientData : ClientDataInformation ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's email | | **phone** | String | yes | - | Customer's phone | | **customId** | String | yes | - | Customer's custom ID | | **uuid** | String | yes | - | Customer's uuid | | **firstName** | String | yes | - | Customer's first name | | **lastName** | String | yes | - | Customer's last name | | **displayName** | String | yes | - | Customer's display name | | **company** | String | yes | - | Customer's company | | **address** | String | yes | - | Customer's address | | **city** | String | yes | - | Customer's city | | **province** | String | yes | - | Customer's province | | **zipCode** | String | yes | - | Customer's ZIP code | | **countryCode** | String | yes | - | Customer's country code | | **birthDate** | String | yes | - | Customer's birthdate | | **sex** | [Sex](/developers/mobile-sdk/class-reference/android/client#sex) | yes | - | Customer's sex | | **avatarUrl** | String | yes | - | Customer's avatar URL | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | yes | - | Customer's agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | yes | - | Customer's attributes |
All properties above are accessible by using setters.
**Initializers:** There are no initializers. **Methods:** There are only setters for above properties. --- --- ### ClientSessionEndReason This enum contains values which describe the reason for sending a session. **Declared In:** `com.synerise.sdk.core.types.enums.ClientSessionEndReason` **Declaration:**
```Java public enum ClientSessionEndReason ```
```Kotlin public enum ClientSessionEndReason ```
**Values:** | Property | Description | | --- | --- | | **SESSION_EXPIRATION** | Session ended due to token expiration. | | **SECURITY_EXCEPTION** | Session ended due to security errors. | | **USER_SIGN_OUT** | Session ended due to a profile sign-out. | | **SYSTEM_SIGN_OUT** | Session ended due to a remote sign out by the system. | | **SESSION_DESTROYED** | Session ended due to the `Client.destroySession` method. | | **CLIENT_REJECTED** | Session ended due to 401 or 410 response. | | **USER_ACCOUNT_DELETED** | Session ended due to profile account deletion. | **Methods:** There are no methods. --- --- ### ClientSignOutMode This enum contains values for the sign out mode. **Declared In:** `com.synerise.sdk.core.types.enums` **Declaration:**
```Java public enum ClientSignOutMode ```
```Kotlin public enum ClientSignOutMode ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **SIGN_OUT** | "LOGOUT" | Sign out with a backend call. The token is invalidated and cleared in the SDK, but the UUID remains the same. | | **SIGN_OUT_WITH_SESSION_DESTROY** | "LOGOUT_WITH_SESSION_DESTROY" | Sign out with a backend call. The token is invalidated. The token and UUID are cleared in the SDK. | **Methods:** No methods. --- --- --- ### GetAccountInformation Class providing a profile account information. **Declared In:** `com.synerise.sdk.client.model.GetAccountInformation` **Declaration:**
```Java public final class GetAccountInformation extends AccountInformation implements Serializable ```
```Kotlin class GetAccountInformation:AccountInformation(), Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **clientId** | long | no | - | A unique ID of a profile | | **lastActivityDate** | Date | no | - | Profile's last performed activity date | | **email** | String | no | - | Profile's email | | **phone** | String | no | - | Profile's phone | | **customId** | String | no | - | Profile's customId | | **uuid** | String | no | - | Profile's UUID | | **firstName** | String | no | - | Profile's first name | | **lastName** | String | no | - | Profile's last name | | **displayName** | String | no | - | Profile's display name | | **company** | String | no | - | Profile's company | | **address** | String | no | - | Profile's address | | **city** | String | no | - | Profile's city | | **province** | String | no | - | Profile's province | | **zipCode** | String | no | - | Profile's ZIP code | | **countryCode** | String | no | - | Profile's country code | | **birthDate** | String | no | - | Profile's birth date | | **sex** | [Sex](/developers/mobile-sdk/class-reference/android/client#sex) | no | - | Profile's sex | | **avatarUrl** | String | no | - | Profile's avatar URL | | **anonymous** | Boolean | no | - | Defines if the profile is anonymous | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | no | - | Profile's agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | - | Profile's attributes | | **tags** | List | no | - | Profile's tags |
All properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. --- --- --- ### UpdateAccountBasicInformation Class providing data to update account basic information. **Declared In:** `com.synerise.sdk.client.model.UpdateAccountBasicInformation` **Declaration:**
```Java public final class UpdateAccountBasicInformation ```
```Kotlin class UpdateAccountBasicInformation ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **phoneNumber** | String | no | - | Profile's phone | | **firstName** | String | no | - | Profile's first name | | **lastName** | String | no | - | Profile's last name | | **displayName** | String | no | - | Profile's display name | | **company** | String | no | - | Profile's company | | **address** | String | no | - | Profile's address | | **city** | String | no | - | Profile's city | | **province** | String | no | - | Profile's province | | **zipCode** | String | no | - | Profile's ZIP code | | **countryCode** | String | no | - | Profile's country code | | **birthDate** | String | no | - | Profile's birth date | | **sex** | [Sex](/developers/mobile-sdk/class-reference/android/client#sex) | no | - | Profile's sex | | **avatarUrl** | String | no | - | Profile's avatar URL | | **anonymous** | Boolean | no | - | Defines if the profile is anonymous | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | no | - | Profile's agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | - | Profile's attributes |
All properties above are accessible by using setters.
**Initializers:** There are no initializers. **Methods:** There are only setters for above properties. --- --- --- ### UpdateAccountInformation Class providing data to update account information. **Declared In:** `com.synerise.sdk.client.model.UpdateAccountInformation` **Declaration:**
```Java public final class UpdateAccountInformation extends AccountInformation ```
```Kotlin class UpdateAccountInformation:AccountInformation() ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | no | - | Profile's email | | **phoneNumber** | String | no | - | Profile's phone | | **customId** | String | no | - | Profile's customId | | **uuid** | String | no | - | Profile's uuid | | **firstName** | String | no | - | Profile's first name | | **lastName** | String | no | - | Profile's last name | | **displayName** | String | no | - | Profile's display name | | **company** | String | no | - | Profile's company | | **address** | String | no | - | Profile's address | | **city** | String | no | - | Profile's city | | **province** | String | no | - | Profile's province | | **zipCode** | String | no | - | Profile's ZIP code | | **countryCode** | String | no | - | Profile's country code | | **birthDate** | String | no | - | Profile's birth date | | **sex** | [Sex](/developers/mobile-sdk/class-reference/android/client#sex) | no | - | Profile's sex | | **avatarUrl** | String | no | - | Profile's avatar URL | | **anonymous** | Boolean | no | - | Defines if the profile is anonymous | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | no | - | Profile's agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | - | Profile's attributes |
All properties above are accessible by using setters.
**Initializers:** There are no initializers. **Methods:** There are only setters for above properties. --- --- --- ### RegisterClient Class responsible for registering a profile. **Declared In:** `com.synerise.sdk.client.model.client.RegisterClient` **Declaration:**
```Java public class RegisterClient extends BaseClient ```
```Kotlin class RegisterClient : BaseClient ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | no | - | Profile's agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | - | Profile's attributes | | **city** | String | yes | - | Profile's city | | **company** | String | yes | - | Profile's company | | **countryCode** | String | yes | - | Profile's country code | | **customId** | String | yes | - | Profile's customId | | **firstName** | String | yes | - | Profile's first name | | **lastName** | String | yes | - | Profile's last name | | **phoneNumber** | String | yes | - | Profile's phone number | | **province** | String | yes | - | Profile's province | | **sex** | [Sex](/developers/mobile-sdk/class-reference/android/client#sex) | yes | - | Profile's sex | | **zipCode** | String | yes | - | Profile's ZIP code | | **uuid** | String | yes | - | Profile's UUID | | **email** | String | yes | - | Profile's email | | **password** | String | yes | - | Profile's password | **Initializers:** There are no initializers. **Methods:** All properties have their own setters. --- --- --- ### PasswordResetRequest Class responsible for creating a payload for password reset request. **Declared In:** `com.synerise.sdk.client.model.password.PasswordResetRequest` **Declaration:**
```Java public final class PasswordResetRequest ```
```Kotlin class PasswordResetRequest ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Profile's email | **Initializers:** There is a constructor.
public PasswordResetRequest(@NonNull String email)
**Methods:** There are no methods. --- --- --- ### PasswordResetConfirmation Class responsible for creating a payload for password reset confirmation. **Declared In:** `com.synerise.sdk.client.model.password.PasswordResetConfirmation` **Declaration:**
```Java public final class PasswordResetConfirmation ```
```Kotlin class PasswordResetConfirmation ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **password** | String | no | - | Profile's password | | **token** | String | no | - | Profile's token | **Initializers:** There is a constructor.
public PasswordResetConfirmation(@NonNull String password, @NonNull String token)
**Methods:** There are no methods. --- --- --- ### Sex This enum contains values for the `sex` parameter. **Declared In:** `com.synerise.sdk.core.types.enums.Sex` **Declaration:**
```Java public enum Sex ```
```Kotlin public enum Sex ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **FEMALE** | "FEMALE" | Female | | **MALE** | "MALE" | Male | | **OTHER** | "OTHER" | Other | | **NA** | "NOT_SPECIFIED" | Not specified | **Methods:** This method retrieves the value of the `sex` parameter.
public String getSex()
--- This method retrieves the value of the `sex` parameter.
public static Sex getSex(String name)
--- --- --- ### Agreements Class responsible for passing agreements. **Declared In:** `com.synerise.sdk.client.model.client.Agreements` **Declaration:**
```Java public class Agreements ```
```Kotlin class Agreements ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **email** | Boolean | yes | - | Email agreement | | **sms** | Boolean | yes | - | SMS agreement | | **push** | Boolean | yes | - | Push agreement | | **bluetooth** | Boolean | yes | - | Bluetooth agreement | | **rfid** | Boolean | yes | - | RFID agreement | | **wifi** | Boolean | yes | - | WiFi agreement | **Initializers:** There are no initializers. **Methods:** All properties have their own setters and getters. --- --- --- ### Attributes Class responsible for passing attributes. **Declared In:** `com.synerise.sdk.client.model.client.Attributes` **Declaration:**
```Java public class Attributes ```
```Kotlin class Attributes ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **properties** | HashMap | yes | - | A key-value pair of profile's attributes | **Initializers:** There are no initializers. **Methods:** This method adds attributes.
public Attributes add(String key, String value)
--- This method retrieves a value of an attribute.
public HashMap<String, String> getProperties()
--- --- --- ### ClientEventData Event data model. **Declared In:** `com.synerise.sdk.client.model.events.ClientEventData` **Declaration:**
```Java public class ClientEventData ```
```Kotlin class ClientEventData ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **time** | String | no | - | Event time | | **action** | String | no | - | Event action | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision Hub or Automation Hub. It isn't shown on a Profile card. | | **client** | HashMap | no | - | Profiles |
All properties above are accessible by using getters and setters.
**Initializers:** There are no initializers. **Methods:** This method returns the value of the `email` attribute from the profile hashmap.
public String getClientEmail()
--- This method returns the `uuid` attribute from the profile hashmap.
public String getClientUuid()
--- This method returns the `clientId` attribute from the profile hashmap.
public int getClientId()
--- --- --- ### ClientEventQuery Class responsible for creating a query to get events. **Declared In:** `com.synerise.sdk.client.model.client.ClientEventsQuery` **Declaration:**
```Java public class ClientEventsQuery ```
```Kotlin class ClientEventsQuery ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **actions** | List | yes | - | Event action | | **timeFrom** | Date | yes | - | Event time | | **label** | String | yes | - | This value is currently unused | | **limit** | int | yes | 1000 | Event limit |
All properties above are accessible by using setters.
**Initializers:** There are no initializers. **Methods:** There are no methods. --- --- --- ### TokenPayload TokenPayload model. **Declared In:** `com.synerise.sdk.core.types.model.TokenPayload` **Declaration:**
```Java public class TokenPayload ```
```Kotlin class TokenPayload ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **tokenString** | String | no | Token as a raw string | | **expirationDate** | Date | no | Token's expiration time | | **creationDate** | Date | no | Token's creation time | | **rlm** | [TokenRLM](/developers/mobile-sdk/class-reference/android/client#tokenrlm) | no | Token's RLM | | **origin** | [TokenOrigin](/developers/mobile-sdk/class-reference/android/client#tokenorigin) | no | Token's origin | | **uuid** | String | no | Customer's UUID | | **clientId** | String | no | Customer's ID | | **customId** | String | yes | Customer's custom ID |
All properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. --- --- --- ### Token Token model. **Declared In:** `com.synerise.sdk.core.types.model.Token` **Declaration:**
```Java public class Token ```
```Kotlin class Token ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **rawJwt** | String | no | - | Raw JWT token string | | **expirationUnixTime** | long | no | - | Parsed expiration time in UNIX format | | **signKey** | String | no | - | Encrypted signing key | | **tokenRLM** | [TokenRLM](/developers/mobile-sdk/class-reference/android/client#tokenrlm) | no | - | Token scope | | **tokenOrigin** | [TokenOrigin](/developers/mobile-sdk/class-reference/android/client#tokenorigin) | no | - | Token source origin | | **clientId** | String | no | - | Token customer ID | | **customId** | String | no | - | Token customId |
All properties above are accessible by using getters.
**Initializers:**
public static Token createToken(String signKey, String rawJwt, long expirationUnixTime, String rlm, String origin)
--- --- --- ### TokenOrigin This enum contains values for a token origin. **Declared In:** `com.synerise.sdk.core.types.model.Token.TokenOrigin` **Declaration:**
```Java public enum TokenOrigin ```
```Kotlin public enum TokenOrigin ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **SYNERISE** | "SYNERISE" | Token comes from Synerise | | **SIMPLE_AUTH** | "SIMPLE_AUTH" | Token comes from Synerise Simple Profile Authentication | | **FACEBOOK** | "FACEBOOK" | Token comes from Facebook | | **OAUTH** | "OAUTH" | Token comes from OAuth | | **UNKNOWN** | "UNKNOWN" | Unknown token source | **Methods:** This method retrieves the value of the `origin` parameter.
public String getOrigin()
--- This method retrieves the value of the `origin` parameter.
public static TokenOrigin getOrigin(String rlm)
--- --- --- ### TokenRLM This enum contains values for a token realm. **Declared In:** `com.synerise.sdk.core.types.model.Token.TokenRLM` **Declaration:**
```Java public enum TokenRLM ```
```Kotlin public enum TokenRLM ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **ANONYMOUS** | "anonymous_client" | Anonymous profile | | **CLIENT** | "client" | Recognized profile | **Methods:** This method retrieves the value of the `rlm` parameter.
public String getRlm()
--- This method retrieves the value of the `rlm` parameter.
public static TokenRLM getRlm(String rlm)
--- ### iOS # Method reference - iOS ### React Native # Installation and configuration (React Native) In this article, you will find out how to install and initialize the Synerise SDK in a React Native mobile application. While performing the actions from this guide, keep the presented order presented.
The [Settings](/developers/mobile-sdk/settings#pre-initialization-settings) article contains additional information about SDK behaviors you may need prior to configuration.
## Requirements --- You need: * Access to a [workspace](/docs/settings/business-profile) * 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. ### Android {id=requirements-android} * Recommended environment: - Minimum Android SDK version - 24 - Supported targetSDKVersion - 33 ### iOS {id=requirements-ios} * Recommended environment: - Xcode 16 - iOS SDK 18 * Target deployment: - **iOS 13.0+** for SDK versions 1.0.0 and higher - **iOS 9.0+** for SDK versions lower than 1.0.0
Bitcode is not supported in SDK version 1.0.0 and higher. Xcode ignores bitcode.
## Setting up Android --- 1. Install the module with npm:
npm install react-native-synerise-sdk --save
2. Install dependencies: - **React Native 0.60 or lower:** In your `android` build.gradle top-level build file, add:
...
          allprojects {
              repositories {
                  google()
                  jcenter()
                  maven { url 'https://pkgs.dev.azure.com/Synerise/AndroidSDK/_packaging/prod/maven/v1' }
              }
          }
- **React Native newer than 0.60**: Link the native dependency:
react-native link react-native-synerise-sdk
1. **If you DON'T use autolinking**: In your app's `build.gradle` file, add the following dependency: `implementation 'com.synerise.sdk.react:react-native-synerise-sdk:RN_SDK_VERSION'` where `RN_SDK_VERSION` is the SDK version. You can check the latest version in our [Github repository](https://github.com/Synerise/react-native-synerise-sdk/blob/master/CHANGELOG.md). Doing this together with autolinking causes a build error. 2. In the app's main class, to your list of packages, add `RNSyneriseSdkPackage`
```Java @Override protected List getPackages() { @SuppressWarnings("UnnecessaryLocalVariable") List packages = new PackageList(this).getPackages(); packages.add(new RNSyneriseSdkPackage());; return packages; } ```
## Setting up iOS ---
Starting from React Native 0.60, CocoaPods is the default integration approach for React Native iOS projects.
1. Install the module with npm:
npm install react-native-synerise-sdk --save
2. Install dependencies: - **React Native 0.60 or lower**: Install the native dependencies by using CocoaPods from your `ios` directory:
pod install
- **React Native newer than 0.60**: 1. Link the native dependency.
react-native link react-native-synerise-sdk
1. Install from your iOS:
pod install --repo-update
1. In your `ios/Podfile`, add the following dependency: `pod 'react-native-synerise-sdk', :path => '../node_modules/react-native-synerise-sdk'` **Result**: Your Podfile looks as follows:
target 'YourTarget' do

       # Pods for your target
       pod 'React', :path => '../node_modules/react-native/'
       pod 'React-Core', :path => '../node_modules/react-native/React'
       # ... other React dependencies

       # Add react-native-synerise-sdk
       pod 'react-native-synerise-sdk', :path => '../node_modules/react-native-synerise-sdk'

       use_native_modules!

       end
3. From your `ios` directory, run `pod install`
If you prefer linking manually, check [React Native - Linking Libraries](https://reactnative.dev/docs/linking-libraries-ios/#manual-linking) to link your libraries that contain native code.
## Initialization --- When you use the **react-native-synerise-sdk** module, use the following native **Synerise SDK** frameworks: - [Android](/developers/mobile-sdk/installation-and-configuration/android) - [iOS](/developers/mobile-sdk/installation-and-configuration/ios) ### Importing Synerise SDK You will need to import the **Synerise** object from the **react-native-synerise-sdk** module.
```JavaScript import { Synerise } from 'react-native-synerise-sdk'; ```
You must always import suitable objects from the **react-native-synerise-sdk** module into the files that contain the code that relates to the Synerise SDK.
### Basic initialization Initialize the Synerise SDK and provide the [Profile API Key](/docs/settings/tool/api). You may initialize it wherever you want and when you need.
```JavaScript Synerise.Initializer() .withApiKey('YOUR_PROFILE_API_KEY') // 1 .withRequestValidationSalt('YOUR_REQUEST_VALIDATION_SALT') // 2 .withDebugModeEnabled(false) // 3 .withCrashHandlingEnabled(true) // 4 .init(); ```
1. `.withApiKey('YOUR_PROFILE_API_KEY')` - Sets Profile API Key for Synerise SDK initialization. 2. `.withRequestValidationSalt('YOUR_REQUEST_VALIDATION_SALT')` - Sets salt string for request validation. 3. `.withDebugModeEnabled(false)` - Enables debug mode. See [Debug mode](/developers/mobile-sdk/installation-and-configuration/react-native#debug-mode) section for more information. 4. `.withCrashHandlingEnabled(true)` - Enables crash handling. Synerise SDK sends a crash event automatically when an uncaught exception occurs. ### Initialization with custom API environment You can change the base URL of the API for on-premise installations. Use the following initialization method:
```JavaScript Synerise.Initializer() .withApiKey('YOUR_PROFILE_API_KEY') .withBaseUrl("YOUR_API_BASE_URL") .init(); ```
### Advanced initialization This is an example of advanced initialization with: - custom API base URL for on-premise installations - request validation salt configured - debug mode enabled - crash handling enabled - most settings options available - initialization listeners set
Secure sensitive keys (for example, `clientApiKey` and `requestValidationSalt`) with mechanisms like string obfuscation or encryption.
```JavaScript Synerise.Initializer() .withBaseUrl("YOUR_API_BASE_URL") .withApiKey('YOUR_PROFILE_API_KEY') .withRequestValidationSalt('YOUR_REQUEST_VALIDATION_SALT') .withDebugModeEnabled(true) .withCrashHandlingEnabled(true) .withSettings({ sdk: { enabled: true, minTokenRefreshInterval: 5000, shouldDestroySessionOnApiKeyChange: true }, notifications: { enabled: true, encryption: false, }, injector: { automatic: true, }, tracker: { isBackendTimeSyncRequired: true, minBatchSize: 20, maxBatchSize: 30, autoFlushTimeout: 60 } }) .init(); Synerise.onReady(function() { // This function is called when Synerise is fully initialized and ready. }); Synerise.onError(function(error) { // This function is called when an error occurs during Synerise initialization. }); ```
## Debug mode --- You can enable debug logs for Synerise SDK by using the `.withDebugModeEnabled(true)` method in `Synerise.Initializer` when you initialize the SDK.
Do not use debug mode in a release version of your application.
You can receive logs about: - **Core**: push notifications - **Tracker**: auto-tracked events, declarative events, sending process - **Client**: customer state, authorization - **Injector**: campaigns - **Promotions**: promotions, vouchers - **Content**: content widget, documents, recommendations ## Main Synerise listeners --- You can handle Synerise SDK initialization result by two listener methods: - `Synerise.onReady()` - This method is called when Synerise is initialized. - `Synerise.onError(error: Error)` - This method is called when an error occurs during Synerise initialization. You can specify your custom action when a customer clicks a simple push, banner or walkthrough. Synerise SDK implements two main actions that a customer may invoke - open URL and Deeplink: - `IInjectorListener.onOpenUrl(url: string)` - This method is called when Synerise handles the open URL action from campaign activities. - `IInjectorListener.onDeepLink(deepLink: string)` - This method is called when Synerise handles the deeplink action from campaign activities.
For more information about handling actions from the Synerise SDK, see the [Campaigns](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-react-native) section.
When you want to deal with Push Notifications: - `INotificationsListener.onRegistrationToken?(token: string)` - This method is called when a native part of the application passes a registration token. - `INotificationsListener.onRegistrationRequired?()` - This method is called when Synerise needs registration for Push Notifications. - `INotificationsListener.onNotification(payload: object)` - This method is called when a native part of the application passes a notification payload.
- For more information about notifications in Android SDK, see [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/android) section. - For more information about notifications in iOS SDK, see [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications/ios) section. - For more information about SDK listeners and delegates, see [Listeners and delegates](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners) section.
### React Native # Method reference - React Native ### Customers - A **profile** is the customer data stored in our database. It can be anonymous or recognized. - An **account** is created for a profile when a customer registers and allows them to authorize and access their own data. ### Silent push ## Overview --- Silent push is a hidden notification that is delivered to the app. It does not cause any interaction with the user like a typical push. Silent notifications quietly deliver a certain set of data to the app so you may use it to notify that new content is available or inform about changes in the content. This kind of campaign does not affect your UI. Within the silent push campaign, the SDK provides features such as remote sign out or acquiring location by using a silent push command. Read more in the [SDK Commands](#sdk-commands) section. ## Configuration --- Silent 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). ## Checking custom notification payloads --- The silent push campaign is designed to send notifications with your own payload and in this case should not be passed to the SDK. However, the campaign allows sending any data in payload including [SDK commands](#sdk-commands). Then, the notification must be handled correctly. You may use the samples below.
```Java @Override public void onMessageReceived(RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); Map data = remoteMessage.getData(); if (Injector.isSynerisePush(data)) { if (Injector.isSilentCommand(data)) { try { SilentCommand silentCommand = Injector.getSilentCommand(data); <> } catch (ValidationException e) { e.printStackTrace(); } } } else { <> } } ```
```Swift extension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { let userInfo = notification.userInfo let isSyneriseNotification: Bool = Synerise.isSyneriseNotification(userInfo) if (isSyneriseNotification == true) { let isSyneriseSilentCommand: Bool = Synerise.isSyneriseSilentCommand(userInfo) if isSyneriseSilentCommand { <> } } else { <> } completionHandler(.alert) } } ```
```JavaScript Synerise.onReady(function() { onNotification: function(payload, actionIdentifier) { let isSyneriseNotification = Synerise.Notifications.isSyneriseNotification(payload); if (isSyneriseNotification == true) { let isSyneriseSilentCommand = Synerise.Notifications.isSilentCommand(payload); if (isSyneriseSilentCommand == true) { <> } else { <> } } } }); ```
## Payload ---
{
  "data": {
    <<campaign content>>
  }
}
{
  "aps": {
    "content-available": 1
  },
  <<campaign content>>
}
## SDK Commands --- ### SIGN_OUT {id=sdk-commands-sign-out}
{
  "data": {
    "issuer": "Synerise",
    "message-type": "dynamic-content",
    "content-type": "silent-sdk-command",
    "content": {
      "class_name": "com.synerise.sdk.injector.Injector",
      "method_name": "SIGN_OUT",
      "method_parameters": []
    }
  }
}
{
  "aps": {
    "content-available": 1
  },
  "issuer": "Synerise",
  "message-type": "dynamic-content",
  "content-type": "silent-sdk-command",
  "content": {
    "class_name": "com.synerise.sdk.injector.Injector",
    "method_name": "SIGN_OUT",
    "method_parameters": []
  }
}
### GET_LOCATION {id=sdk-commands-get-location}
{
  "data": {
    "issuer": "Synerise",
    "message-type": "dynamic-content",
    "content-type": "silent-sdk-command",
    "content": {
      "class_name": "com.synerise.sdk.injector.Injector",
      "method_name": "GET_LOCATION",
      "method_parameters": []
    }
  }
}
{
  "aps": {
    "content-available": 1
  },
  "issuer": "Synerise",
  "message-type": "dynamic-content",
  "content-type": "silent-sdk-command",
  "content": {
    "class_name": "com.synerise.sdk.injector.Injector",
    "method_name": "GET_LOCATION",
    "method_parameters": []
  }
}
### Workspace authentication In today's interconnected world, secure authentication mechanisms are crucial for machine-to-machine (M2M) integrations to ensure the confidentiality, integrity, and availability of data. In Synerise, M2M integrations are handled by [Workspace API keys](/docs/settings/tool/api). In each Workspace, you can create multiple API keys with different permissions.
- Keep the API keys secret. A leaked key must be deactivated **immediately**! - When creating the API key, use allowlisting or denylisting to only allow the events you intend to use. - Workspace API keys can be used to access all customer data, analytics, and manage the workspace. Workspace authentication should only be used in server-to-server communication for integrations. DO NOT use workspace API keys in your mobile applications and websites.
Two commonly used methods for API authentication are: - JSON Web Tokens (JWT): this is the default method for authenticating request made when using a Workspace API key. In this scenario, the API key is used to generate a JWT that expires after some time (60 minutes by default) - API keys (Basic authentication): this is an additional method for authenticating as a Workspace that needs to be enabled separately [in the settings of an API key](/docs/settings/tool/api#basic-workspace-authentication). The GUID of the workspace is used as the login, and the API key as the password. This authentication doesn't have an expiration time. This article explores the differences between these two approaches, compares their features, and highlights the ideal usage scenarios for each variant. By understanding their advantages and disadvantages, developers can make informed decisions to implement robust and secure authentication mechanisms. ## API authentication with JWT JWT are a compact, self-contained, and digitally signed authentication mechanism. They are commonly used for stateless authentication in distributed systems. A JWT token consists of three parts: a header, a payload, and a signature. The header contains information about the token's signing algorithm, while the payload contains relevant user or client data. The signature is generated using a secret key and ensures the token's integrity. In Synerise, the token is generated for you when you authenticate as a workspace. You don't need encode/decode it, or manipulate any data that's included in the token. When you use the token to authenticate a request, Synerise decodes it and checks if that token grants the authorization for the operation you're trying to perform. ### Advantages - Stateless: JWTs do not require server-side storage, making them suitable for scaling and load-balanced environments. - Flexibility: JWTs can carry custom data in their payload, allowing for additional information beyond authentication. - Granular Authorization: Tokens can include claims and scopes to control access to specific resources or functionalities. ### Disadvantages - Token Revocation: Since JWTs are stateless, revoking a token before its expiration requires additional mechanisms, such as maintaining a token denylist or short token expiration periods. - Token Size: JWTs can be larger in size compared to API keys, leading to increased bandwidth consumption. ### Usage 1. Obtain a JWT from the [workspace authentication endpoint](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/profileLogin):
curl --request POST 
   --url https://{SYNERISE_API_BASE_PATH}/uauth/v2/auth/login/profile 
   --header 'accept: application/json' 
   --header 'api-version: 4.4' 
   --header 'content-type: application/json' 
   --data '{"apiKey":"01234abc-1234-5678-9abc-def012345678"}'
The response is a JSON Web Token (JWT) that must be included in the `Authorization` header of further requests. By default, the token is valid for 60 minutes. 2. Include the token (preceded by `"Bearer"`) in the `Authorization` header of the requests you make, for example:
curl --location 'https://api.synerise.com/v4/events/custom' \
   --header 'Authorization: Bearer eyJhbGciOiJSUzUxMiJ9.eyJzdWIiOiJjYTQzMTA4ZGVkNWFhYmM3NzkzZDNmOWI5MjhjZGQ1NCIsImF1ZCI6IkFQSSIsInJsbSI6ImJ1c2luZXNzX3Byb2ZpbGUiLCJjdGQiOjE2ODY3NDEyNzE2NTIsImlzcyI6IlN5bmVyaXNlIiwiYnBpIjoyMzcwLCJzZXNzaW9uSWQiOiI3MjIzMTgzMC02ZDVhLTQwNGUtYjVlMy1hMTZlMDkxNzcyODIiLCJleHAiOjE2ODY3NDQ4NzEsImFwayI6ImFlZTM0NzdiLTY0YWItNDFkYy1iMThjLWRhMjQwZmI0ZjdlYyJ9.w9p94Owhdygw7w4EnZnA1nDXQCFyMinvalidANNobb4vukXFtsb_gCAyxCFpS35SDctCtzgMXKetNErhEJKrovrOhlQ2GhxvuAHDf_Rz8EawlEiSuPvaUV0djfqJdZujkD1wPPylRj2neqFy6El5D3gsqByKRZMVekackbmjTr8KQMbfiddeUtZPtIoDcSxsv6SozRruCNjEulczc4Tgn44Ht7ZhiNJDPTfyR2nINcTfuBdMngDG5ye39QzwW7WAgLxKerBKIwS34Ul10gpUD11UJebtGc9B16WWmlXD5iY90HR6cjiexSQ1kTcjkA3yQgVkyNXrRF2e1mpM5cXbWfvcyh0_W-U-kUfRFu4DQcYIvh5M4nT4eiC4RsxsoeJSUEhvfg7bLe085w_ug_f1PBCxiHM' \
   --header 'Api-Version: 4.4' \
   --header 'Content-Type: application/json' \
   --data '{
       "action": "auth.test",
       "client": {
           "id": 6501571767
       },
       "params": {
           "test": true
       },
       "label": "string"
   }'
## Basic API authentication with API keys When creating or editing a workspace API key, you can enable basic authentication. When you do so, you can authenticate with the workspace GUID as the login and the API key as the password. This is available for all endpoints with workspace authentication. The login/password combination is encoded with base64 and the result is sent in the `Authorization` header of an API request. This authentication doesn't have an expiry date and doesn't need additional API calls to obtain JWTs (but the API key can still be used to generate them as [described earlier](#api-authentication-with-jwt)). ### Advantages - Simplicity: API keys are straightforward to implement, making them an ideal choice for simple integrations or quick prototyping. - Easy Revocation: You can revoke access by disabling or deleting an API key, instantly preventing further authentication. - Performance: API keys are typically smaller in size than JWT tokens, resulting in reduced bandwidth consumption. ### Disadvantages - Key Management: Managing and securing a large number of API keys can be challenging, requiring robust key rotation and storage practices. - Insecure Transmission: API keys sent in plain text via URLs or headers may be vulnerable to interception, necessitating additional security measures like HTTPS and sender/receiver environment security controls. ### Usage In the settings of the workspace API key, [enable Basic workspace authentication](/docs/settings/tool/api#basic-workspace-authentication). In the following examples, these values are used: - Workspace GUID (login): `a919b437-c958-46a5-a82e-b1b2d9b68f61` - API key (password): `065e6fe6-8515-44b3-8427-d8a764295ba2` 1. Encode the `workspaceGuid:apiKey` combination with base64. **Example:**
```java import java.nio.charset.StandardCharsets; import java.util.Base64; class Scratch { public static void main(String[] args) { System.out.println(new String(Base64.getEncoder().encode("a919b437-c958-46a5-a82e-b1b2d9b68f61:065e6fe6-8515-44b3-8427-d8a764295ba2".getBytes(StandardCharsets.UTF_8)))); } } ```
```python import base64 loginAndPassword = b'a919b437-c958-46a5-a82e-b1b2d9b68f61:065e6fe6-8515-44b3-8427-d8a764295ba2' print(base64.b64encode(loginAndPassword).decode('utf-8')) ```
**Result:** ``` YTkxOWI0MzctYzk1OC00NmE1LWE4MmUtYjFiMmQ5YjY4ZjYxOjA2NWU2ZmU2LTg1MTUtNDRiMy04NDI3LWQ4YTc2NDI5NWJhMg== ``` 1. Include the result (preceded by `"Basic"`) in the `Authorization` header of the request:
curl --location 'https://api.synerise.com/v4/events/custom' \
   --header 'Authorization: Basic YTkxOWI0MzctYzk1OC00NmE1LWE4MmUtYjFiMmQ5YjY4ZjYxOjA2NWU2ZmU2LTg1MTUtNDRiMy04NDI3LWQ4YTc2NDI5NWJhMg==' \
   --header 'Api-Version: 4.4' \
   --header 'Content-Type: application/json' \
   --data '{
       "action": "auth.test",
       "client": {
           "id": 6501571767
       },
       "params": {
           "test": true
       },
       "label": "string"
   }'
### OAuth This article contains instruction on authenticating a customer in a mobile application with your backend by an OAuth-like method. Prepare your backend for this solution and then you perform part of the configuration on a user interface in the Synerise platform (`app.synerise.com`).
This is the recommended authentication method.
OAuth diagram
OAuth process diagram
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) - [Custom ID overwriting](/docs/settings/tool/iam-for-apps/general#custom-id-overwriting) - [External ID overwriting](/docs/settings/tool/iam-for-apps/general#external-id-overwriting) ## Logic explained --- The authentication process works in the following way: 1. A customer sign-in to the application generates an authentication request to your backend. 2. Your backend provides the application with an access token. 3. The access token is passed to Synerise by using the following methods: 4. Synerise passes that access token: - if the access token is JWT, to external JWK service for validation - if the access token isn't JWT, back to your backend in order to check if it's valid. 5. In response: - If authentication is successful, Synerise receives customer information such as the email, first name, last name, or other details* (the data can be mapped to fields in our system). For more information, check our [guide](/docs/settings/tool/iam-for-apps/oauth). - If the access token is not valid, the response type is different than HTTP 2xx. 6. If the authentication was successful, Synerise provides the application with our JWT access token for the customer (if this the first time this customer is authenticated, they are also registered with the provided information). *You can declare on user interface in Synerise if you want to update the customer's data with each login or only during the first log-in. ## Authentication methods ---
Conditional authentication lets you verify if a customer exists. This way, you can display screens with agreements or processes necessary for the first log-in.
| OS | Method | |--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Android | - [Client.authenticate(token, provider, agreements, attributes, authId)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-by-identityprovider)
- [Client.authenticateConditionally(token, provider, agreements, attributes, authId)](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-conditionally-by-identityprovider) | | iOS | - [Client.authenticate(token:clientIdentityProvider:authID:context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider)
- [Client.authenticateConditionally(token:clientIdentityProvider:authID:context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider) | | React Native | - [Synerise.Client.authenticate(token, clientIdentityProvider, authID, context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-identityprovider)
- [Synerise.Client.authenticateConditionally(token, clientIdentityProvider, authID context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-conditionally-by-identityprovider) | | Flutter | - [Synerise.client.authenticate(clientAuthContext, clientIdentityProvider, token)](/developers/mobile-sdk/method-reference/flutter/client-authentication#authenticate-customer-by-identityprovider)) |
**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 oAuth, Facebook, Sign in with Apple, or RaaS
This method returns `false` if a customer is authenticated through [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication).
| OS | Method | |--------------|-------------------------------------------------------------------------------------------------------------------------------------------| | Android | [Client.isSignedIn()](/developers/mobile-sdk/method-reference/android/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | iOS | [Client.isSignedIn()](/developers/mobile-sdk/method-reference/ios/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | React Native | [Synerise.Client.isSignedIn()](/developers/mobile-sdk/method-reference/react-native/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | Flutter | [Synerise.client.isSignedIn()](/developers/mobile-sdk/method-reference/flutter/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | ### Customer sign out If you want to provide the customer with a logout feature in your application, use this method. 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) | | iOS | [Client.signOut()](/developers/mobile-sdk/method-reference/ios/client-authentication#sign-out-customer) | | React Native | [Synerise.Client.signOut()](/developers/mobile-sdk/method-reference/react-native/client-authentication#sign-out-a-customer) | | 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). ### Customer authentication ## Set Client State Change listener --- Set your own ClientStateChangeListener to get optional callbacks. **Method name:** Client.setOnClientStateChangeListener(listener); **Declaration:**
```Java public static void setOnClientStateChangeListener(OnClientStateChangeListener listener) ```
```Kotlin fun setOnClientStateChangeListener(listener:OnClientStateChangeListener) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **listener** | OnClientStateChangeListener | yes | - | interface to handle client state change | **Return Value:** No value is returned. **Example:**
```Java Client.setOnClientStateChangeListener(listener); ```
```Kotlin Client.setOnClientStateChangeListener(listener) ```
## Remove Client State Change listener --- Remove your own ClientStateChangeListener. **Method name:** Client.removeClientStateChangeListener(); **Declaration:**
```Java public static void removeClientStateChangeListener() ```
```Kotlin fun removeClientStateChangeListener() ```
**Parameters:** No parameters required. **Return Value:** No value is returned. **Example:**
```Java Client.removeClientStateChangeListener(); ```
```Kotlin Client.removeClientStateChangeListener() ```
## Register customer account --- This method registers a new customer with an email, password, and optional data. This method requires the context object with a customer’s email, password, and optional data. Omitted fields are not modified. Depending on the backend configuration, the account may require activation. For details, see [customer registration](/developers/mobile-sdk/user-identification-and-authorization/overview). Do not allow signing in again (or signing up) when a customer is already signed in. Sign the customer out first. Do not create multiple instances nor call this method multiple times before execution. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_REGISTER_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.registerAccount(registerClient) **Declaration:**
```Java public static IApiCall registerAccount(@NonNull RegisterClient registerClient) ```
```Kotlin fun registerAccount(registerClient: RegisterClient): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | | --- | --- | --- | --- | | **registerClient** | [RegisterClient](/developers/mobile-sdk/class-reference/android/client#registerclient) | yes | - | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java private IApiCall signUpCall; private void signUp(RegisterClient registerClient) { if (signUpCall != null) signUpCall.cancel(); signUpCall = Client.registerAccount(registerClient); signUpCall.onSubscribe(() -> toggleLoading(true)) .doFinally(() -> toggleLoading(false)) .execute(this::onSignUpSuccessful, this::onSignUpFailure); } ```
```Kotlin private var signUpCall: IApiCall private fun signUp(registerClient: RegisterClient) { signUpCall!!.cancel() signUpCall = Client.registerAccount(registerClient) signUpCall!!.onSubscribe({ toggleLoading(true) }) .doFinally({ toggleLoading(false) }) .execute(({ this.onSignUpSuccessful() }), ({ this.onSignUpFailure() })) } ```
## Request customer account activation --- This method requests sending an email with a URL that confirms the registration and activates the account. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.requestAccountActivation(email) **Declaration:**
```java public static IApiCall requestAccountActivation(String email) ```
```kotlin fun requestAccountActivation(email: String): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - |Customer's email| **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall call; if (call != null) call.cancel(); call = Client.requestAccountActivation(email); call.execute(this::onSuccess, this::onError); ```
```kotlin private val call: IApiCall? = null call.cancel(); call = Client.requestAccountActivation(email); call.execute(this::onSuccess, this::onError); ```
## Confirm customer account activation --- This method confirms a customer account with the confirmation token. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 400 status code if the account is already confirmed or 404 if the account does not exist.
The API key must have the `SAUTH_CONFIRMATION_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.confirmAccountActivation(token) **Declaration:**
```java public static IApiCall confirmAccountActivation(String token) ```
```kotlin fun confirmAccountActivation(token: String): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Customer's token | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall call; if (call != null) call.cancel(); call = Client.confirmAccountActivation(token); call.execute(this::onSuccess, this::onError); ```
```kotlin private val call: IApiCall? = null call.cancel(); call = Client.confirmAccountActivation(token); call.execute(this::onSuccess, this::onError); ```
## Request customer account activation by pin --- This method requests a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.requestAccountActivationByPin(email) **Declaration:**
```Java public static IApiCall requestAccountActivationByPin(String email) ```
```Kotlin fun requestAccountActivationByPin(email:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Email to which the pinCode will be sent | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall apiCall; apiCall = Client.requestAccountActivationByPin(email); apiCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val apiCall:IApiCall apiCall = Client.requestAccountActivationByPin(email) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Confirm customer account activation by pin --- This method confirms a customer's account registration process with the PIN code. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PIN_CODE_RESEND_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.confirmAccountActivationByPin(pinCode, email) **Declaration:**
```Java public static IApiCall confirmAccountActivationByPin(String pinCode, String email) ```
```Kotlin fun confirmAccountActivationByPin(pinCode: String, email:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pinCode** | String | yes | - | Code sent to the customer's email | | **email** | String | yes | - | Email used in the registration process | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall apiCall; apiCall = Client.confirmAccountActivationByPin(pinCode, email); apiCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val apiCall:IApiCall apiCall = Client.confirmAccountActivationByPin(pinCode, email) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Sign in a customer --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. **Method name:** Client.signIn(email, password) **Declaration:**
```Java public static IApiCall signIn(@NonNull String email, @NonNull String password) ```
```Kotlin fun signIn(email: String, password: String): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's email | | **password** | String | yes | - | Customer's password | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java private IApiCall signInCall; private void signIn(String login, String password) { if (signInCall != null) signInCall.cancel(); signInCall = Client.signIn(login, password); signInCall.onSubscribe(() -> toggleLoading(true)) .execute(() -> onSignInSuccessful(login), () -> onSignInFailure()); } ```
```Kotlin private var signInCall: IApiCall private fun signIn(login: String, password: String) { signInCall!!.cancel() signInCall = Client.signIn(login, password) signInCall!!.onSubscribe({ toggleLoading(true) }) .execute({ onSignInSuccessful(login) }, { onSignInFailure() }) } ```
## Sign in a customer conditionally --- This method signs a customer in to obtain a JSON Web Token (JWT) which can be used in subsequent requests. The SDK will refresh the token before each call if it is about to expire (but not expired). Do NOT allow signing in again (or signing up) when a customer is already signed in. First, sign the customer out. Do NOT create multiple instances nor call this method multiple times before execution. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Method name:** Client.signInConditionally(email, password) **Declaration:**
```java public static IDataApiCall signInConditionally(@NonNull String email, @NonNull String password) ```
```kotlin fun signInConditionally( email: String, password: String, ): IDataApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Client's email | | **password** | String | yes | - | Client's password | **Return Value:** IDataApiCall<[AuthConditions](/developers/mobile-sdk/class-reference/android/client#authconditions)> object to execute the request. **Example:**
```java private IDataApiCall call; if (call != null) call.cancel(); call = Client.signInConditionally(email, password)); call.execute(this::onSuccess, this::onFailure); ```
```kotlin val call:IDataApiCall call.cancel() call = Client.signInConditionally(email, password) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Authenticate customer by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. If an account for the customer does not exist and the identity provider is different than Synerise, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | 0.3.0 | **Method name:** Client.authenticate(token, clientIdentityProvider, agreements, attributes, authId) **Declaration:**
```java public static IApiCall authenticate(String token, ClientIdentityProvider provider, Agreements agreements, Attributes attributes, String authId) ```
```kotlin fun authenticate( token: String, provider: ClientIdentityProvider, agreements: Agreements?, attributes: Attributes?, authId: String? ): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Token retrieved from provider | | **provider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/android/client#clientidentityprovider) | yes | - | Provider of your token | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | no | - | Optional agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | - | Optional attributes | | **authId** | String | no | - | Optional identifier of authorization |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall call; if (call != null) call.cancel(); call = Client.authenticate(token, provider, null, null, null); call.execute(this::onSuccess, this::onFailure); ```
```kotlin val call:IApiCall call.cancel() call = Client.authenticate(token, provider, null, null, null) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Authenticate customer conditionally by IdentityProvider --- This method authenticates a customer with OAuth, Facebook, Google, Apple, or Synerise. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | **Method name:** Client.authenticateConditionally(token, clientIdentityProvider, agreements, attributes, authId) **Declaration:**
```java public static IDataApiCall authenticateConditionally(@NonNull String token, @NonNull ClientIdentityProvider provider, @Nullable Agreements agreements, @Nullable Attributes attributes, @Nullable String authId) ```
```kotlin fun authenticateConditionally( token: String, provider: ClientIdentityProvider, agreements: Agreements?, attributes: Attributes?, authId: String? ): IDataApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Token retrieved from provider | | **provider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/android/client#clientidentityprovider) | yes | - | Provider of your token | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | no | - | Optional agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | - | Optional attributes | | **authId** | String | no | - | Optional identifier of authorization |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** IDataApiCall<[AuthConditions](/developers/mobile-sdk/class-reference/android/client#authconditions)> object to execute the request. **Example:**
```java private IDataApiCall call; if (call != null) call.cancel(); call = Client.authenticateConditionally(token, clientIdentityProvider, agreements, attributes, authId)); call.execute(this::onSuccess, this::onFailure); ```
```kotlin val call:IDataApiCall call.cancel() call = Client.authenticateConditionally(token, clientIdentityProvider, agreements, attributes, authId) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Authenticate customer with token payload --- This method signs in a customer in with the provided token payload. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.15.0 | 5.15.0 | n/a | n/a | **Method name:** Client.authenticateWithTokenPayload() **Declaration:**
```Java public static IApiCall authenticateWithTokenPayload(TokenPayload tokenPayload, @NonNull String authId) ```
```Kotlin fun authenticateWithTokenPayload( tokenPayload: TokenPayload, authId: String ): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **tokenPayload** | [TokenPayload](/developers/mobile-sdk/class-reference/android/client#tokenpayload) | yes | - | Object which contains a token's payload | | **authId** | String | yes | - | Required customer's identifier of authorization |
**authId** parameter is used for decreasion the number of UUID refreshes so it must be unique for every customer.
**Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall call; if (call != null) call.cancel(); call = Client.authenticateWithTokenPayload(tokenPayload, authId); call.execute(this::onSuccess, this::onFailure); ```
```kotlin val call:IApiCall call.cancel() call = Client.authenticateWithTokenPayload(tokenPayload, authId) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Authenticate customer via Simple Profile Authentication --- This method authenticates a customer with Simple Profile Authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 |
When you use this method, you must set a request validation salt by using the `Synerise.setRequestValidationSalt(_:)` method (if salt is enabled for Simple Profile Authentication).
The API key must have the `SAUTH_SIMPLE_AUTH_CREATE` from the **Auth** group.
**Method name:** Client.simpleAuthentication(clientData, authId) **Declaration:**
```java public static IApiCall simpleAuthentication(ClientData clientData, String authId) ```
```kotlin fun simpleAuthentication( clientData: ClientData, authId: String ): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientData** | [ClientData](/developers/mobile-sdk/class-reference/android/client#clientdata) | yes | - | Object which contains customer data | | **authId** | String | yes | - | Required identifier of authorization |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. ## Check if a customer is signed in (via RaaS, OAuth, Facebook, Apple) --- This method checks if a customer is signed in (via Synerise Authentication - RaaS, OAuth, Facebook, Apple). **Method name:** Client.isSignedIn() **Declaration:**
```Java public static boolean isSignedIn() ```
```Kotlin fun isSignedIn():Boolean ```
**Parameters:** No parameters. **Return Value:** Boolean defining whether a customer is signed in or not. **Example:**
```Java boolean isSignedIn = Client.isSignedIn() ```
```Kotlin var isSignedIn = Client.isSignedIn() ```
## Check if a customer is signed in (via Simple Profile Authentication) --- This method checks if a customer is signed in (via Simple Profile Authentication). | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 0.7.0 | **Method name:** Client.isSignedIn() **Declaration:**
```Java public static boolean isSignedInViaSimpleAuthentication() ```
```Kotlin fun isSignedInViaSimpleAuthentication():Boolean ```
**Parameters:** No parameters. **Return Value:** **true** if the customer is signed in (via Simple Profile Authentication), otherwise returns **false**. **Example:**
```Java boolean isSignedInViaSimpleAuthentication = Client.isSignedInViaSimpleAuthentication() ```
```Kotlin var isSignedInViaSimpleAuthentication = Client.isSignedInViaSimpleAuthentication() ```
## Sign out customer --- This method signs out a customer out.
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Method name:** Client.signOut() **Declaration:**
```Java public static void signOut() ```
```Kotlin fun signOut() ```
**Parameters:** No parameters. **Return Value:** Nothing is returned. **Example:**
```Java Client.signOut(); ```
```Kotlin Client.signOut(); ```
## Sign out customer with mode or from all devices --- This method signs out a customer out with a chosen mode and Determines if the method should sign out all devices. Available modes: - `.signOut` mode signs out the customer. - `.signOutWithSessionDestroy` mode signs out the customer and additionally, clears the anonymous session and regenerates the customer UUID. The `fromAllDevices` parameter determines whether the method should notify the backend to sign out all devices. **IMPORTANT: It is an asynchronous method.** | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.11.0 | 5.1.0 | 0.14.0 | 1.0.0 |
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Class:** [Client](/developers/mobile-sdk/class-reference/android/modules#client) **Declaration:**
```java public static IApiCall signOut(ClientSignOutMode mode, Boolean signOutFromAllDevices) ```
```kotlin fun signOut(mode: ClientSignOutMode, signOutFromAllDevices: Boolean): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **mode** | [ClientSignOutMode](/developers/mobile-sdk/class-reference/android/client#clientsignoutmode) | yes | - | Client sign out mode | | **signOutFromAllDevices** | Boolean | yes | - | Determines if the method should sign out all devices | **Return Value:** Nothing is returned. **Example:**
```java private IApiCall signOutCall; private void signOut() { if (signOutCall != null) signOutCall.cancel(); signOutCall = Client.signOut(ClientSignOutMode.SIGN_OUT_WITH_SESSION_CLEARING, true); signOutCall.onSubscribe(() -> toggleLoading(true)) .execute(() -> onSignOutSuccessful(login), () -> onSignOutFailure()); } ```
```kotlin private var signOutCall: IApiCall private fun signOut(login: String, password: String) { signOutCall!!.cancel() signOutCall = Client.signOut(.SIGN_OUT_WITH_SESSION_CLEARING, true) signOutCall!!.onSubscribe({ toggleLoading(true) }) .execute({ onSignOutSuccessful(login) }, { onSignOutFailure() }) } ```
## Removed methods ### Authenticate customer by OAuth with registration {#authenticate-customer-by-oauth-with-registration} --- This method authenticates a customer with OAuth. If an account for the customer does not exist, this request creates an account. | Available on | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided access token and/or API Key is invalid.
**Method name:** Client.authenticateByOAuth(accessToken, agreements, attributes, authId) **Declaration:**
```java public static IApiCall authenticateByOAuth(@NonNull String accessToken, @Nullable Agreements agreements, @Nullable Attributes attributes, @Nullable String authId) ```
```kotlin fun authenticateByOAuth( accessToken: String, agreements: Agreements?, attributes: Attributes?, authId: String? ): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | String | yes | - | OAuth Access Token | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements) | no | --- | Optional agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | --- | Optional attributes | | **authId** | String | no | --- | Optional identifier of authorization |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall call; if (call != null) call.cancel(); call = Client.authenticateByOAuth(token, null, null, null); call.execute(this::onSuccess, this::onFailure); ```
```kotlin val call:IApiCall call.cancel() call = Client.authenticateByOAuth(token, null, null, null) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
### Authenticate customer by OAuth without registration {#authenticate-customer-by-oauth-without-registration} --- This method authenticates a customer with OAuth. | Available on | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided access token and/or API Key is invalid.
**Method name:** Client.authenticateByOAuthIfRegistered(accessToken, authId) **Declaration:**
```java public static IApiCall authenticateByOAuthIfRegistered(@NonNull String accessToken, @Nullable String authId) ```
```kotlin fun authenticateByOAuthIfRegistered( accessToken: String, authId: String? ): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | String | yes | - | OAuth Access Token | | **authId** | String | no | --- | Optional identifier of authorization |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall call; if (call != null) call.cancel(); call = Client.authenticateByOAuthIfRegistered(token, null); call.execute(this::onSuccess, this::onFailure); ```
```kotlin val call:IApiCall call.cancel() call = Client.authenticateByOAuthIfRegistered(token, null) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
### Authenticate customer by Facebook with registration {#authenticate-customer-by-facebook-with-registration} --- This method authenticates a customer with Facebook. If an account for the customer does not exist, this request creates an account. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided Facebook token and/or API Key is invalid.
**Method name:** Client.authenticateByFacebook(facebookToken, agreements, attributes, authId) **Declaration:**
```java public static IApiCall authenticateByFacebook(@NonNull String facebookToken, @Nullable Agreements agreements, @Nullable Attributes attributes, @Nullable String authId) ```
```kotlin fun authenticateByFacebook( facebookToken: String, agreements: Agreements?, attributes: Attributes?, authId: String? ): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | String | yes | - | Facebook Access Token | | **agreements** | [Agreements](/developers/mobile-sdk/class-reference/android/client#agreements)| no | --- | Marketing agreements | | **attributes** | [Attributes](/developers/mobile-sdk/class-reference/android/client#attributes) | no | --- | Additional attributes | | **authId** | String | no | --- | Optional identifier of authorization |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java private IApiCall signInFacebookCall; private void signInFacebook(String facebookToken) { if (signInFacebookCall != null) signInFacebookCall.cancel(); signInFacebookCall = Client.authenticateByFacebook(facebookToken, null, null, null); signInFacebookCall.onSubscribe(() -> toggleFacebookLoading(true)) .execute(this::onSignInFacebookSuccess, this::onSignInFacebookError); } ```
```Kotlin private var signInFacebookCall: IApiCall? = null private fun signInFacebook(facebookToken: String) { if (signInFacebookCall != null) signInFacebookCall!!.cancel() signInFacebookCall = Client.authenticateByFacebook(facebookToken, null, null, null) signInFacebookCall!!.onSubscribe({ toggleFacebookLoading(true) }) .execute(({ this.onSignInFacebookSuccess() }), ({ this.onSignInFacebookError() })) } ```
### Authenticate customer by Facebook without registration {#authenticate-customer-by-facebook-without-registration} --- This method authenticates a customer with Facebook. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.7 | n/a | | Deprecated in: | 3.7.6 | 3.8.0 | 0.9.19 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a |
Returns the HTTP 401 status code if the provided Facebook token and/or API Key is invalid.
**Method name:** Client.authenticateByFacebookRegistered(facebookToken, authId) **Declaration:**
```java public static IApiCall authenticateByFacebookRegistered(@NonNull String facebookToken, @Nullable String authId) ```
```kotlin fun authenticateByFacebookRegistered(facebookToken: String, authId: String?): IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | String | yes | - | Facebook Access Token| | **authId** | String | no | --- | Optional identifier of authorization |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall signInFacebookRegisteredCall; private void signInFacebookRegistered(String facebookToken) { if (signInFacebookRegisteredCall != null) signInFacebookRegisteredCall.cancel(); signInFacebookRegisteredCall = Client.authenticateByFacebookRegistered(facebookToken, null); signInFacebookRegisteredCall.onSubscribe(() -> toggleFacebookLoading(true)) .execute(this::onSignInFacebookSuccess, this::onSignInFacebookError); } ```
```kotlin private var signInFacebookRegisteredCall: IApiCall? = null private fun signInFacebook(facebookToken: String) { signInFacebookRegisteredCall!!.cancel() signInFacebookRegisteredCall = Client.authenticateByFacebookRegistered(facebookToken, null) signInFacebookRegisteredCall!!.onSubscribe({ toggleFacebookLoading(true) }) .execute(({ this.onSignInFacebookSuccess() }), ({ this.onSignInFacebookError() })) } ```
### Sign out customer with mode {#sign-out-customer-with-mode} --- This method signs out a customer out with a chosen mode: - `.signOut` mode notifies the backend that the customer is signed out. - `.signOutWithSessionDestroy` mode notifies the backend that the customer is signed out and additionally, clears the anonymous session and regenerates the customer UUID. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.4.0 | 4.6.0 | 0.12.0 | 0.7.0 | | Deprecated in: | 4.11.0 | 5.1.0 | - | - | | Removed in: | 5.0.0 | 6.0.0 | 0.14.0 | 1.0.0 |
This method works with every authentication type (via Synerise, External Provider, OAuth or Simple Profile Authentication).
**Class:** [Client](/developers/mobile-sdk/class-reference/android/modules#client) **Declaration:**
```java public static void signOut(ClientSignOutMode mode) ```
```kotlin fun signOut() ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **mode** | [ClientSignOutMode](/developers/mobile-sdk/class-reference/android/client#clientsignoutmode) | yes | - | Client sign out mode | **Return Value:** Nothing is returned. **Example:**
```Java Client.signOut(mode); ```
```Kotlin Client.signOut(mode); ```
### Events ### Event Main event abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `RecommendationEvent` subclasses instead.
**Declared In:** lib/classes/events/Event.js **Declaration:**
abstract class Event
**Initializers:**
constructor(type: string, label: string, action: string | null, parameters: object)
--- --- ### CustomEvent
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
Represents a custom client event. **Declared In:** lib/classes/events/other/CustomEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class CustomEvent extends Event
**Initializers:**
constructor(label: string, action: string, parameters?: Record<string, any>)
--- --- ### PushViewedEvent Represents a 'client viewed push' event. This event is used for push message interaction tracking. **Declared In:** lib/classes/events/push/ViewedPushEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class PushViewedEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### PushClickedEvent Represents a 'client clicked push' event. This event is used for push message interaction tracking. **Declared In:** lib/classes/events/push/ClickedPushEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class PushClickedEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### PushCancelledEvent Represents a 'client viewed push' event. This event is used for push message interaction tracking. **Declared In:** lib/classes/events/push/CancelledPushEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class PushCancelledEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### CartEvent Main cart action abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `CartEvent` subclasses instead.
**Declared In:** lib/classes/events/cart/CartEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class CartEvent extends Event
**Initializers:**
constructor(type: string, label: string, sku: string, finalPrice: UnitPrice, quantity: number, parameters?: object)
**Methods:** This method sets a value for the `name` parameter.
public setName(name: string)
--- This method sets a value for the `category` parameter.
public setCategory(category: string)
--- This method sets values for the `categories` parameter.
public setCategories(categories: string[])
--- This method sets a value for the `offline` parameter.
public setOffline(offline: boolean)
--- This method sets the value of the `regularPrice` parameter.
public setRegularPrice(regularPrice: UnitPrice)
--- This method sets the value of the `discountedPrice` parameter.
public setDiscountedPrice(discountedPrice: UnitPrice)
--- This method sets the value of the `url` parameter.
public setUrl(url: string)
--- This method sets the value of the `producer` parameter (producer can signify a brand of the item).
public setProducer(producer: string)
--- --- ### UnitPrice **Declared In:** lib/classes/events/cart/UnitPrice.js **Declaration:**
class UnitPrice
**Initializers:**
constructor(amount: number, currency: string)
--- --- ### ProductAddedToCartEvent Represents a 'client added product to cart' event. **Declared In:** lib/classes/events/product/ProductAddedToCartEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class ProductAddedToCartEvent extends CartEvent
**Initializers:**
constructor(label: string, sku: string, finalPrice: UnitPrice, quantity: number, parameters?: object)
--- --- ### ProductRemovedFromCartEvent Represents a 'client removed product from cart' event. **Declared In:** lib/classes/events/cart/RemovedFromCartEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class ProductRemovedFromCartEvent extends CartEvent
**Initializers:**
constructor(label: string, sku: string, finalPrice: UnitPrice, quantity: number, parameters?: object)
--- --- ### ProductViewedEvent Represents a 'client viewed product' event. **Declared In:** lib/classes/events/product/ProductViewEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class ProductViewedEvent extends Event
**Initializers:**
constructor(label: string, productId: string, name: string, parameters?: object)
**Methods:** This method sets a value for the `category` parameter.
public setCategory(category: string)
--- This method sets the value of the `url` parameter.
public setUrl(url: string)
--- --- ### ProductAddedToFavoritesEvent Represents a 'client added product to favorites' event. **Declared In:** lib/classes/events/product/ProductAddedToFavouritesEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class ProductAddedToFavouritesEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### LoggedInEvent Represents a 'client logged in' event. **Declared In:** lib/classes/events/auth/LoggedInEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class LoggedInEvent extends Event
--- --- ### LoggedOutEvent Represents a 'client logged out' event. **Declared In:** lib/classes/events/auth/LoggedOutEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class LoggedOutEvent extends Event
--- --- ### RegisteredEvent Represents a 'client registered' event. **Declared In:** lib/classes/events/auth/RegisteredEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class RegisteredEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ## RecommendationEvent Main recommendation abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `RecommendationEvent` subclasses instead.
**Declared In:** lib/classes/events/recommendation/RecommendationEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class RecommendationEvent extends Event
**Initializers:**
constructor(type: string, label: string, productId: string, name: string, campaignId: string, campaignHash: string, parameters?: object)
--- --- ### RecommendationSeenEvent Represents a 'client saw a recommendation' event. **Declared In:** lib/classes/events/recommendation/RecommendationSeenEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class RecommendationSeenEvent extends RecommendationEvent
**Initializers:**
constructor(label: string, productId: string, name: string, campaignId: string, campaignHash: string, parameters?: object)
--- --- ### RecommendationClickEvent Represents a 'client clicked a recommendation' event. **Declared In:** lib/classes/events/recommendation/RecommendationClickEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) [RecommendationEvent](/developers/mobile-sdk/class-reference/react-native/events#recommendationevent) **Declaration:**
class RecommendationClickEvent extends RecommendationEvent
**Initializers:**
constructor(label: string, productId: string, name: string, campaignId: string, campaignHash: string, parameters?: object)
--- --- ### VisitedScreenEvent Represents a 'client visited screen' event. This can be used for mobile screen usage tracking. **Declared In:** lib/classes/events/other/VisitedScreenEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class VisitedScreenEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### HitTimerEvent Represents a 'client hit timer' event. This could be used for profiling or activity time monitoring - you can send a `HitTimerEvent` when your client starts doing something and send it once again when they finish, but this time with the different time signature. Then you can use our analytics engine to measure, for example, average activity time. **Declared In:** lib/classes/events/other/HitTimerEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class HitTimerEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### SearchedEvent Represents a 'client searched' event. **Declared In:** lib/classes/events/other/SearchedEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class SearchedEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### SharedEvent Represents a 'client shared' event. **Declared In:** lib/classes/events/other/SharedEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class SharedEvent extends Event
**Initializers:**
constructor(label: string, parameters?: object)
--- --- ### AppearedInLocationEvent Represents a 'client appeared in location' event. **Declared In:** lib/classes/events/other/AppearedInLocationEvent.js **Inherits From:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) **Declaration:**
class AppearedInLocationEvent extends Event
**Initializers:**
constructor(label: string, lat: number, lon: number, parameters?: object)
### Events ### TrackerParams Represents custom parameters that may be added to tracked events. **Declared In:** Headers/SNRTrackerParams.h **Related To:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class TrackerParams: NSObject ```
```Objective-C @interface SNRTrackerParams : NSObject ```
**Initializers:**
```Swift static func makeWithBuilder(_: ((TrackerParamsBuilder) -> ())) ```
```Objective-C + (instancetype)makeWithBuilder:(nonnull void (^)(SNRTrackerParamsBuilder *builder))buildBlock ```
--- --- ### TrackerParamsBuilder Object that is used to create parameters for the event classes. **Declared In:** Headers/SNRTrackerParamsBuilder.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class TrackerParamsBuilder: NSObject ```
```Objective-C @interface SNRTrackerParamsBuilder : NSObject ```
**Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
**Methods:**
```Swift func setString(_: String) ```
```Objective-C - (void)setString:(nonnull NSString *)string forKey:(nonnull NSString *)key ```
---
```Swift func setInt(_: Int) ```
```Objective-C - (void)setInt:(NSInteger)integer forKey:(nonnull NSString *)key ```
---
```Swift func setDouble(_: Double) ```
```Objective-C - (void)setDouble:(double)doubleValue forKey:(nonnull NSString *)key ```
---
```Swift func setFloat(_: Float) ```
```Objective-C - (void)setFloat:(float)floatValue forKey:(nonnull NSString *)key ```
---
```Swift func setBool(_: Bool) ```
```Objective-C - (void)setBool:(BOOL)boolValue forKey:(nonnull NSString *)key ```
---
```Swift func setObject(_: AnyClass) ```
```Objective-C - (void)setObject:(nonnull id)object forKey:(nonnull NSString *)key ```
--- --- ### Event Main event abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `Event` subclasses instead.
**Declared In:** Headers/SNREvent.h **Related To:** [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) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class Event: NSObject ```
```Objective-C @interface SNREvent : NSObject ```
**Initializers:**
```Swift init(label: String) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label ```
---
```Swift init(label: String, params: TrackerParams) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andParams:(nullable SNRTrackerParams *)params ```
--- --- ### CustomEvent
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
Represents a custom event. **Declared In:** Headers/SNRCustomEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class CustomEvent: Event ```
```Objective-C @interface SNRCustomEvent : SNREvent ```
**Initializers:**
```Swift init(type: String, label: String, action: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithType:(nonnull NSString *)type label:(nonnull NSString *)label action:(nonnull NSString *)action andParams:(nullable SNRTrackerParams *)params ```

```Swift init(label: String, action: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label action:(nonnull NSString *)action andParams:(nullable SNRTrackerParams *)params ```

```Swift init(label: String, action: String) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label action:(nonnull NSString *)action ```
--- --- ### PushViewedEvent Represents a 'client viewed push' event. This event is used for push message interaction tracking. **Declared In:** Headers/SNRPushViewedEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class PushViewedEvent: Event ```
```Objective-C @interface SNRPushViewedEvent : SNREvent ```
--- --- ### PushClickedEvent Represents a 'client clicked push' event. This event is used for push message interaction tracking. **Declared In:** Headers/SNRPushClickedEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class PushClickedEvent: Event ```
```Objective-C @interface SNRPushClickedEvent : SNREvent ```
--- --- ### PushCancelledEvent Represents a 'client viewed push' event. This event is used for push message interaction tracking. **Declared In:** Headers/SNRCancelledPushEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class CancelledPushEvent: Event ```
```Objective-C @interface SNRCancelledPushEvent : SNREvent ```
--- --- ### CartEvent Main cart action abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `CartEvent` subclasses instead.
**Declared In:** Headers/SNRCartEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class CartEvent: Event ```
```Objective-C @interface SNRCartEvent : SNREvent ```
**Initializers:**
```Swift init(label: String, sku String, finalPrice: UnitPrice, quantity: Int, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label sku:(nonnull NSString *)sku finalPrice:(nonnull SNRUnitPrice *)unitPrice quantity:(NSInteger)quantity andParams:(nullable SNRTrackerParams *)params ```
---
```Swift init(label: String, sku: String, finalPrice: UnitPrice, quantity: Int) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label sku:(nonnull NSString *)sku finalPrice:(nonnull SNRUnitPrice *)unitPrice quantity:(NSInteger)quantity ```
**Methods:** This method sets a value for the `name` parameter.
```Swift func setName(_: String) ```
```Objective-C - (void)setName:(nonnull NSString *)name ```
--- This method sets a value for the `category` parameter.
```Swift func setCategory(_: String) ```
```Objective-C - (void)setCategory:(nonnull NSString *)category ```
--- This method sets values for the `categories` parameter.
```Swift func setCategories(_: [String]) ```
```Objective-C - (void)setCategories:(nonnull NSArray *)categories ```
--- This method sets a value for the `offline` parameter.
```Swift func setOffline(_: Bool) ```
```Objective-C - (void)setOffline:(BOOL)isOffline ```
--- This method sets the value of the `regularPrice` parameter.
```Swift func setRegularPrice(_: UnitPrice) ```
```Objective-C - (void)setRegularPrice:(nonnull SNRUnitPrice *)price ```
--- This method sets the value of the `discountedPrice` parameter.
```Swift func setDiscountedPrice(_: UnitPrice) ```
```Objective-C - (void)setDiscountedPrice:(nonnull SNRUnitPrice *)price ```
--- This method sets the value of the `url` parameter.
```Swift func setURL(_: URL) ```
```Objective-C - (void)setURL:(nonnull NSURL *)url ```
--- This method sets the value of the `producer` parameter (producer can signify a brand of the item).
```Swift func setProducer(_: String) ```
```Objective-C - (void)setProducer:(nonnull NSString *)producer ```
--- --- ### UnitPrice **Declared In:** Headers/SNRUnitPrice.h **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class UnitPrice: NSObject ```
```Objective-C @interface SNRUnitPrice : NSObject ```
**Initializers:**
```Swift init(amount: Float) ```
```Objective-C - (instancetype)initWithAmount:(float)amount ```
---
```Swift init(amount: Float, locale: NSLocale) ```
```Objective-C - (instancetype)initWithAmount:(float)amount locale:(nonnull NSLocale *)locale ```
--- --- ### ProductAddedToCartEvent Represents a 'client added product to cart' event. **Declared In:** Headers/SNRProductAddedToCartEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) [CartEvent](/developers/mobile-sdk/class-reference/ios/events#cartevent) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class ProductAddedToCartEvent: CartEvent ```
```Objective-C @interface SNRProductAddedToCartEvent : SNRCartEvent ```
--- --- ### ProductRemovedFromCartEvent Represents a 'client removed product from cart' event. **Declared In:** Headers/SNRProductRemovedFromCartEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) [CartEvent](/developers/mobile-sdk/class-reference/ios/events#cartevent) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class ProductRemovedFromCartEvent: CartEvent ```
```Objective-C @interface SNRProductRemovedFromCartEvent : SNRCartEvent ```
--- --- ### ProductViewedEvent Represents a 'client viewed product' event. **Declared In:** Headers/SNRProductViewedEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class ProductViewedEvent: Event ```
```Objective-C @interface SNRProductViewedEvent : SNREvent ```
**Initializers:**
```Swift init(label: String, productName: String, productId: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label productName:(nonnull NSString *)productName productId:(nonnull NSString *)productId andParams:(nullable SNRTrackerParams *)params ```
**Methods:** Sets if a product is recommended or not.
```Swift func setIsRecommended(_: Bool) ```
```Objective-C - (void)setIsRecommended:(BOOL)isRecommended ```
--- This method sets a value for the `category` parameter.
```Swift func setCategory(_: String) ```
```Objective-C - (void)setCategory:(NSString *)category ```
--- This method sets the value of the `url` parameter.
```Swift func setURL(_: URL) ```
```Objective-C - (void)setURL:(NSURL *)url ```
--- --- ### ProductAddedToFavoritesEvent Represents a 'client added product to favorites' event. **Declared In:** Headers/SNRProductAddedToFavoritesEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class ProductAddedToFavoritesEvent: Event ```
```Objective-C @interface SNRProductAddedToFavoritesEvent : SNREvent ```
--- --- ### LoggedInEvent Represents a 'client logged in' event. **Declared In:** Headers/SNRLoggedInEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events/#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events/#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events/#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class LoggedInEvent: Event ```
```Objective-C @interface SNRLoggedInEvent : SNREvent ```
--- --- ### LoggedOutEvent Represents a 'client logged out' event. **Declared In:** Headers/SNRLoggedOutEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class LoggedOutEvent: Event ```
```Objective-C @interface SNRLoggedOutEvent : SNREvent ```
--- --- ### RegisteredEvent Represents a 'client registered' event. **Declared In:** Headers/SNRCancelledPushEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class RegisteredEvent: Event ```
```Objective-C @interface SNRRegisteredEvent : SNREvent ```
--- --- ### RecommendationEvent Main recommendation abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `RecommendationEvent` subclasses instead.
**Declared In:** Headers/SNRRecommendationEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class RecommendationEvent: Event ```
```Objective-C @interface SNRRecommendationEvent : SNREvent ```
--- --- ### RecommendationViewEvent Represents a 'client viewed a recommendation' event. **Declared In:** Headers/SNRRecommendationViewEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) [RecommendationEvent](/developers/mobile-sdk/class-reference/ios/events#recommendationevent) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class RecommendationViewEvent: RecommendationEvent ```
```Objective-C @interface SNRRecommendationViewEvent : SNRRecommendationEvent ```
**Initializers:**
```Swift init(label: String, campaignID: String, campaignHash: String, correlationId: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(NSString *)label campaignID:(NSString *)campaignID campaignHash:(NSString *)campaignHash correlationId:(NSString *)correlationId andParams:(nullable SNRTrackerParams *)params ```
---
```Swift init(label: String, items: [String], campaignID: String, campaignHash: String, correlationId: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(NSString *)label items:(nullable NSArray *)items campaignID:(NSString *)campaignID campaignHash:(NSString *)campaignHash correlationId:(NSString *)correlationId andParams:(nullable SNRTrackerParams *)params ```
**Methods:** This method sets a value for the `items` parameter.
```Swift func setItems(_ items: [String]) ```
```Objective-C - (void)setItems:(NSArray *)items ```
--- --- ### RecommendationSeenEvent Represents a 'client saw a recommendation' event. **Declared In:** Headers/SNRRecommendationSeenEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) [RecommendationEvent](/developers/mobile-sdk/class-reference/ios/events#recommendationevent) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class RecommendationSeenEvent: RecommendationEvent ```
```Objective-C @interface SNRRecommendationSeenEvent : SNRRecommendationEvent ```
**Initializers:**
```Swift init(label: String, productName: String, productId: String, campaignID: String, campaignHash: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label productName:(nonnull NSString *)productName productId:(nonnull NSString *)productId campaignID:(nonnull NSString *)campaignID campaignHash:(nonnull NSString *)campaignHash andParams:(nullable SNRTrackerParams *)params ```
**Methods:** Set a product's category.
```Swift func setCategory(_: String) ```
```Objective-C - (void)setCategory:(nonnull NSString *)category ```
--- Set a product's URL.
```Swift func setURL(_: URL) ```
```Objective-C - (void)setURL:(nonnull NSURL *)url ```
--- --- ### RecommendationClickEvent Represents a 'client clicked a recommendation' event. **Declared In:** Headers/SNRRecommendationSeenEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) [RecommendationEvent](/developers/mobile-sdk/class-reference/ios/events#recommendationevent) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class RecommendationClickEvent: RecommendationEvent ```
```Objective-C @interface SNRRecommendationClickEvent : SNRRecommendationEvent ```
**Initializers:**
```Swift init(label: String, productName: String, productId: String, campaignID: String, campaignHash: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label productName:(nonnull NSString *)productName productId:(nonnull NSString *)productId campaignID:(nonnull NSString *)campaignID campaignHash:(nonnull NSString *)campaignHash andParams:(nullable SNRTrackerParams *)params ```
**Methods:** Set a product's category.
```Swift func setCategory(_: String) ```
```Objective-C - (void)setCategory:(nonnull NSString *)category ```
--- Set a product's URL.
```Swift func setURL(_: URL) ```
```Objective-C - (void)setURL:(nonnull NSURL *)url ```
--- --- ### VisitedScreenEvent Represents a 'client visited screen' event. This can be used for mobile screen usage tracking. **Declared In:** Headers/SNRVisitedScreenEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class VisitedScreenEvent: Event ```
```Objective-C @interface SNRVisitedScreenEvent : SNREvent ```
**Initializers:**
```Swift init(label: String) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label ```
---
```Swift init(label: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andParams:(nullable SNRTrackerParams *)params ```
--- --- ### HitTimerEvent Represents a 'client hit timer' event. This could be used for profiling or activity time monitoring - you can send a `HitTimerEvent` when a client starts doing something and send it once again when they finish, but this time with the different time signature. Then you can use our analytics engine to measure, for example, average activity time. **Declared In:** Headers/SNRHitTimerEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class HitTimerEvent: Event ```
```Objective-C @interface SNRHitTimerEvent : SNREvent ```
**Initializers:**
```Swift init(label: String) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label ```
---
```Swift init(label: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andParams:(nullable SNRTrackerParams *)params ```
--- --- ### SearchedEvent Represents a 'client searched' event. **Declared In:** Headers/SNRSearchedEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class SearchedEvent: Event ```
```Objective-C @interface SNRSearchedEvent : SNREvent ```
**Initializers:**
```Swift init(label: String) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label ```
---
```Swift init(label: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andParams:(nullable SNRTrackerParams *)params ```
--- --- ### SharedEvent Represents a 'client shared' event. **Declared In:** Headers/SNRSharedEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class SharedEvent: Event ```
```Objective-C @interface SNRSharedEvent : SNREvent ```
**Initializers:**
```Swift init(label: String) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label ```
---
```Swift init(label: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andParams:(nullable SNRTrackerParams *)params ```
--- --- ### AppearedInLocationEvent Represents a 'client appeared in location' event. **Declared In:** Headers/SNRAppearedInLocationEvent.h **Related To:** [CCLocation](https://developer.apple.com/documentation/corelocation/cllocation) [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class AppearedInLocationEvent: Event ```
```Objective-C @interface SNRAppearedInLocationEvent : SNREvent ```
**Initializers:**
```Swift init(label: String, location: CCLocation) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andLocation:(nonnull CLLocation *)location ```
---
```Swift init(label: String, location: CCLocation, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andLocation:(nonnull CLLocation *)location andParams:(nullable SNRTrackerParams *)params ```
--- --- ### CrashEvent Represents an 'application crashed' event. **Declared In:** Headers/SNRCrashEvent.h **Related To:** [TrackerParams](/developers/mobile-sdk/class-reference/ios/events#trackerparams) [TrackerParamsBuilder](/developers/mobile-sdk/class-reference/ios/events#trackerparamsbuilder) **Inherits From:** [Event](/developers/mobile-sdk/class-reference/ios/events#event) **Conforms To:** [NSCopying](https://developer.apple.com/documentation/foundation/nscopying) **Declaration:**
```Swift class CrashEvent: Event ```
```Objective-C @interface SNRCrashEvent : SNREvent ```
**Initializers:**
```Swift init(label: String) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label ```

```Swift init(label: String, params: TrackerParams?) ```
```Objective-C - (instancetype)initWithLabel:(nonnull NSString *)label andParams:(nullable SNRTrackerParams *)params ```
**Methods:** This method sets the exception's `name` parameter.
```Swift func setExceptionName(_: String) ```
```Objective-C - (void)setExceptionName:(nonnull NSString *)exceptionName ```
--- This method sets the exception's `reason` parameter.
```Swift func setExceptionReason(_: String) ```
```Objective-C - (void)setExceptionReason:(nonnull NSString *)exceptionReason ```
--- This method sets the exception's `stacktrace` parameter.
```Swift func setExceptionStacktrace(_: String) ```
```Objective-C - (void)setExceptionStacktrace:(nonnull NSString *)exceptionStacktrace ```
### Events ### Event Class model for events. **Declared In:** `com.synerise.sdk.event.Event` **Declaration:**
```Java public abstract class Event implements Serializable ```
```Kotlin abstract class Event : Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **eventTime** | Date | no | - | Event time | | **type** | String | no | - | Event type | | **action** | String | no | - | Event action | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **clientParams** | HashMap | no | - | Profile parameters | | **params** | HashMap | no | - | Event params |
All properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves the value of the `label` parameter.
public String getLabel()
--- This method retrieves the value of the `action` parameter.
public String getAction()
--- This method retrieves the values of the `clientParams` object.
public HashMap<String, Object> getClientParams()
--- This method retrieves the value of the `eventTime` parameter.
public Date getEventTime()
--- This method retrieves the value of the `type` parameter.
public String getType()
--- This method retrieves the values of the `eventParams` object.
public HashMap<String, Object> getParams()
--- --- --- ### CustomEvent
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
Class model for _custom_ event. **Declared In:** `com.synerise.sdk.event.model.CustomEvent` **Declaration:**
```Java public class CustomEvent extends Event ```
```Kotlin class CustomEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **action** | String | no | - | Event action | | **params** | TrackerParams | yes | - | Event tracker parameters | **Initializers:** The following constructors are available:
public CustomEvent(@NonNull String action, @NonNull String label)
public CustomEvent(@NonNull String action, @NonNull String label, @Nullable TrackerParams params)
public CustomEvent(@NonNull String type, @NonNull String action, @NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### AppStartedEvent Class model for the application started event. **Declared In:** `com.synerise.sdk.event.model.interaction.AppStartedEvent` **Declaration:**
```Java public class AppStartedEvent extends Event ```
```Kotlin class AppStartedEvent : Event ```
This event will be sent every time an application is started.
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hub. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker parameters | #### Parameters tracked | Parameter | Description | | --- | --- | | **currentSDKVersion** | Current SDK version | | **lastSDKVersion** | Last SDK version | | **sdkVersionCode** | Current SDK version code | | **applicationName** | Application name | | **version** | Application version | | **appVersionCode** | Application version code | | **deviceId** | Device ID. Can be null | | **deviceModel** | Device model | | **deviceManufacturer** | Device manufacturer | | **deviceResolution** | Device resolution | | **deviceType** | Device type | | **os** | OS type | | **osVersion** | OS version | | **osLanguage** | System language | | **systemPushConsent** | System push agreement | | **networkType** | Network type | | **origin** | Origin of SDK | | **networkCountry** | Country of network | | **cellType** | Cell type | | **cellCarrier** | Cell carrier | | **cellCountry** | Cell country | | **cellRoaming** | Cell roaming | **Initializers:** The following constructors are available:
public AppStartedEvent(@NonNull String label)
public AppStartedEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### AutoTrackingEvent Class model for _autotracking_ events. **Declared In:** `com.synerise.sdk.event.model.interaction.AutoTrackingEvent` **Declaration:**
```Java public class AutoTrackingEvent extends Event ```
```Kotlin class AutoTrackingEvent : Event ```
This event is sent only by the Synerise SDK. Sending this event in your application on your own is **not recommended**.
**Properties:** There are no public properties.
The `screen.interaction` and `screen.view` events are sent by the [auto-tracking module](/developers/mobile-sdk/event-tracking#events-tracked-automatically).
**Initializers:** There are no public constructors. **Methods:** There are no methods. --- --- ### ViewedPushEvent Class model for the `push.view` event. **Declared In:** `com.synerise.sdk.event.model.push.ViewedPushEvent` **Declaration:**
```Java public class ViewedPushEvent extends Event ```
```Kotlin class ViewedPushEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker parameters | **Initializers:** The following constructors are available:
public ViewedPushEvent(@NonNull String label)
public ViewedPushEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### ClickedPushEvent Class model for the `push.click` event. **Declared In:** `com.synerise.sdk.event.model.push.ClickedPushEvent` **Declaration:**
```Java public class ClickedPushEvent extends Event ```
```Kotlin class ClickedPushEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hub. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker parameters | **Initializers:** The following constructors are available:
public ClickedPushEvent(@NonNull String label)
public ClickedPushEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### CancelledPushEvent Class model for the cancel push event generated. **Declared In:** `com.synerise.sdk.event.model.push.CancelledPushEvent` **Declaration:**
```Java public class CancelledPushEvent extends Event ```
```Kotlin class CancelledPushEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hub. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker parameters | **Initializers:** The following constructors are available:
public CancelledPushEvent(@NonNull String label)
public CancelledPushEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### CartEvent Class model for the events related to a cart. **Declared In:** `com.synerise.sdk.event.model.products.cart.CartEvent` **Declaration:**
```Java public abstract class CartEvent extends Event ```
```Kotlin abstract class CartEvent : Event ```
#### Inheriting classes [AddedToCartEvent](/developers/mobile-sdk/class-reference/ios/events#productaddedtocartevent) [RemovedFromCartEvent](/developers/mobile-sdk/class-reference/ios/events#productremovedfromcartevent) **Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **type** | String | no | - | Event type | | **sku** | String | no | - | SKU of the item | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hub. It isn't shown on a Profile card. | | **finalPrice** | `UnitPrice` | no | - | Final price of the item | | **quantity** | int | no | - | Quantity of the item | | **params** | TrackerParams | yes | - | Event tracker parameters |
The following keys: `sku`, `name`, `category`, `categories`, `offline`, `regularUnitPrice`, `discountedUnitPrice`, `finalUnitPrice`, `url`, `producer`, `quantity` are reserved by Synerise for the `params` object.
**Initializers:**
CartEvent(@NonNull String type, @NonNull String label, @NonNull String sku, @NonNull UnitPrice finalPrice, int quantity,
              @Nullable TrackerParams params)
**Methods:** This method sets a value for the `name` parameter.
public void setName(String name)
--- This method sets a value for the `category` parameter.
public void setCategory(String category)
--- This method sets values for the `categories` parameter.
public void setCategories(List<String> categories)
--- This method sets a value for the `offline` parameter.
public void setOffline(boolean offline)
--- This method sets the value of the `regularPrice` parameter.
public void setRegularPrice(UnitPrice regularPrice)
--- This method sets the value of the `discountedPrice` parameter.
public void setDiscountedPrice(UnitPrice discountedPrice)
--- This method sets the value of the `url` parameter.
public void setUrl(String url)
--- This method sets the value of the `producer` parameter (producer can signify a brand of the item).
public void setProducer(String producer)
--- --- --- ### AddedToCartEvent Class model for _add to cart_ event. **Declared In:** `com.synerise.sdk.event.model.products.cart.AddedToCartEvent` **Declaration:**
```Java public class AddedToCartEvent extends CartEvent ```
```Kotlin class AddedToCartEvent : CartEvent ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **type** | String | no | - | Event type | | **sku** | String | no | - | SKU of the product | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **finalPrice** | UnitPrice | no | - | Final price of the product | | **quantity** | int | no | - | Quantity of the product | | **params** | TrackerParams | yes | - | Event tracker params |
The `"sku"`, `"name"`, `"category"`, `"categories"`, `"offline"` , `"regularUnitPrice"`, `"discountedUnitPrice"`, `"finalUnitPrice"`, `"url"`, `"producer"` , `"quantity"` keys are reserved by Synerise in params.
**Initializers:** The following constructors are available:
public AddedToCartEvent(@NonNull String label, @NonNull String sku, @NonNull UnitPrice finalPrice, int quantity)
public AddedToCartEvent(@NonNull String label, @NonNull String sku, @NonNull UnitPrice finalPrice, int quantity,
                            @Nullable TrackerParams params)
**Methods:** This method defines the value of the `name` parameter.
public void setName(String name)
--- This method defines the value of the `category` parameter.
public void setCategory(String category)
--- This method defines the values of the `categories` parameter.
public void setCategories(List<String> categories)
--- This method defines the value of the `offline` parameter. The offline parameter describes whether an event occurred outside website, for example in a cash register.
public void setOffline(boolean offline)
--- This method defines the value of the `regularPrice` parameter.
public void setRegularPrice(UnitPrice regularPrice)
--- This method defines the value of the `discountedPrice` parameter.
public void setDiscountedPrice(UnitPrice discountedPrice)
--- This method defines the value of the `url` parameter.
public void setUrl(String url)
--- This method defines the value of the `producer` parameter. A producer is a manufacturer of the item.
public void setProducer(String producer)
--- --- --- ### RemovedFromCartEvent Class model for _remove from cart_ event. **Declared In:** `com.synerise.sdk.event.model.products.cart.RemovedFromCartEvent` **Declaration:**
```Java public class RemovedFromCartEvent extends CartEvent ```
```Kotlin class RemovedFromCartEvent : CartEvent ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **type** | String | no | - | Event type | | **sku** | String | no | - | SKU of the product | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **finalPrice** | `UnitPrice` | no | - | Final price of the product | | **quantity** | int | no | - | Quantity of the product | | **params** | TrackerParams | yes | - | Event tracker params |
The keys `"sku"`, `"name"`, `"category"`, `"categories"`, `"offline"` , `"regularUnitPrice"`, `"discountedUnitPrice"`, `"finalUnitPrice"`, `"url"`, `"producer"` , `"quantity"` are reserved by Synerise in params.
**Initializers:** The following constructors are available:
public RemovedFromCartEvent(@NonNull String label, @NonNull String sku, @NonNull UnitPrice finalPrice, int quantity)
public RemovedFromCartEvent(@NonNull String label, @NonNull String sku, @NonNull UnitPrice finalPrice, int quantity,
                            @Nullable TrackerParams params)
**Methods:** This method defines the value of the `name` parameter.
public void setName(String name)
--- This method defines the value of the `category` parameter.
public void setCategory(String category)
--- This method defines the values of the `categories` parameter.
public void setCategories(List<String> categories)
--- This method defines the value of the `offline` parameter. The offline parameter describes whether an event occurred outside website, for example in a cash register.
public void setOffline(boolean offline)
--- This method defines the value of the `regularPrice` parameter.
public void setRegularPrice(UnitPrice regularPrice)
--- This method defines the value of the `discountedPrice` parameter.
public void setDiscountedPrice(UnitPrice discountedPrice)
--- This method defines the value of the `url` parameter.
public void setUrl(String url)
--- This method defines the value of the `producer` parameter. A producer is a manufacturer of the item.
public void setProducer(String producer)
--- --- --- ### ProductEvent Class model for _product_ events. **Declared In:** `com.synerise.sdk.event.model.ai.ProductEvent` **Declaration:**
```Java public class ProductEvent extends Event ```
```Kotlin class ProductEvent : Event ```
#### Inheriting classes ProductViewEvent **Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **name** | String | no | - | Product name | | **type** | String | no | - | Event type | | **productId** | String | no | - | Product ID | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params |
The `"productId"`, `"name"`, `"category"`, `"url"` keys are reserved by Synerise in params.
**Initializers:**
public ProductEvent(@NonNull String type, @NonNull String label, @NonNull String productId, @NonNull String name,
                        @Nullable TrackerParams params)
**Methods:** This method defines the value of the `category` parameter.
public void setCategory(String category)
--- This method defines the value of the `url` parameter.
public void setUrl(String url)
--- --- --- ### ProductViewEvent Class model for _the product view_ event. **Declared In:** `com.synerise.sdk.event.model.ai.ProductViewEvent` **Declaration:**
```Java public class ProductViewEvent extends ProductEvent ```
```Kotlin class ProductViewEvent : ProductEvent ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **name** | String | no | - | Product name | | **productId** | String | no | - | Product ID | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params |
The `"productId"`, `"name"`, `"category"`, `"url"` keys are reserved by Synerise in params.
**Initializers:** The following constructors are available:
public ProductViewEvent(@NonNull String label, @NonNull String productId, @NonNull String name)
public ProductViewEvent(@NonNull String label, @NonNull String productId, @NonNull String name,
                            @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### AddedToFavoritesEvent Class model for _add to favourites_ event. **Declared In:** `com.synerise.sdk.event.model.products.AddedToFavoritesEvent` **Declaration:**
```Java public class AddedToFavoritesEvent extends Event ```
```Kotlin class AddedToFavoritesEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public AddedToFavoritesEvent(@NonNull String label)
public AddedToFavoritesEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### LoggedInEvent Class model for _Log in_ event. **Declared In:** `com.synerise.sdk.event.model.session.LoggedInEvent` **Declaration:**
```Java public class LoggedInEvent extends Event ```
```Kotlin class LoggedInEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public LoggedInEvent(@NonNull String label)
public LoggedInEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### LoggedOutEvent Class model for _Log out_ event. **Declared In:** `com.synerise.sdk.event.model.session.LoggedOutEvent` **Declaration:**
```Java public class LoggedOutEvent extends Event ```
```Kotlin class LoggedOutEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public LoggedOutEvent(@NonNull String label)
public LoggedOutEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### RegisteredEvent Class model for _client register_ event. . **Declared In:** `com.synerise.sdk.event.model.session.RegisteredEvent` **Declaration:**
```Java public class RegisteredEvent extends Event ```
```Kotlin class RegisteredEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public RegisteredEvent(@NonNull String label)
public RegisteredEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### RecommendationEvent Class model for _recommendation_ events. **Declared In:** `com.synerise.sdk.event.model.ai.RecommendationEvent` **Declaration:**
```Java public class RecommendationEvent extends Event ```
```Kotlin class RecommendationEvent : Event ```
#### Inheriting classes RecommendationClickEvent RecommendationSeenEvent **Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **name** | String | no | - | Product name | | **type** | String | no | - | Event type | | **productId** | String | no | - | Product ID | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **campaignId** | String | no | - | Recommendation campaign ID | | **campaignHash** | String | no | - | Recommendation campaign hash | | **params** | TrackerParams | yes | - | Event tracker params |
The `"productId"`, `"name"`, `"category"`, `"url"`, `"campaignId"` , `"campaignHash"` keys are reserved by Synerise in params.
**Initializers:**
public RecommendationEvent(@NonNull String type, @NonNull String label, @NonNull String productId, @NonNull String name,
                               @NonNull String campaignId, @NonNull String campaignHash,
                               @Nullable TrackerParams params)
**Methods:** This method defines the value of the `category` parameter.
public void setCategory(String category)
--- This method defines the value of the `url` parameter.
public void setUrl(String url)
--- --- --- ### RecommendationViewEvent Class model for _recommendation_ events. **Declared In:** `com.synerise.sdk.event.model.ai.RecommendationViewEvent` **Declaration:**
```Java public class RecommendationViewEvent extends Event ```
```Kotlin class RecommendationViewEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **productId** | String | no | - | Product ID. If this parameter is used, it is translated into a single-item `items` list automatically. If `items` is used, this parameter should be omitted. | | **items** | `List` | no | - | List of product IDs. If `productId` is used to define a single item in the event, this parameter should be omitted. | | **correlationId** | String | no | - | Correlation ID of the recommendation | | **campaignId** | String | no | - | Campaign ID | | **campaignHash** | String | no | - | Campaign hash |
The `"items"`, `"correlationId"`, `"category"`, `"url"`, `"campaignId"` , `"campaignHash"` keys are reserved by Synerise in params.
**Initializers:**
public RecommendationViewEvent(@NonNull String productId, @NonNull String correlationId,
                                   @NonNull String campaignId, @NonNull String campaignHash)

public RecommendationViewEvent(@NonNull String label, @NonNull String productId, @NonNull String correlationId,
                                   @NonNull String campaignId, @NonNull String campaignHash, @Nullable TrackerParams params)
    
public RecommendationViewEvent(@NonNull List<String> items, @NonNull String correlationId,
                                   @NonNull String campaignId, @NonNull String campaignHash)

public RecommendationViewEvent(@NonNull String label, @NonNull List<String> items, @NonNull String correlationId,
                                   @NonNull String campaignId, @NonNull String campaignHash, @Nullable TrackerParams params)
**Methods:** This method defines the value of the `category` parameter.
public void setCategory(String category)
--- This method defines the value of the `url` parameter.
public void setUrl(String url)
--- --- --- ### RecommendationSeenEvent Class model for _recommendation seen_ event. **Declared In:** `com.synerise.sdk.event.model.ai.RecommendationSeenEvent` **Declaration:**
```Java public class RecommendationSeenEvent extends RecommendationEvent ```
```Kotlin class RecommendationSeenEvent : RecommendationEvent ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **name** | String | no | - | Product name | | **productId** | String | no | - | Product ID | | **campaignId** | String | no | - | Recommendation campaign ID | | **campaignHash** | String | no | - | Recommendation campaign hash | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params |
The `"productId"`, `"name"`, `"category"`, `"url"`, `"campaignId"` , `"campaignHash"` keys are reserved by Synerise in params.
**Initializers:** The following constructors are available:
public RecommendationSeenEvent(@NonNull String label, @NonNull String productId, @NonNull String name,
                                   @NonNull String campaignId, @NonNull String campaignHash)
public RecommendationSeenEvent(@NonNull String label, @NonNull String productId, @NonNull String name,
                                   @NonNull String campaignId, @NonNull String campaignHash, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### RecommendationClickEvent Class model for _recommendation click_ event. **Declared In:** `com.synerise.sdk.event.model.ai.RecommendationClickEvent` **Declaration:**
```Java public class RecommendationClickEvent extends RecommendationEvent ```
```Kotlin class RecommendationClickEvent : RecommendationEvent ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **name** | String | no | - | Product name | | **productId** | String | no | - | Product ID | | **campaignId** | String | no | - | Recommendation campaign ID | | **campaignHash** | String | no | - | Recommendation campaign hash | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params |
The `"productId"`, `"name"`, `"category"`, `"url"`, `"campaignId"` , `"campaignHash"` keys are reserved by Synerise in params.
**Initializers:** The following constructors are available:
public RecommendationClickEvent(@NonNull String label, @NonNull String productId, @NonNull String name,
                                    @NonNull String campaignId, @NonNull String campaignHash)
public RecommendationClickEvent(@NonNull String label, @NonNull String productId, @NonNull String name,
                                    @NonNull String campaignId, @NonNull String campaignHash, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### VisitedScreenEvent Class model for _visited screen_ event. **Declared In:** `com.synerise.sdk.event.model.interaction.VisitedScreenEvent` **Declaration:**
```Java public class VisitedScreenEvent extends Event ```
```Kotlin class VisitedScreenEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public VisitedScreenEvent(@NonNull String label)
public VisitedScreenEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### HitTimerEvent Class model for _hit timer_ event. Record a "customer hit timer" event. This could be used for profiling or activity time monitoring - you can send "hit timer" when your customer starts doing something and send it once again when they finish, but this time with a different time signature. Then you can use [Decision Hub](/docs/analytics) to measure, for example, average activity time. **Declared In:** `com.synerise.sdk.event.model.interaction.HitTimerEvent` **Declaration:**
```Java public class HitTimerEvent extends Event ```
```Kotlin class HitTimerEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public HitTimerEvent(@NonNull String label)
public HitTimerEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### SearchedEvent Class model for _client searched_ event. **Declared In:** `com.synerise.sdk.event.model.interaction.SearchedEvent` **Declaration:**
```Java public class SearchedEvent extends Event ```
```Kotlin class SearchedEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public SearchedEvent(@NonNull String label)
public SearchedEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### SharedEvent Class model for _client shared_ event. **Declared In:** `com.synerise.sdk.event.model.interaction.SharedEvent` **Declaration:**
```Java public class SharedEvent extends Event ```
```Kotlin class SharedEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** The following constructors are available:
public SharedEvent(@NonNull String label)
public SharedEvent(@NonNull String label, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### AppearedInLocationEvent Class model for _appeared in location_ event. **Declared In:** `com.synerise.sdk.event.model.interaction.AppearedInLocationEvent` **Declaration:**
```Java public class AppearedInLocationEvent extends Event ```
```Kotlin class AppearedInLocationEvent : Event ```
This event will be transformed into `client.location` in the database.
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hub. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | | **lon** | Double | no | - | Longitude | | **lat** | Double | no | - | Latitude |
The `"lat"` and `"lon"` keys are reserved by Synerise in params.
**Initializers:** The following constructors are available:
public AppearedInLocationEvent(@NonNull String label, double lat, double lon)
public AppearedInLocationEvent(@NonNull String label, double lat, double lon, @Nullable TrackerParams params)
**Methods:** There are no methods. --- --- ### CrashEvent Class model for _crash_ event. **Declared In:** `com.synerise.sdk.event.model.crash.CrashEvent` **Declaration:**
```Java public class CrashEvent extends Event ```
```Kotlin class CrashEvent : Event ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **label** | String | no | - | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hub. It isn't shown on a Profile card. | | **params** | TrackerParams | yes | - | Event tracker params | **Initializers:** There is a constructor.
public CrashEvent(@NonNull String label, @NonNull TrackerParams params)
**Methods:** There are no methods. ### Customer account management --- ## Get customer account information --- This method gets a customer’s account information. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientAccountInformation](/developers/mobile-sdk/class-reference/flutter/client#clientaccountinformation) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> getAccount({required void Function(ClientAccountInformation) onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function([ClientAccountInformation](/developers/mobile-sdk/class-reference/flutter/client#clientaccountinformation) clientAccountInformation) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.getAccount(onSuccess: (ClientAccountInformation result) {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<ClientAccountInformation> getAccount() async
**Return Value:** [ClientAccountInformation](/developers/mobile-sdk/class-reference/flutter/client#clientaccountinformation) **Example:**
final ClientAccountInformation clientAccountInformation = await Synerise.client.getAccount().catchError((error)
## Update customer account basic information --- This method updates a customer’s account’s basic information (without identification data: uuid, customId, email). This method requires the context object with the customer’s account information. Omitted fields are not modified. This method does not require customer authentication and can be used by anonymous profiles. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.22.0 | 5.21.0 | 0.24.0 | 1.4.0 |
The API key must have the `API_BASIC_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientAccountUpdateBasicInformationContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountupdatebasicinformationcontext) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client) **Declaration:**
Future<void> updateAccountBasicInformation(ClientAccountUpdateBasicInformationContext context,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountUpdateBasicInformationContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountupdatebasicinformationcontext) | yes | - | Object with customer’s first name, phone, and other optional data | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
ClientAccountUpdateBasicInformationContext context = ClientAccountUpdateBasicInformationContext(
        email: email,
        password: password,
        firstName: firstName,
        lastName: lastName,
        sex: ClientSex.getClientSexFromString(sex));

    await Synerise.client.updateAccountBasicInformation(clientAccountUpdateContext, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
## Update customer account information --- This method updates a customer’s account information. This method requires the context object with the customer’s account information. Omitted fields are not modified. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientAccountUpdateContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountupdatecontext) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> updateAccount(ClientAccountUpdateContext context,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountUpdateContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountupdatecontext) | yes | - | Object with customer's email, password, and other optional data | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
ClientAccountUpdateContext clientAccountUpdateContext = ClientAccountUpdateContext(
        email: email,
        password: password,
        firstName: firstName,
        lastName: lastName,
        sex: ClientSex.getClientSexFromString(sex));

    await Synerise.client.updateAccount(clientAccountUpdateContext, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> updateAccount(ClientAccountUpdateContext context) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountUpdateContext](/developers/mobile-sdk/class-reference/flutter/client#clientaccountupdatecontext) | yes | - | Object with customer's email, password, and other optional data | **Return Value:** No value is returned. **Example:**
ClientAccountUpdateContext clientAccountUpdateContext = ClientAccountUpdateContext(
        email: email,
        password: password,
        firstName: firstName,
        lastName: lastName,
        sex: ClientSex.getClientSexFromString(sex));

    await Synerise.client.updateAccount(clientAccountUpdateContext).catchError((error) {
      //onError handling
    });
## Change customer's account password --- This method changes a customer’s password. This method requires customer authentication.
Returns the HTTP 403 status code if the provided old password is invalid.
The API key must have the `SAUTH_CHANGE_PASSWORD_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> changePassword(String oldPassword, String newPassword,
    {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **oldPassword** | String | yes | - | Customer’s old password | | **newPassword** | String | yes | - | Customer’s new password | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.changePassword(oldPassword, newPassword, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> changePassword(String oldPassword,  String password) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **newPassword** | String | yes | - | Customer’s new password | | **oldPassword** | String | yes | - | Customer’s old password | **Return Value:** No value is returned. **Example:**
await  Synerise.client.changePassword(oldPassword, password).catchError((error)
## Request password reset for customer account --- This method requests a customer’s password reset with email. The customer will receive a token to the provided email address. That token is then used for the confirmation of password reset. This method requires the customer’s email. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> requestPasswordReset(String email, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s email | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.requestPasswordReset(email, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> requestPasswordReset(String email) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s email | **Return Value:** No value is returned. **Example:**
await  Synerise.client.requestPasswordReset(email).catchError((error)
## Confirm password reset for customer account --- This method confirm a customer’s password reset with the new password and token provided by password reset request. This method requires the customer’s new password and the confirmation token received by e-mail. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> confirmPasswordReset(String password, String token, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **password** | String | yes | - | New password for the customer | | **token** | String | yes | - | Customer's token provided in an email | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmPasswordReset(password, token, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> confirmPasswordReset(String password, String token) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s email | | **token** | String | yes | - | Customer's token provided in an email | **Return Value:** No value is returned. **Example:**
await  Synerise.client.confirmPasswordReset(email, token).catchError((error)
## Delete customer account --- This method deletes a customer's account. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
Returns the HTTP 403 status code is returned if the provided password is invalid.
The API key must have the `SAUTH_CLIENT_DELETE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Related To:** [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> deleteAccount(String clientAuthFactor, IdentityProvider identityProvider, {String? authId, required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientAuthFactor** | String | yes | - | Customer’s password or token from the identity provider | | **identityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) | yes | - | Customer's identity provider | | **authID** | String | no | null | Optional identifier of authorization | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.deleteAccount(clientAuthFactor, identityProvider, authId, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> deleteAccount(String clientAuthFactor,  IdentityProvider identityProvider,  String? authId) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientAuthFactor** | String | yes | - | Customer’s password or token from the identity provider | | **identityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/flutter/client#clientidentityprovider) | yes | - | Customer's identity provider | | **authID** | String | yes | null | Optional identifier of authorization | **Return Value:** No value is returned. **Example:**
await  Synerise.client.deleteAccount(clientAuthFactor, identityProvider, authId).catchError((error)
## Request email change for customer account --- This method requests a customer's email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token or the password is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> requestEmailChange(String email, String password, {String? externalToken, String? authID, required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's new email | | **password** | String | yes | Customer's password | | **externalToken** | String | no | Customer's token (if OAuth, Facebook, and so on) | | **authID** | String | no | Optional identifier of authorization | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.requestEmailChange(email, password, externalToken: externalToken, authID: authID, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client) **Declaration:**
Future<void> requestEmailChange(String email, String password, [String? externalToken, String? authID]) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's new email | | **password** | String | yes | Customer's password | | **externalToken** | String | no | Customer's token (if OAuth, Facebook, and so on) | | **authID** | String | no | Optional identifier of authorization | **Return Value:** No value is returned. **Example:**
await Synerise.client.requestEmailChange(email, password).catchError((error) {
## Confirm email change for customer account --- This method confirms an email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> confirmEmailChange(String token, bool newsletterAgreement,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **token** | String | yes | Customer's token provided in an email | | **newsletterAgreement** | bool | yes | Agreement for sending newsletters to the provided email | | **onSuccess** | Function() | yes | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmAccountActivationByPin(email, pinCode, onSuccess: () {
    //onSuccess handling
  }, onError: (SyneriseError error) {
    //onError handling
  });
**Declaration:**
Future<void> confirmEmailChange(String token, bool newsletterAgreement) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **token** | String | yes | Customer's token provided in an email | | **newsletterAgreement** | bool | yes | Agreement for sending newsletters to the provided email | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmEmailChange(token, true).catchError((error) {
## Request phone update on customer account --- This method requests a customer's phone update. A confirmation code is sent to the phone number. This method is a global operation and doesn't require customer authentication.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> requestPhoneUpdate(String phone, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **phone** | String | yes | Customer's new phone number | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.requestPhoneUpdate(phone, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> requestPhoneUpdate(String phone) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **phone** | String | yes | Customer's new phone number | **Return Value:** No value is returned. **Example:**
await Synerise.client.requestPhoneUpdate(phone).catchError((error) {
## Confirm phone update on customer account --- This method confirms a phone number update. This action requires the new phone number and confirmation code as parameters. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided UUID does not exist or the password is invalid.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> confirmPhoneUpdate(String phone, String confirmationCode, bool smsAgreement, {required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **phone** | String | yes | New phone number | | **confirmationCode** | String | yes | A confirmation code received by a text message | | **smsAgreement** | bool | yes | Agreement for sending SMS to the provided number | | **onSuccess** | Function() | yes | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmPhoneUpdate(phone, confirmationCode, smsAgreement, onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> confirmPhoneUpdate(String phone, String confirmationCode, bool smsAgreement) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **phone** | String | yes | New phone number | | **confirmationCode** | String | yes | A confirmation code received by a text message | | **smsAgreement** | bool | yes | Agreement for sending SMS to the provided number | **Return Value:** No value is returned. **Example:**
await Synerise.client.confirmPhoneUpdate(phone, confirmationCode, true).catchError((error) {
### React Native # Class reference - React Native ### React Native # Configuring push notifications (React Native) ## Configuring Firebase --- Google Firebase Cloud Messaging is necessary to handle [push notifications](/docs/campaign/Mobile) sent from Synerise. 1. Follow the instructions in [this article](https://firebase.google.com/docs/storage/ios/start). 2. Integrate the Firebase project with Synerise. See [this article](/docs/settings/tool/firebase). ## Setting up - Android {id=setting-up-android} --- ### Requirements {id=android-requirements} After configuring Firebase, add the `google-services.json` file to your project/android/app catalog. ### Firebase Cloud Messaging integration {id=android-firebase-cloud-messaging-integration} 1. Add the google-services dependency to your project's `build.gradle` file.
dependencies {
             ...
             classpath 'com.google.gms:google-services:4.3.3'
             ...
         }
2. Configure the application's `build.gradle` as follows:
dependencies {
         implementation fileTree(dir: "libs", include: ["*.jar"])
         implementation "com.facebook.react:react-native:+"  // from node_modules

         // FCM
         implementation "com.google.firebase:firebase-messaging:20.0.1"
         implementation "com.google.android.gms:play-services-base:17.1.0"
         implementation "com.google.firebase:firebase-core:17.2.1"
         implementation "com.google.firebase:firebase-analytics:17.2.1"
             ...
         }
1. Make sure that at the end of the application gradle file, you add plugin: 'com.google.gms.google-services' 1. In your MainApplication class, include `setPushListener` to listen for the changes of the Firebase token.
```Java @Override public void onCreate() { super.onCreate(); SoLoader.init(this, /* native exopackage */ false); getReactNativeHost().getReactInstanceManager().createReactContextInBackground(); RNNotifications.setPushListener(new OnRegisterPushListener() { @Override public void onRegisterPushRequired() { FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener(instanceIdResult -> { String refreshedToken = instanceIdResult.getToken(); Log.d(TAG, "Refreshed token: " + refreshedToken); RNNotifications.setRegistrationToken(refreshedToken); }); } }); } ```
```Kotlin fun onCreate() { super.onCreate() SoLoader.init(this, /* native exopackage */ false) getReactNativeHost().getReactInstanceManager().createReactContextInBackground() RNNotifications.setPushListener(object:OnRegisterPushListener() { fun onRegisterPushRequired() { FirebaseInstanceId.getInstance().getInstanceId().addOnSuccessListener({ instanceIdResult-> val refreshedToken = instanceIdResult.getToken() Log.d(TAG, "Refreshed token: " + refreshedToken) RNNotifications.setRegistrationToken(refreshedToken) }) } }) } ```
### Receiving push notifications {id=android-receiving-push-notifications} In order to handle Synerise push notifications, you must pass the incoming push payload to the Synerise SDK. 1. Create a class extending `FirebaseMessagingService`:
```Java public class MyFirebaseMessagingService extends FirebaseMessagingService { private static final String TAG = MyFirebaseMessagingService.class.getSimpleName(); @Override public void onMessageReceived(@NonNull RemoteMessage remoteMessage) { super.onMessageReceived(remoteMessage); Map data = remoteMessage.getData(); RNNotifications.onNotificationReceive(data); } @Override public void onNewToken(String refreshedToken) { super.onNewToken(refreshedToken); Log.d(TAG, "Refreshed token: " + refreshedToken); if (refreshedToken != null) { RNNotifications.setRegistrationToken(refreshedToken); } } } ```
```Kotlin class MyFirebaseMessagingService:FirebaseMessagingService() { fun onMessageReceived(@NonNull remoteMessage:RemoteMessage) { super.onMessageReceived(remoteMessage) val data = remoteMessage.getData() RNNotifications.onNotificationReceive(data) } fun onNewToken(refreshedToken:String) { super.onNewToken(refreshedToken) Log.d(TAG, "Refreshed token: " + refreshedToken) if (refreshedToken != null) { RNNotifications.setRegistrationToken(refreshedToken) } } } ```
1. To enable banners, handle the intent when the app starts. You can do it in your `MainActivity` by calling `RNNotifications.onNotificationReceive` in your `onCreate` and `onNewIntent`.
```Java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); RNNotifications.onNotificationReceive(getIntent().getExtras()); } @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); RNNotifications.onNotificationReceive(intent.getExtras()); } ```
```Kotlin protected fun onCreate(savedInstanceState:Bundle) { super.onCreate(savedInstanceState) RNNotifications.onNotificationReceive(getIntent().getExtras()) } fun onNewIntent(intent:Intent) { super.onNewIntent(intent) RNNotifications.onNotificationReceive(intent.getExtras()) } ```
## Setting up - iOS {id=setting-up-ios} --- ### Requirements {id=ios-requirements} Configure handling Push Notifications in your application. See [Apple Notifications](https://developer.apple.com/notifications/). ### Firebase Cloud Messaging integration {id=ios-firebase-cloud-messaging-integration} 1. Import `RNNotifications.h`
```Swift import react-native-synerise-sdk ```
```Objective-C #import ```
2. 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 } } else { let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) application.registerUserNotificationSettings(settings) } application.registerForRemoteNotifications() } // MARK: - MessagingDelegate func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { RNNotifications.didChangeRegistrationToken(fcmToken) } ```
```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) { }]; } else { UIUserNotificationType allNotificationTypes = (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge); UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil]; [[UIApplication sharedApplication] registerUserNotificationSettings:settings]; } [[UIApplication sharedApplication] registerForRemoteNotifications]; } #pragma mark - FIRMessagingDelegate - (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken { [RNNotifications didChangeRegistrationToken:fcmToken]; } ```
Make sure that the Firebase token is always up-to-date. When it changes, use `RNNotifications.didChangeRegistrationToken(registrationToken:)` again.
### Receiving push notifications {id=ios-receiving-push-notifications} The following code shows how to receive push notifications in the `AppDelegate.h` and pass these to the React Native part of the application:
To properly receive notifications, all of these methods must be implemented.
```Swift // iOS 9 // Push Notifications // Silent Push Notifications func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { RNNotifications.didReceiveNotification(userInfo) completionHandler(.noData) } func application(_ application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [AnyHashable : Any], completionHandler: @escaping () -> Void) { RNNotifications.didReceiveNotification(userInfo, actionIdentifier:identifier) completionHandler() } // iOS 10 and above // Push Notifications // MARK: - UNUserNotificationCenterDelegate @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { RNNotifications.didReceiveNotification(response.notification.request.content.userInfo, actionIdentifier:response.actionIdentifier) completionHandler() } @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { RNNotifications.didReceiveNotification(notification.request.content.userInfo) completionHandler(UNNotificationPresentationOptions.init(rawValue: 0)) } ```
```Objective-C // iOS 9 // Push Notifications // Silent Push Notifications - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [RNNotifications didReceiveNotification:userInfo]; completionHandler(UIBackgroundFetchResultNoData); } - (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler { [RNNotifications didReceiveNotification:userInfo actionIdentifier:identifier]; completionHandler(); } // iOS 10 and above // Push Notifications #pragma mark - UNUserNotificationCenterDelegate - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler NS_AVAILABLE_IOS(10) { [RNotifications didReceiveNotification:response.notification.request.content.userInfo actionIdentifier:response.actionIdentifier]; completionHandler(); } - (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler NS_AVAILABLE_IOS(10) { [RNNotifications didReceiveNotification:notification.request.content.userInfo]; completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound); } ```
### Extensions for push notifications {id=ios-extensions-for-push-notifications} #### Notification Service Extension {id=synerise-notification-service-extension-for-ios} **Synerise Notification Service Extension** is an object that adds the notification functionality to the SDK. It implements the following operations: - Decrypting **Simple Push** communication data (if encryption is enabled). - Tracking events from **Simple Push** communication. - 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. **Notification Service Extension** should be implemented in the native part of the application. Follow the instructions in [this article](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension-configuration). #### Rich Media Notification Content Extensions {id=synerise-notification-content-extension-for-ios} **Synerise Rich Media 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). **Synerise Rich Media Notification Content Extensions** should be implemented in the native part of the application. Follow the instructions in [this article](/developers/mobile-sdk/configuring-push-notifications/ios#rich-media-in-push-notifications). ## Set up Firebase FCM token registration for Synerise SDK --- Get Firebase FCM token from the native part of the application so our SDK can receive the Firebase token that is required to deliver push notifications from Synerise. Make sure that the Firebase FCM token is always up-to-date by implementing the [onRegistrationRequired()](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener) method.
```JavaScript Synerise.Notifications.setListener({ onRegistrationToken: function(token) { Synerise.Notifications.registerForNotifications(token, true, function() { // success }, function(error) { // failure }); }, onRegistrationRequired: function() { let registrationToken = getLastPushRegistrationToken(); let mobilePushAgreement = true; // true or false, should depend on device permissions and customer's agreement in the application Synerise.Notifications.registerForNotifications(registrationToken, mobilePushAgreement, function() { // success }, function(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 [Synerise.Notifications.registerForNotifications(registrationToken:mobilePushAgreement:onSuccess:onError:) method in the method reference](/developers/mobile-sdk/method-reference/react-native/campaigns#register-for-push-notifications).
You must always keep the Firebase token updated. In many cases in the application lifecycle, such as authorization, destroy session, user context change, and so on, the registration needs to be updated. In these situations, the SDK invokes the [onRegistrationRequired()](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener) method (see code snippet above).
## Configure Notification Encryption --- ### Android {id=android-notification-encryption-configuration} See [Configure Notification Encryption](/developers/mobile-sdk/configuring-push-notifications/android#configure-notification-encryption). ### iOS {id=ios-notification-encryption-configuration} See [Synerise Notification Service Extension](#synerise-notification-service-extension-for-ios) and [Configure Notification Encryption](/developers/mobile-sdk/configuring-push-notifications/ios#configure-notification-encryption). ### Application implementation {id=application-notification-encryption-configuration} In the application, you must set `encryption` to `true` in the SDK initializer or in the SDK settings.
```JavaScript // The first way // WARNING: This option must be configured before Synerise SDK is initialized! Synerise.Settings.notifications.encryption = true; // The second way Synerise.Initializer() .withApiKey('XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX') .withBaseUrl(null) .withDebugModeEnabled(true) .withCrashHandlingEnabled(true) .withSettings({ notifications: { enabled: true, encryption: true } //... }) .init() ```
## 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).
### Synerise payload The following code shows how to handle push notifications:
```JavaScript Synerise.Notifications.setListener({ //... onNotification: function(payload, actionIdentifier) { if (Synerise.Notifications.isSyneriseNotification(payload)) { Synerise.Notifications.handleNotification(payload, actionIdentifier); } } //... }); ```
### 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 the notification origin and then handles it.
```JavaScript Synerise.Notifications.setListener({ //... onNotification: function(payload, actionIdentifier) { if (Synerise.Notifications.isSyneriseNotification(payload)) { Synerise.Notifications.handleNotification(payload, actionIdentifier); } else { // Handle other notification in your own way } } //... }); ```
### Encrypted payloads If you handle the Synerise notification, you do not have to do anything. The SDK decrypts Synerise notification's payload: - In [Notification Service Extension](#synerise-notification-service-extension-for-ios) for push notifications - In the SDK, after invoking [`Synerise.Notifications.handleNotification(payload, actionIdentifier)`](/developers/mobile-sdk/method-reference/react-native/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 it: - [`Synerise.Notifications.isNotificationEncrypted(payload)`](/developers/mobile-sdk/method-reference/react-native/campaigns#check-if-push-notification-is-encrypted) - checks if the notification payload is encrypted by Synerise. - [`Synerise.Notifications.decryptNotification(payload)`](/developers/mobile-sdk/method-reference/react-native/campaigns#decrypt-push-notification) - decrypts a notification payload.
```JavaScript Synerise.onReady(function() { //... onNotification: function(payload, actionIdentifier) { if (Synerise.Notifications.isSyneriseNotification(payload)) { let isNotificationEncrypted = Synerise.Notifications.isNotificationEncrypted(payload) var decryptedPayload if (isNotificationEncrypted) { decryptedPayload = Synerise.Notifications.decryptNotification(payload) } else { decryptedPayload = payload } Synerise.Notifications.handleNotification(decryptedPayload, actionIdentifier) } } //... }) }) ```
The `Synerise.Notifications.decryptNotification(payload)` method returns raw data when the payload is not encrypted. If the operation fails, the method returns null.
## 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-react-native) ## Additional in-app alert from push notifications --- The React Native SDK on iOS devices 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
Simple Push campaign with in-app alert
## Limitations compared to native platforms --- Due to platform limitations, not all notification functionalities may work as in native SDKs. ### Customer account management ## Get customer account information --- This method gets a customer’s account information. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_READ` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Related To:** [ClientAccountInformation](/developers/mobile-sdk/class-reference/ios/client#clientaccountinformation) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func getAccount(success: ((ClientAccountInformation) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getAccountWithSuccess:(nonnull void (^)(SNRClientAccountInformation *accountInformation))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **success** | ((ClientAccountInformation) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift Client.getAccount(success: { (clientAccountInformation) in // success }) { (error) in // failure } ```
```Objective-C [SNRClient getAccountWithSuccess:^(SNRClientAccountInformation *accountInformation) { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Get customer's events --- This method retrieves events for an authenticated customer. This method requires customer authentication. **Declared In:** Headers/SNRClient.h **Related To:** [ClientEventsApiQuery](/developers/mobile-sdk/class-reference/ios/client#clienteventsapiquery) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func getEvents(apiQuery: ClientEventsApiQuery, success: (([ClientEventData]) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getEventsWithApiQuery:(nonnull SNRClientEventsApiQuery *)apiQuery success:(nonnull void (^)(NSArray *events))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiQuery** | [ClientEventsApiQuery](/developers/mobile-sdk/class-reference/ios/client#clienteventsapiquery) | yes | - | Object responsible for storing all query parameters | | **success** | (([ClientEventData]) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. ## Update customer account basic information --- This method updates a customer’s account’s basic information (without identification data: uuid, customId, email). This method requires the context object with the customer’s account information. Omitted fields are not modified. This method does not require customer authentication and can be used by anonymous profiles. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.22.0 | 5.21.0 | 0.24.0 | 1.4.0 |
The API key must have the `API_BASIC_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Related To:** [ClientUpdateAccountBasicInformationContext](/developers/mobile-sdk/class-reference/ios/client#clientupdateaccountbasicinformationcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func updateAccountBasicInformation(context: ClientUpdateAccountBasicInformationContext, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)updateAccountBasicInformation:(nonnull SNRClientUpdateAccountBasicInformationContext *)context success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientUpdateAccountBasicInformationContext](/developers/mobile-sdk/class-reference/ios/client#clientupdateaccountbasicinformationcontext) | yes | - | Object with customer's basic information optional data | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. ## Update customer account information --- This method updates a customer’s account information. This method requires the context object with the customer’s account information. Omitted fields are not modified. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Related To:** [ClientUpdateAccountContext](/developers/mobile-sdk/class-reference/ios/client#clientupdateaccountcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func updateAccount(context: ClientUpdateAccountContext, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)updateAccount:(nonnull SNRClientUpdateAccountContext *)context success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientUpdateAccountContext](/developers/mobile-sdk/class-reference/ios/client#clientupdateaccountcontext) | yes | - | Object with customer's email, password, and other optional data | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let agreements: ClientAgreements = ClientAgreements() agreements.email = true agreements.sms = true agreements.push = true agreements.bluetooth = true agreements.rfid = true agreements.wifi = true let context: ClientUpdateAccountContext = ClientUpdateAccountContext() context.email = "hello@synerise.com" context.phone = "123-456-789" context.customId = "CUSTOM_ID" context.uuid = "UUID" context.firstName = "FIRST_NAME" context.lastName = "LAST_NAME" context.displayName = "DISPLAY_NAME" context.sex = .male context.company = "Synerise" context.address = "Lubostroń 1" context.city = "Kraków" context.province = "Małopolskie" context.zipCode = "30-383" context.countryCode = "+48" context.birthDate = "01-01-2019" context.avatarUrl = "http://www.synerise.com" context.agreements = agreements context.attributes = ["attribute1": "value1", "attribute2": "value2"] context.tags = ["tag1", "tag2" "tag3"] Client.updateAccount(context: context, success: { // success }) { (error) in // failure } ```
```Objective-C SNRClientAgreements *agreements = [SNRClientAgreements new]; agreements.email = true; agreements.sms = true; agreements.push = true; agreements.bluetooth = true; agreements.rfid = true; agreements.wifi = true; SNRClientUpdateAccountContext *context = [SNRClientUpdateAccountContext new]; context.email = @"hello@synerise.com" context.phone = @"123-456-789"; context.customId = @"CUSTOM_ID" context.firstName = @"FIRST_NAME"; context.lastName = @"LAST_NAME"; context.displayName = @"DISPLAY_NAME" context.sex = SNRClientSexMale; context.company = @"Synerise"; context.address = @"Lubostroń 1"; context.city = @"Kraków"; context.province = @"Małopolskie"; context.zipCode = @"30-383"; context.countryCode = @"+48"; context.birthDate = @"01-01-2019" context.avatarUrl = @"http://www.synerise.com" context.agreements = agreements; context.attributes = @{@"attribute": @"value"}; context.tags = @[@"tag1", @"tag2" @"tag3"]; [SNRClient updateAccount:context success:^() { // success } failure:^(NSError * _Nonnull error) { // failure }]; ```
## Change customer's account password --- This method changes a customer’s password. This method requires customer authentication.
Returns the HTTP 403 status code if the provided old password is invalid.
The API key must have the `SAUTH_CHANGE_PASSWORD_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func changePassword(password: String, oldPassword: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)changePassword:(nonnull NSString *)password oldPassword:(nonnull NSString *)oldPassword success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **password** | String | yes | - | Customer's new password | | **oldPassword** | String | yes | - | Customer's old password | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let newPassword: String = "NEW_PASSWORD" let oldPassword: String = "OLD_PASSWORD" Client.changePassword(password: newPassword, oldPassword: oldPassword, success: { // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *newPassword = @"NEW_PASSWORD"; NSString *oldPassword = @"OLD_PASSWORD"; [SNRClient changePassword:newPassword oldPassword:oldPassword success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Request password reset for customer account --- This method requests a customer’s password reset with email. The customer will receive a token to the provided email address. That token is then used for the confirmation of password reset. This method requires the customer’s email. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Related To:** [ClientPasswordResetRequestContext](/developers/mobile-sdk/class-reference/ios/client#clientpasswordresetrequestcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func requestPasswordReset(context: ClientPasswordResetRequestContext, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)requestPasswordReset:(nonnull SNRClientPasswordResetRequestContext *)context success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientPasswordResetRequestContext](/developers/mobile-sdk/class-reference/ios/client#clientpasswordresetrequestcontext) | yes | - | Object with the customer's email | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let email: String = "EMAIL" let context: ClientPasswordResetRequestContext = ClientPasswordResetRequestContext(email: email) Client.requestPasswordReset(context: context, success: { // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *email = @"EMAIL"; SNRClientPasswordResetRequestContext *context = [SNRClientPasswordResetRequestContext alloc] initWithEmail:email]; [SNRClient requestPasswordReset:context success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Confirm password reset for customer account --- This method confirm a customer’s password reset with the new password and token provided by password reset request. This method requires the customer’s new password and the confirmation token received by e-mail. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Related To:** [ClientPasswordResetConfirmationContext](/developers/mobile-sdk/class-reference/ios/client#clientpasswordresetconfirmationcontext) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func confirmResetPassword(context: ClientPasswordResetConfirmationContext, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)confirmResetPassword:(nonnull SNRClientPasswordResetConfirmationContext *)context success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientPasswordResetConfirmationContext](/developers/mobile-sdk/class-reference/ios/client#clientpasswordresetconfirmationcontext) | yes | - | Object with customer's password and token | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let password: String = "PASSWORD" let token: String = "TOKEN" let context: ClientPasswordResetConfirmationContext = ClientPasswordResetConfirmationContext(password: password, token: token) Client.confirmResetPassword(context: context, success: { // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *password = @"PASSWORD" NSString *token = @"TOKEN" SNRClientPasswordResetConfirmationContext *context = [[SNRClientPasswordResetConfirmationContext alloc] initWithPassword:password andToken:token]; [SNRClient confirmResetPassword:context success:^() { // success } failure:^(NSError * _Nonnull error) { // failure }]; ```
## Request email change for customer account --- This method requests a customer's email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token or the password is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func requestEmailChange(email: String, password: String, externalToken: AnyObject?, authID: String?, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)requestEmailChange:(nonnull NSString *)email password:(NSString *)password externalToken:(id)externalToken authID:(NSString *)authID success:(nonnull void (^)(void))success failure:(nonnull void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's new email | | **password** | String | yes | - | Customer's password | | **externalToken** | AnyObject | no | - | Customer's token (if OAuth, Facebook, and so on) | | **authID** | String | no | - | Optional identifier of authorization | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. ## Confirm email change for customer account --- This method confirms an email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func confirmEmailChange(token: String, newsletterAgreement: Bool, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)confirmEmailChange:(nonnull NSString *)token newsletterAgreement:(BOOL)newsletterAgreement success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Customer's token provided in an email | | **newsletterAgreement** | Bool | yes | - | Agreement for sending newsletters to the provided email | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let token: String = "TOKEN" Client.confirmEmailChange(token: token, success: { // success }) { (error) in // failure } ```
```Objective-C NSString *token = @"TOKEN"; [SNRClient confirmEmailChange:token newsletterAgreement:YES success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Request phone update on customer account --- This method requests a customer's phone update. A confirmation code is sent to the phone number. This method is a global operation and doesn't require customer authentication.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func requestPhoneUpdate(phone: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)requestPhoneUpdate:(nonnull NSString *)phone success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **phone** | String | yes | - | Customer's new phone number | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let phone: String = "123-456-789" Client.requestPhoneUpdate(phone: phone, success: { // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *phone = @"123-456-789"; [SNRClient requestPhoneUpdate:phone success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Confirm phone update on customer account --- This method confirms a phone number update. This action requires the new phone number and confirmation code as parameters. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided UUID does not exist or the password is invalid.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func confirmPhoneUpdate(phone: String, confirmationCode: String, smsAgreement: Bool, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)confirmPhoneUpdate:(nonnull NSString *)phone confirmationCode:(nonnull NSString *)confirmationCode smsAgreement:(BOOL)smsAgreement success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **phone** | String | yes | - | New phone number | | **confirmationCode** | String | yes | - | A confirmation code received by a text message | | **smsAgreement** | Bool | yes | - | Agreement for sending SMS to the provided number | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift let phone: String = "123-456-789" let confirmationCode: String = "CONFIRMATION_CODE" Client.confirmPhoneUpdate(phone: phone, confirmationCode: confirmationCode, smsAgreement: true, success: { // success }) { (error) in // failure } ```
```Objective-C NSString *phone = @"123-456-789"; NSString *confirmationCode = @"CONFIRMATION_CODE"; [SNRClient confirmPhoneUpdate:phone confirmationCode:confirmationCode smsAgreement:YES success:^() { // success } failure:^(SNRApiError *error) { // failure }]; ```
## Delete customer account by Identity Provider --- This method deletes a customer's account. This method requires customer authentication.
HTTP 403 status code is returned if the provided password or token is invalid.
The API key must have the `SAUTH_CLIENT_DELETE`, `SAUTH_OAUTH_CLIENT_DELETE`, `SAUTH_FACEBOOK_CLIENT_DELETE`, `SAUTH_APPLE_CLIENT_DELETE` permissions from the **Client** group.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func deleteAccount(clientAuthFactor: String, clientIdentityProvider: ClientIdentityProvider, authID: String, success: (() -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)deleteAccount:(nonnull id)clientAuthFactor clientIdentityProvider:(SNRClientIdentityProvider)clientIdentityProvider authID:(nullable NSString *)authID success:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientAuthFactor** | String | yes | - | Customer's token from the identity provider | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/ios/client#clientidentityprovider) | yes | - | Customer's identity provider | | **authID** | String | no | - | Optional identifier of authorization | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. ## Removed methods ### Request email change for customer account by Facebook {#request-email-change-for-customer-account-by-facebook} --- This method requests a customer's email change by Facebook. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Replaced By:** [Request email change for customer account](/developers/mobile-sdk/method-reference/ios/client-account#request-email-change-for-customer-account) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func requestEmailChangeByFacebook(email: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)requestEmailChangeByFacebook:(nonnull NSString *)email success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's new email | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let email: String = "EMAIL" Client.requestEmailChange(email: email, success: { success in // success }) { (error) in // failure } ```
```Objective-C NSString *email = @"EMAIL"; [SNRClient requestEmailChangeByFacebook:email success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Delete customer account {#delete-customer-account} --- This method deletes a customer's account. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
Returns the HTTP 403 status code is returned if the provided password is invalid.
The API key must have the `SAUTH_CLIENT_DELETE` permission from the **Client** group.
**Replaced By:** [Delete customer account by Identity Provider](/developers/mobile-sdk/method-reference/ios/client-account#delete-customer-account-by-identity-provider) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func deleteAccount(password: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) ```
```Objective-C + (void)deleteAccount:(nonnull NSString *)password success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **password** | String | yes | - | Customer's password | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let password: String = "PASSWORD" Client.deleteAccount(password: password, success: { (success) in // success }) { (error) in // failure } ```
```Objective-C NSString *password = "PASSWORD"; [SNRClient deleteAccount:password success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Delete customer account by OAuth {#delete-customer-account-by-oauth} --- This method deletes a customer's account by OAuth. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `SAUTH_CLIENT_DELETE` and `SAUTH_OAUTH_CLIENT_DELETE` permissions from the **Client** group.
**Replaced By:** [Delete customer account by Identity Provider](/developers/mobile-sdk/method-reference/ios/client-account#delete-customer-account-by-identity-provider) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func deleteAccountByOAuth(accessToken: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)deleteAccountByOAuth:(nonnull NSString *)accessToken success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | String | yes | - | OAuth Access Token | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. ### Delete customer account by Facebook {#delete-customer-account-by-facebook} --- This method deletes a customer's account by Facebook. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `SAUTH_CLIENT_DELETE` and `SAUTH_FACEBOOK_CLIENT_DELETE` permissions from the **Client** group.
**Replaced By:** [Delete customer account by Identity Provider](/developers/mobile-sdk/method-reference/ios/client-account#delete-customer-account-by-identity-provider) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func deleteAccountByFacebook(facebookToken: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)deleteAccountByFacebook:(nonnull NSString *)facebookToken success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | String | yes | - | Token from an active Facebook session | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift guard let facebookToken = FBSDKAccessToken.current()?.tokenString else { return } Client.deleteAccountByFacebookToken(facebookToken: facebookToken, success: { (success) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *facebookToken = [FBSDKAccessToken currentAccessToken].tokenString; [SNRClient deleteAccountByFacebook:facebookToken success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Delete customer account by Apple Sign In {#delete-customer-account-by-apple-sign-in} --- This method deletes a customer's account information by Sign In With Apple. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | n/a | n/a | n/a |
The API key must have the `SAUTH_CLIENT_DELETE` and `SAUTH_APPLE_CLIENT_DELETE` permissions from the **Client** group.
**Replaced By:** [Delete customer account by Identity Provider](/developers/mobile-sdk/method-reference/ios/client-account#delete-customer-account-by-identity-provider) **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func deleteAccountByAppleSignIn(identityToken: Data, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)deleteAccountByAppleSignIn:(nonnull NSData *)identityToken success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identityToken** | Data | yes | - | Token from Sign In With Apple session | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. ### Customer account management When a customer registers, they become the owner of their account. They can change their own data and security settings. The requests for self-management do not require parameters that identify the customer. Identity information is encoded in the JSON Web Token used for authorization. ## Retrieving customers' own data Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/getAccountDataGET). A customer can access their own data stored in the database.
curl --location --request \
GET 'https://{SYNERISE_API_BASE_PATH}/v4/my-account/personal-information' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJh...1FG5M'
The response includes all of the customer's data from the database. ## Updating customers' own data Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/updateAccountDataUsingPOST). A customer can update their personal data. When sending the request, include only the fields that you want to update. Sending a null value deletes an attribute (if it's a custom attribute) or sets it to null/default value (if the attribute is Synerise-native). Empty strings are not accepted. The following example request updates the customer's avatar:
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/v4/my-account/personal-information' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJh...JxkM5o' \
--data-raw '{
    "avatarUrl": "https://www.gravatar.com/avatar/21b3b5d704c1a5169d16cef176ad4415?s=100&r=g&d=blank"
}'
## Changing email addresses A customer can change their own email address. **Prerequisites**: [SMS sender integration](/docs/settings/tool/integrating-sms-gateways) must be enabled.
Email address is the primary unique identifier of a recognized/authenticated customer.
1. [Request an email change](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/requestClientEmailChange).
curl --request POST 
     --url https://{SYNERISE_API_BASE_PATH}/sauth/my-account/email-change/request 
     --header 'authorization: Bearer eyJh...JxkM5o' 
     --header 'content-type: application/json' 
     --data '{
         "email":"newemail@synerise.com",
         "password":"strongpassword",
         "uuid":"07243772-008a-42e1-ba37-c3807cebde8f",
         "deviceId":"b3f56868-9667-4843-a8e5-0509456baa9b"
       }'
**Result:** A confirmation token is sent to the customer's phone number. 2. [Confirm email change](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/confirmClientEmailChange). You can also use this request to enable newsletter agreements for the new email.
curl --request POST 
     --url https://{SYNERISE_API_BASE_PATH}/sauth/my-account/email-change/confirmation 
     --header 'authorization: Bearer eyJh...JxkM5o' 
     --header 'content-type: application/json' 
     --data '{
         "token":"string",
         "newsletterAgreement":true
       }'
## Changing phone numbers A customer can change their own phone number. **Prerequisites**: [SMS sender integration](/docs/settings/tool/integrating-sms-gateways) must be enabled. 1. [Request a phone number change](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/RequestClientPhoneNumberChange).
curl --request POST 
     --url https://{SYNERISE_API_BASE_PATH}/v4/my-account/phone-update/request 
     --header 'authorization: Bearer eyJh...JxkM5o' 
     --data '{
         "phone":"555015332"
       }'
**Result:** A confirmation token is sent to the new phone number. 2. Confirm the phone number change. You can also use this request to enable SMS marketing permissions for the new number.
curl --request POST 
     --url https://{SYNERISE_API_BASE_PATH}/v4/my-account/phone-update/confirmation 
     --header 'authorization: Bearer eyJh...JxkM5o' 
     --data '{
         "phone":"string",
         "confirmationCode":"string",
         "deviceId":"string",
         "smsAgreement":true
       }'
## Account deletion Customers can delete their own accounts. Depending on the registration method, you need to use one of the following methods: - [Delete RaaS account](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/deleteAccountUsingPOST) - [Delete OAuth account](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/deleteOauthClientUsingPOST) - [Delete Log in with Facebook account](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/DeleteAFacebookClientAccount) - [Delete Sign in with Apple account](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/deleteAppleClientUsingPOST) When an account is deleted, its events (anonymized) are retained in the database. The customer profile stops being visible in the list of profiles and is deleted. ### Customer account management --- ## Get customer account information --- This method gets a customer’s account information. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAccountInformation](/developers/mobile-sdk/class-reference/react-native/client#clientaccountinformation) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public getAccount(onSuccess: (clientAccountInformation: ClientAccountInformation) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.getAccount(function(clientAccountInformation) { //success }, function(error) { //failure }); ```
## Update customer account basic information --- This method updates a customer’s account’s basic information (without identification data: uuid, customId, email). This method requires the context object with the customer’s account information. Omitted fields are not modified. This method does not require customer authentication and can be used by anonymous profiles. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.22.0 | 5.21.0 | 0.24.0 | 1.4.0 |
The API key must have the `API_BASIC_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAccountBasicInformationUpdateContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountupdatebasicinformationcontext) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public updateAccountBasicInformation(context: ClientAccountBasicInformationUpdateContext, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountBasicInformationUpdateContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountupdatebasicinformationcontext) | yes | - | Object with customer’s first name, phone, and other optional data | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let context = new ClientAccountBasicInformationUpdateContext(); context.firstName = 'John'; context.lastName = 'Rise'; context.displayName = 'John Rise'; context.sex = ClientSex.Male; context.phone = '123456789'; context.birthDate = '1989-08-03'; context.company = 'Synerise'; context.address = 'Marszałkowska'; context.city = 'Warszawa'; context.province = 'Mazowieckie'; context.zipCode = '00-000'; context.countryCode = '+48'; context.agreements = new ClientAgreements({ email: true, sms: true, push: true, bluetooth: true, rfid: true, wifi: true }); context.attributes = { ATTRIBUTE_1: 'ATTRIBUTE_1' } Synerise.Client.updateAccountBasicInformation(context, function() { // success }, function(error) { // failure }) ```
## Update customer account information --- This method updates a customer’s account information. This method requires the context object with the customer’s account information. Omitted fields are not modified. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientAccountUpdateContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountupdatecontext) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public updateAccount(context: ClientAccountUpdateContext, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **context** | [ClientAccountUpdateContext](/developers/mobile-sdk/class-reference/react-native/client#clientaccountupdatecontext) | yes | - | Object with customer's email, password, and other optional data | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let context = new ClientAccountUpdateContext(); context.email = 'hello@synerise.com'; context.phone = '123456789'; context.customId = '000111'; context.firstName = 'John'; context.lastName = 'Rise'; context.displayName = 'John Rise'; context.sex = ClientSex.Male; context.birthDate = '1989-08-03'; context.company = 'Synerise'; context.address = 'Marszałkowska'; context.city = 'Warszawa'; context.province = 'Mazowieckie'; context.zipCode = '00-000'; context.countryCode = '+48'; context.agreements = new ClientAgreements({ email: true, sms: true, push: true, bluetooth: true, rfid: true, wifi: true }); context.attributes = { ATTRIBUTE_1: 'ATTRIBUTE_1' } Synerise.Client.updateAccount(context, function() { // success }, function(error) { // failure }) ```
## Change customer's account password --- This method changes a customer’s password. This method requires customer authentication.
Returns the HTTP 403 status code if the provided old password is invalid.
The API key must have the `SAUTH_CHANGE_PASSWORD_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public changePassword(oldPassword: string, newPassword: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **newPassword** | string | yes | - | Customer's new password | | **oldPassword** | string | yes | - | Customer's old password | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let newPassword = "NEW_PASSWORD"; let oldPassword = "OLD_PASSWORD"; Synerise.Client.changePassword(newPassword, oldPassword, function() { // success }, function(error) { // failure }); ```
## Request password reset for customer account --- This method requests a customer’s password reset with email. The customer will receive a token to the provided email address. That token is then used for the confirmation of password reset. This method requires the customer’s email. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public requestPasswordReset(email: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | string | yes | - | Customer's email | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.requestPasswordReset("EMAIL", function() { // success }, function(error) { // failure }); ```
## Confirm password reset for customer account --- This method confirm a customer’s password reset with the new password and token provided by password reset request. This method requires the customer’s new password and the confirmation token received by e-mail. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public confirmPasswordReset(password: string, token: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **password** | string | yes | - | Customer's new password | | **token** | string | yes | - | Customer's token provided in an email | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.confirmPasswordReset("PASSWORD", "TOKEN", function() { // success }, function(error) { // failure }); ```
## Request email change for customer account --- This method requests a customer's email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token or the password is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public requestEmailChange(email: string, password: string | null, externalToken: string | null, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | string | yes | - | Customer's new email | | **password** | string | yes | - | Customer's password | | **externalToken** | AnyObject | no | - | Customer's token (if OAuth, Facebook, and so on) | | **authID** | String | no | - | Optional identifier of authorization | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.requestEmailChange("EMAIL", "PASSWORD", function() { // success }, function(error) { // failure }); ```
## Confirm email change for customer account --- This method confirms an email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public confirmEmailChange(token: string, newsletterAgreement: Boolean, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | string | yes | - | Customer's token provided in an email | | **newsletterAgreement** | boolean | yes | - | Agreement for sending newsletters to the provided email | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.confirmEmailChange("TOKEN", true, function() { // success }, function(error) { // failure }); ```
## Request phone update on customer account --- This method requests a customer's phone update. A confirmation code is sent to the phone number. This method is a global operation and doesn't require customer authentication.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public requestPhoneUpdate(phone: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **phone** | string | yes | - | Customer's new phone number | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.requestPhoneUpdate("PHONE", function() { // success }, function(error) { // failure }); ```
## Confirm phone update on customer account --- This method confirms a phone number update. This action requires the new phone number and confirmation code as parameters. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided UUID does not exist or the password is invalid.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public confirmPhoneUpdate(phone: string, confirmationCode: string, smsAgreement: Boolean, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **phone** | string | yes | - | New phone number | | **confirmationCode** | string | yes | - | A confirmation code received by a text message | | **smsAgreement** | boolean | yes | - | Agreement for sending SMS to the provided number | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.confirmPhoneUpdate("PHONE", "CONFIRMATION_CODE", true, function() { // success }, function(error) { // failure }); ```
## Delete customer account by Identity Provider --- This method deletes a customer's account. This method requires customer authentication.
HTTP 403 status code is returned if the provided password or token is invalid.
The API key must have the `SAUTH_CLIENT_DELETE`, `SAUTH_OAUTH_CLIENT_DELETE`, `SAUTH_FACEBOOK_CLIENT_DELETE`, `SAUTH_APPLE_CLIENT_DELETE` permissions from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [ClientIdentityProvider](/developers/mobile-sdk/class-reference/react-native/client#clientidentityprovider) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public deleteAccountByIdentityProvider(clientAuthFactor: string, clientIdentityProvider: ClientIdentityProvider, authID: string | null, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientAuthFactor** | string | yes | - | Token retrieved from provider | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/react-native/client#clientidentityprovider) | yes | - | Provider of your token | | **authID** | string | no | null | Optional identifier of authorization | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. ## Deprecated methods ### Delete customer account --- This method deletes a customer's account. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
Returns the HTTP 403 status code is returned if the provided password is invalid.
The API key must have the `SAUTH_CLIENT_DELETE` permission from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public deleteAccount(password: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **password** | string | yes | - | Customer's password | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let password = "PASSWORD"; Synerise.Client.deleteAccount(password, function(token) { // success }, function(error) { // failure }); ```
### Delete customer account by OAuth --- This method deletes a customer's account by OAuth. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `SAUTH_CLIENT_DELETE` and `SAUTH_OAUTH_CLIENT_DELETE` permissions from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public deleteAccountByOAuth(accessToken: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | string | yes | - | OAuth Access Token | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.deleteAccountByOAuth(accessToken, function(token) { // success }, function(error) { // failure }); ```
### Delete customer account by Facebook --- This method deletes a customer's account by Facebook. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `SAUTH_CLIENT_DELETE` and `SAUTH_FACEBOOK_CLIENT_DELETE` permissions from the **Client** group.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public deleteAccountByFacebook(facebookToken: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | string | yes | - | Facebook Access Token | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.deleteAccountByFacebook(facebookToken, function(token) { // success }, function(error) { // failure }); ```
### React Native # React Native listeners ### Initialization {id=initialization} A listener to handle the SDK lifecycle events.
```JavaScript Synerise.onReady(function() { ... }); Synerise.onError(function(error) { ... }) ```
--- --- ### NotificationsListener {id=notifications-listener} A listener to handle actions from the notifications module.
```JavaScript Synerise.Notifications.setListener({ // The following method is called when Synerise receives a registration token from the native part of application // It is optional function onRegistrationToken: function(token) { ... }, // The following method is called when registration for Push Notifications is needed. // It is optional function onNotification: function(payload) { ... }, // The following method is called when Synerise receives a notification's payload from the native part of application. // It is optional function onRegistrationRequired: function() { ... } }); ```
After invoking **onRegistrationRequired()** function, you must invoke the [Synerise.Notifications.registerForNotifications(registrationToken, mobileAgreement, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/campaigns#register-for-push-notifications) method again.
--- --- ### ClientStateListener {id=client-state-listener} A listener to handle customer's sign-in state changes.
```JavaScript Synerise.Client.setClientStateListener({ // The following method is called when a customer signs in. // It is optional function onClientSignedIn: function() { ... }, // The following method is called when a customer signs out // It is optional function onClientSignedOut: function(reason) { ... } }); ```
--- --- ### InjectorListener {id=injector-listener} A listener to handle URL and deeplink actions from the injector module.
```JavaScript Synerise.Injector.setListener({ // The following method is called when Synerise handles URL action from campaign activities // It is required function onOpenUrl: function(url) { ... }, // The following method is called when Synerise handles deep link action from campaign activities // It is required function onDeepLink: function(deepLink) { ... } }); ```
--- --- ### InjectorInAppMessageListener {id=injector-in-app-message-listener} A listener to handle the states of [in-app messages](/developers/mobile-sdk/campaigns/in-app-message).
```JavaScript Synerise.Injector.setInAppMessageListener({ shouldPresent: function(data) { return true; }, // The following method is called after an in-app message appears onPresent: function (data) { ... }, // The following method is called after an in-app message disappears onHide: function(data) { ... }, // This method is called when a individual context for an in-app message is needed contextIsNeeded: function(data) { return {} }, // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. onOpenUrl: function (data, url) { ... }, // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. onDeepLink: function (data, deepLink) { ... }, // This method is called when the // SRInApp.handleCustomAction(name, params) method is used in an in-app message. onCustomAction: function(data, name, parameters) { } }) ```
--- --- ## InjectorWalkthroughListener {id=injector-walkthrough-listener}
**InjectorWalkthroughListener** was removed in SDK version 1.0.0..
--- --- ## InjectorBannerListener {id=injector-banner-listener}
**InjectorBannerListener** was removed in SDK version 1.0.0..
### Client ### ClientIdentityProvider **Declared In:** lib/enums/client/identity_provider.dart **Declaration:**
enum IdentityProvider {
  synerise('SYNERISE'),
  facebook('FACEBOOK'),
  google('GOOGLE'),
  oauth('OAUTH'),
  apple('APPLE'),
  unknown('UNKNOWN');
  }
--- --- ### ClientAuthContext **Declared In:** lib/model/client/client_auth_context.dart **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) **Declaration:**
class ClientAuthContext
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **authId** | String | yes | null | Optional identifier of authorization | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) | yes | null | Object that stores all agreements of a customer | | **attributes** | HashMap | yes | null | Additional custom attributes of a customer |
**authId** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Initializers:**
ClientAuthContext({this.authId, this.agreements, this.attributes})
**Example:**
```Dart ClientAuthContext clientAuthContext = ClientAuthContext( authId: 'AUTH_ID', agreements: agreements, attributes: attributes ); ```
--- --- ### ClientConditionalAuthContext **Declared In:** lib/model/client/client_conditional_auth_context.dart **Related To:** [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) **Declaration:**
class ClientCondtitionalAuthContext {
**Properties:** Property | Type | Optional | Description | | --- | --- | --- | --- | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) | yes | Object that stores all agreements of a customer | | **attributes** | Map | yes | Additional custom attributes of a customer | **Initializers:**
ClientCondtitionalAuthContext({this.agreements, this.attributes});
--- --- ### ClientAccountInformation Model representating the customer information.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/model/client/client_account_information.dart **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) **Declaration:**
class ClientAccountInformation
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **clientId** | int | no | Customer's ID | | **email** | String | no | Customer's email | | **phone** | String | yes | Customer's phone | | **customId** | String | yes | Customer's custom ID | | **uuid** | String | no | Customer's UUID | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) | no | Customer's sex | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **lastActivityDate** | Date | no | Customer's last activity date | | **avatarUrl** | String | yes | Customer's avatar URL | | **anonymous** | bool | no | Customer's anonymous flag | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) | no | Customer's agreements | | **attributes** | HashMap | yes | Customer's attributes | | **tags** | List | yes | Customer's tags | --- --- ### ClientAccountUpdateBasicInformationContext **Declared In:** lib/model/client/client_account_update_basic_information_context.dart **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) **Declaration:**
class ClientAccountUpdateBasicInformationContext
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) | yes | Customer's sex | | **phone** | String | yes | Customer's phone number | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **avatarUrl** | String | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) | yes | Customer's agreements | | **attributes** | HashMap | yes | Customer's attributes | **Initializers:**
ClientAccountUpdateBasicInformationContext({
  this.firstName,
  this.lastName,
  this.displayName,
  this.sex,
  this.phone,
  this.company,
  this.address,
  this.city,
  this.province,
  this.zipcode,
  this.countrycode,
  this.agreements,
  this.attributes
});
**Example:**
```Dart ClientAccountUpdateBasicInformationContext context = ClientAccountUpdateBasicInformationContext( firstName: firstName, lastName: lastName, sex: sex, phone: phone, company: company, address: address, city: city, province: province, zipcode: zipcode, countrycode: countrycode); ```
--- --- ### ClientAccountUpdateContext **Declared In:** lib/model/client/client_account_update_context.dart **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) **Declaration:**
class ClientAccountUpdateContext
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | | **customId** | String | yes | Customer's custom ID | | **uuid** | String | yes | Customer's UUID | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) | yes | Customer's sex | | **phone** | String | yes | Customer's phone number | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **avatarUrl** | String | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) | yes | Customer's agreements | | **attributes** | HashMap | yes | Customer's attributes | **Initializers:**
ClientAccountUpdateContext({
  this.email,
  this.customId,
  this.uuid,
  this.firstName,
  this.lastName,
  this.sex,
  this.phone,
  this.company,
  this.address,
  this.city,
  this.province,
  this.zipcode,
  this.countrycode,
  this.agreements,
  this.attributes
});
**Example:**
```Dart ClientAccountUpdateContext clientAccountUpdateContext = ClientAccountUpdateContext( email: email, firstName: firstName, lastName: lastName, sex: sex, phone: phone, company: company, address: address, city: city, zipcode: zipcode, countrycode: countrycode, province: province); ```
--- --- ### ClientAccountRegisterContext **Declared In:** lib/model/client/client_account_register_context.dart **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) **Declaration:**
class ClientAccountRegisterContext
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | String | no | Customer's email | | **password** | String | no | Customer's password | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **customId** | String | yes | Customer's custom ID | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) | yes | Customer's sex | | **phone** | String | yes | Customer's phone | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province code | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) | yes | Customer's agreements | | **attributes** | HashMap | yes | Customer's attributes | **Initializers:**
ClientAccountRegisterContext({
  required this.email,
  required this.password,
  this.firstName,
  this.lastName,
  this.sex,
  this.phone,
  this.company,
  this.address,
  this.city,
  this.zipcode,
  this.countrycode,
  this.province,
  this.uuid,
  this.customId,
  this.agreements,
  this.attributes
})
**Example:**
```Dart ClientAccountRegisterContext clientAccountRegisterContext = ClientAccountRegisterContext(email: "EMAIL", password: "PASSWORD"); ```
--- --- ### ClientSimpleAuthenticationData **Declared In:** lib/model/client/client_simple_authentication_data.dart **Related To:** [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) **Declaration:**
class ClientSimpleAuthenticationData
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | String | yes | Customer's email | | **phone** | String | yes | Customer's phone | | **customId** | String | yes | Customer's custom ID | | **uuid** | String | yes | Customer's UUID | | **firstName** | String | yes | Customer's first name | | **lastName** | String | yes | Customer's last name | | **displayName** | String | yes | Customer's display name | | **sex** | [ClientSex](/developers/mobile-sdk/class-reference/flutter/client#clientsex) | yes | Customer's sex | | **company** | String | yes | Customer's company | | **address** | String | yes | Customer's address | | **city** | String | yes | Customer's city | | **province** | String | yes | Customer's province | | **zipCode** | String | yes | Customer's ZIP code | | **countryCode** | String | yes | Customer's country code | | **birthDate** | String | yes | Customer's birthdate | | **avatarUrl** | String | yes | Customer's avatar URL | | **agreements** | [ClientAgreements](/developers/mobile-sdk/class-reference/flutter/client#clientagreements) | yes | Customer's agreements | | **attributes** | Map | yes | Customer's attributes | **Initializers:**
ClientAccountUpdateContext({
  this.email,
  this.password,
  this.firstName,
  this.lastName,
  this.sex,
  this.phone,
  this.company,
  this.address,
  this.city,
  this.zipcode,
  this.countrycode,
  this.province,
  this.uuid,
  this.customId,
  this.agreements,
  this.attributes
});
--- --- ### ClientSex **Declared In:** lib/enums/client/client_sex.dart **Declaration:**
enum ClientSex {
  notSpecified('NOT_SPECIFIED'),
  male('MALE'),
  female('FEMALE'),
  other('OTHER');
}
--- --- ### ClientAgreements **Declared In:** lib/model/client/client_agreements.dart **Declaration:**
class ClientAgreements
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **email** | bool | no | Email agreement | | **sms** | bool | no | SMS agreement | | **push** | bool | no | Push notifications agreement | | **bluetooth** | bool | no | Bluetooth agreement | | **rfid** | bool | no | RFID agreement | | **wifi** | bool | no | WIFI agreement | **Initializers:**
ClientAgreements({this.email, this.sms, this.push, this.bluetooth, this.rfid, this.wifi})
--- --- ### Token **Declared In:** lib/model/client/token.dart **Related To:** [TokenOrigin](/developers/mobile-sdk/class-reference/flutter/client#tokenorigin) **Declaration:**
class Token
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **tokenString** | String | no | Token as a raw string | | **origin** | [TokenOrigin](/developers/mobile-sdk/class-reference/flutter/client#tokenorigin) | no | Token's origin | | **expirationDate** | DateTime | no | Token's expiration time | --- --- ### TokenOrigin **Declared In:** lib/enums/client/token_origin.dart **Declaration:**
enum TokenOrigin {
  synerise('SYNERISE'),
  facebook('FACEBOOK'),
  google('GOOGLE'),
  oauth('OAUTH'),
  apple('APPLE'),
  simpleAuth('SIMPLE_AUTH'),
  anonymous('ANONYMOUS'),
  unknown('UNKNOWN');
}
--- --- ### ClientConditionalAuthResult **Declared In:** lib/model/client/client_conditional_auth_result.dart **Declaration:**
class ClientConditionalAuthResult
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **status** | [ClientConditionalAuthStatus](/developers/mobile-sdk/class-reference/flutter/client#clientconditionalauthstatus) | no | Status of the authentication | | **conditions** | List | yes | Authentication conditions |
All properties are read-only.
--- --- ### ClientConditionalAuthStatus **Declared In:** lib/enums/client/client_conditional_auth_status.dart **Declaration:**
enum ClientConditionalAuthStatus {
  success('SUCCESS'),
  unauthorized('UNAUTHORIZED'),
  activationRequired('ACTIVATION_REQUIRED'),
  registrationRequired('REGISTRATION_REQUIRED'),
  approvalRequired('APPROVAL_REQUIRED'),
  termsAcceptanceRequired('TERMS_ACCEPTANCE_REQUIRED'),
  mfaRequired('MFA_REQUIRED');
  }
**Functions:** Converts from **ClientConditionalAuthStatus** to **String**.
```Dart String getClientConditionalAuthStatusAsString() { ```
--- Converts from **String** to **ClientConditionalAuthStatus**.
```Dart static ClientConditionalAuthStatus? getClientConditionalAuthStatusFromString(String string) { ```
--- --- ### ClientSignOutMode **Declared In:** lib/enums/client/client_sign_out_mode.dart **Declaration:**
enum ClientSignOutMode {
  signOut('SIGN_OUT'),
  signOutWithSessionDestroy('SIGN_OUT_WITH_SESSION_DESTROY');
**Functions:** Converts from **ClientSignOutMode** to **String**.
```Dart String clientSignOutModeAsString() { ```
--- Converts from **String** to **ClientSignOutMode**.
```Dart static ClientSignOutMode? getClientSignOutModeFromString(String string) { ```
### Settings This article describes options that allow you to change some SDK behaviors. It contains all settings you can configure to change some SDK behaviors. The settings are divided into groups: - [General](/developers/mobile-sdk/settings#general) - This group contains options related to the general functioning of mobile SDK. - [Notifications](/developers/mobile-sdk/settings#notifications) - This group contains options related to push notifications. - [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. - [Tracker](/developers/mobile-sdk/settings#tracker) - This group contains options related to tracking the customer activities in a mobile application. - [Injector](/developers/mobile-sdk/settings#injector) - This group contains options related to displaying [campaigns](/docs/campaign/Mobile). ## Pre-initialization settings Some of the pre-initialization settings are optional. If you want to use them, they must be configured before Synerise SDK is initialized, before invoking the following methods: - Synerise.Builder.build() (Android) - [Synerise.initialize(apiKey:)](/developers/mobile-sdk/method-reference/ios/lifecycle#initialization) (iOS) **Pre-initialization settings:** - [Set up App Group Identifier](#set-up-app-group-identifier) (iOS only) - [Set up Keychain Group Identifier](#set-up-keychain-group-identifier) (iOS only) - [Maintaining customer session on different API keys](#maintaining-customer-session-on-different-api-keys) - [Turn on/turn off notification encryption](#turn-onturn-off-notification-encryption) **The rest of the options can be changed dynamically anytime.**
See advanced initialization example with all settings options for: - [Advanced initialization - Android](/developers/mobile-sdk/installation-and-configuration/android#initialization) - [Advanced initialization - iOS](/developers/mobile-sdk/installation-and-configuration/ios#advanced-initialization) - [Advanced initialization - React Native](/developers/mobile-sdk/installation-and-configuration/react-native#advanced-initialization)
## General ### Enable/disable SDK --- This parameter specifies if the SDK is enabled. If the SDK is disabled, it means: - the SDK does not send any events - the SDK does not handle notifications - the SDK does not show in-app messages Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.enabled` | `Boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.enabled` | `Bool` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.sdk.enabled`| `boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.enabled`| `bool` | true |
### Minimum time interval to refresh token --- This parameter sets a time interval (in seconds) counting backwards from the expiration time. Within this time, the authorization token will be automatically refreshed by the SDK. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Method | Type | Default | Minimum | | --- | --- | --- | --- | | `Synerise.settings.sdk.setMinTokenRefreshInterval(value)` | `TimeInterval` | 1800 | 1800 |
| Parameter | Type | Default | Minimum | | --- | --- | --- | --- | | `Synerise.settings.sdk.minTokenRefreshInterval` | `TimeInterval` | 1800 | 1800 |
| Parameter | Type | Default | Minimum | | --- | --- | --- | --- | | `Synerise.Settings.sdk.minTokenRefreshInterval` | `number` | 1800 | 1800 |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.minTokenRefreshInterval`| `double` | 1800 |
### Maintaining customer session on different API keys --- This parameter specifies if a session is destroyed after the Profile API (formerly Client) key changes.
This option must be configured when Synerise SDK is initialized.
Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.shouldDestroySessionOnApiKeyChange` | `Boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.shouldDestroySessionOnApiKeyChange` | `Bool` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.sdk.shouldDestroySessionOnApiKeyChange` | `boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.shouldDestroySessionOnApiKeyChange`| `bool` | true |
This option works only if you change the Profile (formerly Client) API key within one workspace. To change the API key from a different workspace, use the following method: - for Android [Client.changeApiKey](/developers/mobile-sdk/method-reference/android/lifecycle#change-profile-api-key-dynamically) - for iOS [Synerise.changeApiKey](/developers/mobile-sdk/method-reference/ios/lifecycle#change-profile-api-key-dynamically) - for React Native [Synerise.changeApiKey](/developers/mobile-sdk/method-reference/react-native/lifecycle#change-profile-api-key-dynamically) - for Flutter [Synerise.changeApiKey](/developers/mobile-sdk/method-reference/flutter/lifecycle#change-profile-api-key-dynamically)
### Set up App Group Identifier --- This parameter identifies the user default group applications and extensions belong to.
This option must be configured when Synerise SDK is initialized, before invoking the [Synerise.initialize(apiKey:)](/developers/mobile-sdk/method-reference/ios/lifecycle#initialization) method.
Available on: **iOS**, **React Native (iOS)**, **Flutter (iOS)**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.appGroupIdentifier` | `String` | nil |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.sdk.appGroupIdentifier` | `string` | null |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.appGroupIdentifier`| `String` | null |
Synerise SDK requires this parameter to be configured for storing your non-sensitive data and sharing it between your app and extensions. Your App Group must be registered on the [Apple Developer](https://developer.apple.com/) portal. It is recommended to use reverse-domain name style and prefix it with `group.` by default. For example, your App Group can be `group.com.synerise.sdk.sample`. When your App Group is registered, add it as a capability on the [Apple Developer](https://developer.apple.com/) portal in App ID Configuration and in Xcode in the **Signing&Capabilities** tab. Documentation is available at [Apple Developer - App Groups](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_application-groups). Once configured, you need to set it up in the SDK: #### Example
```Swift Synerise.settings.sdk.appGroupIdentifier = "group.com.synerise.sdk.sample" ```
```Objective-C SNRSynerise.settings.sdk.appGroupIdentifier = @"group.com.synerise.sdk.sample"; ```
```JavaScript Synerise.Settings.sdk.appGroupIdentifier = "group.com.synerise.sdk.sample"; ```
```Dart Synerise.settings.sdk.appGroupIdentifier = "group.com.synerise.sdk.sample"; ```
### Set up Keychain Group Identifier --- This parameter identifies the keychain group used by applications, extensions and services that your app belongs to.
This option must be configured when Synerise SDK is initialized, before invoking the [Synerise.initialize(apiKey:)](/developers/mobile-sdk/method-reference/ios/lifecycle#initialization) method.
Available on: **iOS**, **React Native (iOS)**, **Flutter (iOS)**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.keychainGroupIdentifier` | `String` | nil |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.sdk.keychainGroupIdentifier` | `string` | null |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.sdk.keychainGroupIdentifier`| `String` | null |
Synerise SDK requires that parameter to be configured for storing your data safely and sharing it between your app and extensions. Your Keychain Group Identifier is made of: - your Keychain Group - your $(AppIdentifierPrefix), also called Team ID. For example, if your Keychain Group is set to `SharedItems` and your Team ID is `ABC1234DEF`, the complete literal that you should set as Keychain Group Identifier is `ABC1234DEF.SharedItems`. Documentation is available at [Apple Developer - Sharing Access to Keychain Items Among a Collection of Apps](https://developer.apple.com/documentation/security/keychain_services/keychain_items/sharing_access_to_keychain_items_among_a_collection_of_apps). Once configured, you need to set it up in the SDK: #### Example
```Swift Synerise.settings.sdk.keychainGroupIdentifier = "ABC1234DEF.SharedItems" ```
```Objective-C SNRSynerise.settings.sdk.keychainGroupIdentifier = @"ABC1234DEF.SharedItems"; ```
```JavaScript Synerise.Settings.sdk.keychainGroupIdentifier = "ABC1234DEF.SharedItems"; ```
```Dart Synerise.settings.sdk.keychainGroupIdentifier = "ABC1234DEF.SharedItems"; ```
### Localize some strings occurring in the SDK --- This parameter specifies the localization of some strings occurring in the SDK. When this option isn't used, the SDK uses default strings. Available on: **iOS**, **React Native (iOS)**, **Flutter (iOS)**.
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.sdk.localizable` | `[LocalizableStringKey: String]` | nil | 4.14.12 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.Settings.sdk.localizable` | `object` | null | 0.19.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.sdk.localizable` | `Map` | null | 1.0.0 |
We recommend updating the property when you change the language in the Host App.
## Notifications ### Enable/disable notifications --- This parameter specifies if handling notifications by the SDK is enabled. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.enabled` | `Boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.enabled` | `Bool` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.notifications.enabled` | `boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.enabled` | `bool` | true |
### Turn on/turn off notification encryption --- This parameter specifies if encryption for push notifications is enabled.
This option must be configured when Synerise SDK is initialized.
Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Method | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.setEncryption(value)` | `Boolean` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.encryption` | `Bool` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.notifications.encryption` | `boolean` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.encryption` | `bool` | false |
Encryption must be enabled in the [workspace settings](https://app.synerise.com/spa/modules/old-settings/setting/integration), in the Firebase integration section.
The application must be properly configured and implemented for notification encryption: - [Configure Notification Encryption for Android.](/developers/mobile-sdk/configuring-push-notifications/android#configure-notification-encryption) - [Configure Notification Encryption for iOS.](/developers/mobile-sdk/configuring-push-notifications/ios#configure-notification-encryption) - [Configure Notification Encryption for React Native.](/developers/mobile-sdk/configuring-push-notifications/react-native#configure-notification-encryption) - [Configure Notification Encryption for Flutter.](/developers/mobile-sdk/configuring-push-notifications/flutter#configure-notification-encryption)
### Enable/disable notification in-app alerts --- This parameter determines whether the SDK displays an additional alert in the application right after a notification is delivered. If you have your own notification implementation, or you do not want to display alerts with notification content, you should disable in-app notification alerts from the Synerise SDK. Also, read [here](/developers/mobile-sdk/campaigns/simple-push#additional-in-app-alert-when-simple-push-is-received). Available on: **iOS**, **React Native (iOS)**, **Flutter (iOS)**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.disableInAppAlerts` | `Bool` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.notifications.disableInAppAlerts` | `boolean` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.notifications.disableInAppAlerts` | `bool` | false |
## In-app messaging ### Check Global Control Groups when fetching definitions --- This parameter specifies if global control groups should be checked immediately after in-app definitions are fetched. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.checkGlobalControlGroupsOnDefinitionsFetch` | `Boolean` | false | 5.15.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.checkGlobalControlGroupsOnDefinitionsFetch` | `Bool` | false | 4.15.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.Settings.notifications.checkGlobalControlGroupsOnDefinitionsFetch` | `boolean` | false | 0.19.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.checkGlobalControlGroupsOnDefinitionsFetch` | `bool` | false | 0.8.3 |
### Maximum time interval between in-app definition updates --- This parameter sets the maximum interval (in seconds) between automatic [in-app message](/docs/campaign/in-app-messages) definition updates. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Method | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.setMaxDefinitionUpdateIntervalLimit(value)` | `TimeInterval` | 600.0 | 600.0 | 4.7.0 |
| Parameter | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.maxDefinitionUpdateIntervalLimit` | `TimeInterval` | 600.0 | 600.0 | 4.6.0 |
| Parameter | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.Settings.inAppMessaging.maxDefinitionUpdateIntervalLimit` | `number` | 600.0 | 600.0 | 0.12.0 |
| Parameter | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.maxDefinitionUpdateIntervalLimit` | `double` | 600.0 | 600.0 | 0.4.0 |
### Content base URL for in-app message --- This parameter defines the base URL for loading external resources (such as JavaScript files, CSS stylesheets, images, or fonts) within your in-app content. This is particularly useful when resources are hosted on your own server and you have set up **CORS (Cross-Origin Resource Sharing) policies**.
Thanks to the base URL, the app will know where to look for all external resources that are loaded dynamically. This helps avoid specifying full URLs each time a resource is requested and ensures that resources are consistently loaded from the correct location.
Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.contentBaseUrl` | `String` | null | 5.21.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.contentBaseUrl` | `String` | nil | 4.21.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.Settings.inAppMessaging.contentBaseUrl` | `string` | null | 0.24.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.contentBaseUrl` | `String` | null | 1.4.0 |
#### Example You should set `contentBaseUrl` to the root URL of the server hosting your resources. This is especially important when hosting assets such as fonts, images, or scripts from a specific domain or server.
```Swift Synerise.settings.inAppMessaging.contentBaseUrl = "https://www.synerise.com" ```
```Objective-C SNRSynerise.settings.inAppMessaging.contentBaseUrl = @"https://www.synerise.com"; ```
```JavaScript Synerise.Settings.inAppMessaging.contentBaseUrl = "https://www.synerise.com" ```
```Dart Synerise.settings.inAppMessaging.contentBaseUrl = "https://www.synerise.com" ```
### Maximum time for in-app message rendering --- This parameter sets a timeout (in seconds) for in-app message rendering. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.renderingTimeout` | `TimeInterval` | 2.0 | - | 4.7.0 |
| Parameter | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.renderingTimeout` | `TimeInterval` | 5.0 | 1.0 | 4.6.0 |
| Parameter | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.Settings.inAppMessaging.renderingTimeout` | `number` | 2.0 (Android)
5.0 (iOS) | - (Android)
1.0 (iOS) | 0.12.0 |
| Parameter | Type | Default | Minimum | Min. SDK version | | --- | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.renderingTimeout` | `double` | 2.0 (Android)
5.0 (iOS) | - (Android)
1.0 (iOS) | 0.4.0 |
### Enable/disable sending inApp.capping event --- This parameter specifies if the SDK should send the `inApp.capping` event. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.shouldSendInAppCappingEvent` | `Boolean` | true | 5.10.1 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.shouldSendInAppCappingEvent` | `Bool` | true | 4.14.8 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.Settings.inAppMessaging.shouldSendInAppCappingEvent` | `boolean` | true | 0.16.0 |
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.inAppMessaging.shouldSendInAppCappingEvent` | `bool` | true | 0.7.2 |
## Tracker ### Enable/disable declarative tracking --- This parameter specifies if the [declarative tracking](/developers/mobile-sdk/event-tracking#declarative-tracking) feature is enabled. Available on: **Android**, **iOS**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.tracking.enabled` | `Boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.tracking.enabled` | `Bool` | true |
### Enable/disable auto-tracking ---
Autotracking is **NOT** available when building apps with Jetpack Compose (Android) and SwiftUI (iOS).
This parameter specifies if the [auto-tracking feature](/developers/mobile-sdk/event-tracking#auto-tracking) is enabled. Available on: **Android**, **iOS**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoTracking.enabled` | `Boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoTracking.enabled` | `Bool` | true |
### Require/do not require backend time synchronization to send events --- This parameter specifies if events are sent when the server time synchronization has failed. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.isBackendTimeSyncRequired` | `Boolean` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.isBackendTimeSyncRequired` | `Bool` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.tracker.isBackendTimeSyncRequired` | `Bool` | true |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.isBackendTimeSyncRequired` | `bool` | true |
### Minimum number of events in queue --- This parameter sets the minimum number of events in queue required to send the queue. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Method | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.settings.tracker.setMinimumBatchSize(value)` | `Integer` | 10 | 1 | 100 |
| Parameter | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.settings.tracker.minBatchSize` | `Int` | 10 | 1 | 100 |
| Parameter | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.Settings.tracker.minBatchSize` | `number` | 10 | 1 | 100 |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.minBatchSize` | `int` | 10 | 1 | 100 |
If the [timer](/developers/mobile-sdk/settings#timeout-to-send-events-automatically) runs out, events are sent even if the queue is smaller than defined in **minBatchSize**.
### Maximum number of events in queue --- This parameter sets the maximum number of events which may be sent in a single batch. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Method | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.settings.tracker.setMaximumBatchSize(value)` | `Integer` | 100 | 1 | 100 |
| Parameter | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.Settings.tracker.maxBatchSize` | `number` | 100 | 1 | 100 |
| Parameter | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.Settings.tracker.maxBatchSize` | `number` | 100 | 1 | 100 |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.maxBatchSize` | `int` | 100 | 1 | 100 |
### Timeout to send events automatically --- This parameter sets the time (in milliseconds for Android, in seconds for other SDKs) required before an attempt is made to send the queue. Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Method | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.settings.tracker.setAutoFlushTimeout(value)` | `TimeInterval` | 5000 | 50 | - |
| Parameter | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.settings.tracker.autoFlushTimeout` | `TimeInterval` | 5.0 | 0.5 | - |
| Parameter | Type | Default | Minimum | Maximum | | --- | --- | --- | --- | --- | | `Synerise.Settings.tracker.autoFlushTimeout` | `number` | 5.0 | 0.5 | - |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoFlushTimeout` | `double` | 5.0 | 0.5 | - |
If the [minimum queue size](/developers/mobile-sdk/settings#minimum-number-of-events-in-queue) is met, events are sent even if the timer has not run out.
### Events triggering flush mechanism --- This parameter sets an array of event 'action' values which trigger the flush mechanism. The list can be modified or cleared - including removing the default values. Available on: **Android** (5.17.0 or newer), **iOS** (4.17.0 or newer).
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.tracker.eventsTriggeringFlush` | `List` | ["push.click", "push.view", "push.notView", "push.button.click", "push.dismiss"] | 5.17.0 |
In iOS, `push.view` events are handled by the Notification Service Extension and always sent immediately, regardless of this setting.
| Parameter | Type | Default | Min. SDK version | | --- | --- | --- | --- | | `Synerise.settings.tracker.eventsTriggeringFlush` | `[String]` | ["push.openInApp", "push.click", "push.button.click", "push.dismiss"] | 4.17.0 |
### Automatic location event sending --- This parameter specifies if location events are sent automatically. Available on: **Android**, **iOS**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.locationAutomatic` | `Boolean` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.locationAutomatic` | `Bool` | false |
### Auto-tracking mode --- This parameter parameter defines the [auto-tracking](/developers/mobile-sdk/event-tracking#auto-tracking-configuration) mode. Available on: **Android**, **iOS**.
- `PLAIN` - listeners are set to track screen visits only. - `FINE` - listeners are attached to nearly everything that is clickable in your app, including screen visits. | Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoTracking.trackMode` | TrackMode | FINE |
- `.disabled` - listeners are disabled (default). - `.plain` - listeners are set to on-click only. - `.fine` - listeners are attached to nearly everything in your app (even to activities and `viewDidAppear`, the method that records [**VisitedScreen**](/developers/mobile-sdk/class-reference/ios/events#visitedscreenevent) events). | Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoTracking.mode` | `TrackerAutoTrackMode` | .disabled |
### Classes excluded from auto-tracking --- This parameter excludes classes from auto-tracking. Available on: **Android**, **iOS**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoTracking.excludedClasses` | `List` | [] |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoTracking.excludedClasses` | `[AnyClass]` | [] |
### View Tags excluded from auto-tracking --- This parameter excludes view tags from [auto-tracking](/developers/mobile-sdk/event-tracking#auto-tracking-configuration). Available on: **iOS**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.tracker.autoTracking.excludedViewTags` | `[Int]` | [] |
## Injector ### Enable/disable automatic starting of mobile campaigns (deprecated) --- This parameter specifies if walkthrough is processed automatically or not. - **DEPRECATED** Available on: **Android**, **iOS**, **React Native**, **Flutter**.
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.injector.automatic` | `Boolean` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.injector.automatic` | `Bool` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.Settings.injector.automatic` | `boolean` | false |
| Parameter | Type | Default | | --- | --- | --- | | `Synerise.settings.injector.automatic` | `bool` | false |
### Managing newsletter agreements with API ## Enabling with single/double opt-in Ensure that a [workflow for collecting newsletter agreements](/docs/settings/configuration/newsletter-sign-up) is running. Send a create/update API call with the `"newsletter_agreement_enabled": "enabled"` attribute. API reference is available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/BatchAddOrUpdateClients).
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients/batch' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJ...G2DI' \
--data-raw '[
   {
      "clientId": 12345,
      "attributes": {
          "newsletter_agreement_enabled": "enabled"
      }
   }
]'
This information is processed in the following way: 1. The customer's profile is updated with the `'newsletter_agreement_enabled': 'enabled'` attribute. 2. An event with details of the profile update is created and triggers the [workflow that collects newsletter agreements](/docs/settings/configuration/newsletter-sign-up). 3. One of the following happens: - If single opt-in is used, the agreement is enabled. Depending on the workflow configuration, the customer may receive an email with a notification. - If double opt-in is used, the customer receives an email and must click the link in that email to confirm the subscription. ## Enabling immediately You can also immediately enable an agreement over the API, without asking for confirmation or notifying the customer. If you use email address as a unique identifier, send a create/update API call with the `agreements.email` param set to `true`.
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients/batch' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJ...G2DI' \
--data-raw '[
   {
      "clientId": 12345,
      "agreements": {
         "email": true
         }
   }
]'
If you configured [non-unique emails](/docs/settings/configuration/non-unique-emails), send a create/update API call which changes the attribute you set as the agreement indicator to `enabled`
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients/batch' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJ...G2DI' \
--data-raw '[
   {
      "clientId": 12345,
      "attributes": {
         "the-newsletter-agreement-attribute-you-set-up": "enabled"
         }
   }
]'
The agreement is enabled immediately. API reference is available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/BatchAddOrUpdateClients). ## Disabling a newsletter agreement If you use email address as a unique identifier, send a create/update API call with the `agreements.email` param set to `false`. API reference is available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/BatchAddOrUpdateClients).
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients/batch' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJ...G2DI' \
--data-raw '[
   {
      "clientId": 12345,
      "agreements": {
         "email": false
         }
   }
]'
If you configured [non-unique emails](/docs/settings/configuration/non-unique-emails), send a create/update API call which changes the attribute you set as the agreement indicator to `disabled`
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/clients/batch' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJ...G2DI' \
--data-raw '[
   {
      "clientId": 12345,
      "attributes": {
         "the-newsletter-agreement-attribute-you-set-up": "disabled"
         }
   }
]'
The agreement is disabled immediately. ### Synerise user authorization The user is the person who logs in to the [Synerise Application](https://app.synerise.com/). They can have access to one or more workspaces, with different permissions in each profile. After a user logs in, they must choose a workspace to work with. Users may be required to log in using multi-factor authentication. ## Logging in as a user API reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/userLogin). To log in as a user, you need the username and the password.
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/uauth/auth/login/user' \
--header 'Content-Type: application/json' \
--data-raw '{
    "username": "user@synerise.com",
    "password": "strongPassword"
}'
The response includes: - JSON Web Token (JWT) needed to authorize when selecting a workspace or modifying user data. This token cannot be used to perform operations within a workspace. - Information about the multi-factor authentication method - Information about the user. Note that no workspace is selected, the user has no permissions (authorities) and no roles.
{
      // JWT
      "token": "eyJhbGciOiJinvalidXyw0TAc",
      // User info
      "consumer": {
          "type": "USER",
          "businessProfileId": null,
          "name": "user@synerise.com",
          "id": 12345,
          "authorities": [],
          "roles": "-2",
          "type": "USER"
      },
      // multi-factor authentication method, if required
      "mfaMethods": [
          "TOTP_AUTHENTICATOR"
      ]
  }
- If `mfaMethods` is **not** empty, you must [confirm the multi-factor authentication](#confirming-multi-factor-authentication). - If `mfaMethods` is empty, [select a workspace](#workspace-selection). ## Confirming multi-factor authentication API reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/userMfaLogin).
After a user logs on, they don't need to enter the authentication code on the same device for 8 hours.
You need the JWT obtained from the login request and a token from your authentication app.
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/uauth/auth/login/user/mfa/verification?mfaType=TOTP_AUTHENTICATOR' \
--header 'Authorization: Bearer eyJhbG...2KIh6IU' \
--header 'Content-Type: application/json' \
--data-raw '{
    "verificationCode": "938538"
}'
The response is the same as in the login endpoint. Proceed to [workspace selection](#workspace-selection). ## Workspace selection After authentication, a user must select a workspace to work in. ### Checking available workspaces API reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getBusinessProfilesUsingGET). You need a JWT obtained from [logging in](#logging-in-as-a-user); [multi-factor authentication](#confirming-multi-factor-authentication) (if enabled); or with a workspace already selected (when switching between profiles). The following request checks the workspaces available to a user:
curl --location --request \
GET 'https://{SYNERISE_API_BASE_PATH}/uauth/business-profile/' \
--header 'Authorization: Bearer eyJhbGciOiJSUz...qDTl72iqwIji4'
The response is an array of workspaces available to a user. The UUID is stored in the `businessProfileGuid` field.
[
    {
        "id": 48,
        "name": "Sample Profile",
        "logo": "https://synerise.com/sample.png",
        "businessProfileGuid": "01234abc-1234-5678-9abc-def012345678",
        "created": "2020-07-21T12:41:59Z",
        "subdomain": "sample-profile",
        "ipRestricted": false,
        "mfaRequired": true
    }
]
### Selecting a workspace API reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/userProfileLoginUsingPOST). You need: - a JWT obtained from [logging in](#logging-in-as-a-user); [multi-factor authentication](#confirming-multi-factor-authentication) (if enabled); or with a workspace already selected (when switching between profiles). - the [UUID of the workspace](#checking-available-workspaces)
curl --location --request \
  POST 'https://{SYNERISE_API_BASE_PATH}/uauth/auth/login/user/profile/01234abc-1234-5678-9abc-def012345678' \
  --header 'Authorization: Bearer eyJh...d886bpyWWZKvQESsM8cUYWuVqfSI'
The response includes: - JWT needed to perform operations as a user within a workspace (most operations performed as Synerise User require this token) - Information about the user and their authorities (permissions) in the workspace. These permissions correspond to the ones listed as required in the API reference.
{
      "token": "eyJhbGciOiJSU...tIarjyXFFCv_Ek6M",
      "consumer": {
          "type": "USER",
          "businessProfileId": 48,
          "name": "user@synerise.com",
          "id": 12345,
          "authorities": [
              "ROLE_ADMIN_EDITUSER",
              "ROLE_ANALYTICS_SHOW",
              "ROLE_API_ADD",
              "ROLE_API_CREATE",
              "ROLE_API_DELETE",
              ...
          ],
          "roles": "16",
          "type": "USER"
      }
  }
### Campaigns ## SyneriseSource | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 5.0.0 | 6.0.0 | 0.18.0 | 0.8.0 | **Declared In:** Headers/SNRSyneriseSource.h **Declaration:**
```Swift enum SyneriseSource: Int { simplePush, inAppMessage } ```
```Objective-C typedef NS_ENUM(NSInteger, SNRSyneriseSource) { SNRSyneriseActivitySimplePush, SNRSyneriseActivityInAppMessage } ```
--- --- ## NotificationInfo **Declared In:** Headers/SNRNotificationInfo.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class NotificationInfo: BaseModel ```
```Objective-C @interface SNRNotificationInfo : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **campaignHashId** | String | no | Identifier of the notification campaign. | | **campaignTitle** | String | no | Identifier of the notification title. | | **payload** | [AnyHashable: Any] | yes | Payload of the notification. |
All properties are read-only.
--- --- ## PushNotificationsRegistrationOrigin **Declared In:** Headers/SNRSynerise.h **Declaration:**
```Swift enum PushNotificationsRegistrationOrigin: Int { .appStarted, .clientContextChange, .securityReason, .periodicJob } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPushNotificationsRegistrationOrigin) { SNRPushNotificationsRegistrationOriginAppStarted, SNRPushNotificationsRegistrationOriginClientContextChange, SNRPushNotificationsRegistrationOriginSecurityReason, SNRPushNotificationsRegistrationOriginPeriodicJob } ```
--- --- ## InAppMessageData Model representing an in-app message data.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** Headers/SNRInAppMessageData.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class InAppMessageData: BaseModel ```
```Objective-C @interface SNRInAppMessageData : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **campaignHash** | String | no | Identifier of the in-app message campaign. | | **variantIdentifier** | String | no | Identifier of the in-app message campaign variant. | | **additionalParameters** | [AnyHashable: Any] | yes | Parameters additionally provided by the campaign. | | **isTest** | Bool | no | Specifies if the object is from a test campaign. |
All properties are read-only.
--- --- ### SyneriseMethod Enum with a list of SDK methods that can be called from JavaScript in an in-app. See [Using in-app template builder](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#use-a-mobile-sdk-method) ## Deprecated symbols ### *SyneriseActivity* | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Deprecated in: | 5.0.0 | n/a | n/a | n/a | **Declared In:** Headers/SNRSyneriseActivity.h **Declaration:**
```Swift enum SyneriseActivity: Int { simplePush, banner, walkthrough, inAppMessage } ```
```Objective-C typedef NS_ENUM(NSInteger, SNRSyneriseActivity) { SNRSyneriseActivitySimplePush, SNRSyneriseActivityBanner, SNRSyneriseActivityWalkthrough, SNRSyneriseActivityInAppMessage } ```
--- --- ### *SyneriseActivityAction* | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Deprecated in: | 5.0.0 | n/a | n/a | n/a | **Declared In:** Headers/SNRSynerise.h **Declaration:**
```Swift enum SyneriseActivityAction: Int { none, hide } ```
```Objective-C typedef NS_ENUM(NSInteger, SNRSyneriseActivityAction) { SNRSyneriseActivityActionNone, SNRSyneriseActivityActionHide } ```
### OG Tags # Open Graph tags Open Graph tags (OG tags) can be used to additional information about items. When a page visit event is sent, the data from the OG tags is included in the data of that event. You can use this information, for example, to add an item or category context when creating recommendation filters. The name of the property is defined in the `property` attribute, and the value in the `content` attribute. Example:
<!-- "product" is the mandatory og:type for use with dynamic products catalog -->
<meta property="og:type" content="product">

<!-- the mandatory unique product ID, the Stock Keeping Unit (SKU), must be the same as the one sent to the cart/basket -->
<meta property="product:retailer_part_no" content="112233">

<!-- a product's photo -->
<meta property="og:image" content="https://example.com/photo/product_image.jpg">

<meta property="og:title" content="product_name">
<meta property="og:site_name" content="Example Site">
<meta property="og:url" content="https://example.com/product_site.html">

<!-- multiple categories are allowed -->
<meta property="product:category" content="category1_name">
<meta property="product:category" content="category2_name">

<meta property="product:price:amount" content="1,000.00">
<meta property="product:sale_price:amount" content="800.00" />
<meta property="product:original_price:amount" content="1,000.00">
og:tags are included in the URL of the SDK request. If there are too many, the browser may not process the request. The following table presents the URL length limits for different browsers: | Browser | Maximum URL length | | --- | --- | | Google Chrome | 32779 | | Google Android | 8192 | | Firefox | >64k | | Apple Safari | >64k | | Microsoft Internet Explorer 11| 2047 | | Microsoft Edge 16 | 2047 |
You can add custom information that you want to keep in the catalog:
<meta property="product:customName1" content="customValue1">
<meta property="product:customName2" content="customValue1">
<meta property="product:customName3" content="customValue1">
Using the [inserts](/developers/inserts) mechanism, you can refer to a catalog and retrieve all information contained in it. You can find out more about og:tags on the [Open Graph](http://ogp.me/) website. ## Adding OG tags to a website The OG tags (and other metadata) can be added to the website: - with the [Synerise tracking code](/developers/web/installation-and-configuration#customizing-metadata). - as a static part of the site when you build it. - with your own scripts that modify the page source. The script must run before loading the Synerise SDK. ## OG tags in regular websites A `page.visit` event is sent automatically every time a page is opened/refreshed.
og:tags must be implemented in the structure of the HTML document in the head section of a product card. Tags must be placed at the very beginning of the page, so that they load before the Synerise SDK tracker loads.
## OG tags in single-page applications If your page is a single-page application, the SDK is initialized only once. This means that `page.visit` events must be sent on-demand by your implementation. The way the event must be sent depends on how you implement OG tags in the page: - [OG tags are injected into the source of the page and available for retrieval with JS.](#single-page-with-og-tags) - [OG tags are not available and must be explicitly included in the `page.visit` event.](#single-page-without-og-tags) ### Single-page with OG tags If you inject the OG tags into the source of the page, they will be read and sent to Synerise when you call the following method:
SR.event.pageVisit()
No additional parameters are needed. ### Single-page without OG tags If the OG tags are not included in the source of the page, you must send them as an additional `ogTags`attribute of the `page.visit` event. The attribute is a stringified JSON object. The following example sends five OG tags with the `page.visit` event.
SR.event.pageVisit({
    "ogTags": JSON.stringify({
        "og:type": "product",
        "product:retailer_part_no": "87247894536",
        "og:site_name": "shoeStore",
        "og:title": "Red Sneakers LUE42",
        "product:color": "Red"
    })
})
## OG tag catalog Tags from page.visit events are automatically saved to a catalog named `Snrs-produktu-ogTag`. You can use this catalog to: - Verify that data from a page.visit event was sent correctly to Synerise (if it wasn't, it's not in the catalog) - Use data from this catalog in inserts. In this case, remember that the data is only updated when the item page is opened - so if an item wasn't viewed for a long time, the data in the catalog may be out-of-date. ### Flutter # Class reference - Flutter ### Sending form data with API Form data is usually [tracked by using the SDK](/developers/web/tracking-form-data), but you can make API calls from your backend, so that you have more control over the process and access to detailed event logs. Unlike the SDK, the logic of calling endpoints can also be modified according to business requirements.
The API calls must be made by the server! Making API calls from the browser exposes your API key.
The logic described in this article will let you detect if the customer who fills in a form (for example, a log-in form) is the same as the one currently recognized in the browser. The data is saved in a `form.submit` event. The event contains all data from the form.
If you implement tracking form data over the API, it is recommended to block sending form.submit events by the SDK. See [Event authentication settings](/docs/assets/events/event-settings).
To learn more about our API, see [these articles](/developers/api). ## Implementation overview The flowchart presents an overview of the logic which replicates the behavior of tracking form data over the SDK. In certain conditions, some steps of the logic are redundant. Thanks to this, all scenarios are covered with inserting additional checks.
Depending on your configuration, the unique identifier is email (default setting) or custom ID (see [Identifiers](/docs/settings/configuration/non-unique-emails).)
This logic is a suggestion. You can modify it according to your business needs or create your own. Remember to cover all the scenarios.
Sending form data with API
Overview of tracking form data by using the API
## Implementation details This section explains in detail the flow of events and actions, and how to implement them. ### Customer enters site and fills in HTML form HTML form example:
<form action="" method="post">
    <input type="text" name="email" placeholder="Email" value="john.doe@synerise.com" />
    <input type="text" name="name" placeholder="Name" value="John" />
    <input type="text" name="surname" placeholder="Surname" value="Doe" />
    <input type="submit" value="Save" />
</form>
1. Gather data from the HTML form. 2. **Optional:** Validate the data in the form (for example, check if email is properly formatted). 3. **Optional:** Authenticate the customer. 4. Check if the `_snrs_p` cookie has a value for `identityHash`. **`_snrs_p` cookie example:**
_snrs_p:
       host:
       permUuid:e0097757-d1e2-44ac-ba3c-d97979a354c1 # deprecated
       uuid:e0097757-d1e2-44ac-ba3c-d97979a354c1 # current UUID
       identityHash:277163923
       init:1613135695
       last:1625149870.406
       current:1625149875
       uniqueVisits:7
       allVisits:17
1. Perform one of the following actions: - if `identityHash` does not have a value, proceed to [this section](#if-identityhash-does-not-a-have-a-value). - if `identityHash` has a value, proceed to [this section](#if-identityhash-has-a-value). ### If identityHash does not a have a value The customer is currently anonymous. The data from the anonymous account needs to be associated with the data for the customer who filled in the HTML form. 1. Generate an UUIDv5 for the customer. For details, see [this article](/developers/web/uuids#generating-uuidv5). 2. Send a create/update API call to merge the anonymous customer with the one who was identified in the HTML form. The request body must contain an array with two objects: one with the identifier and the new UUIDv5, the other with the identifier and the UUID from the `_snrs_p` cookie. API reference is available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/BatchAddOrUpdateClients). If you want to send additional data, such as agreements or free-form attributes, they must be included in the object with the new UUIDv5.
See curl example (email)

The highlighted properties are required, the others are optional. For a comprehensive list of properties you can send, see API reference.

curl --location --request POST '{SYNERISE_API_BASE_PATH}/v4/clients/batch' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Api-Version: 4.4' \ --header 'Authorization: Bearer eyJ...yeIc' \ --data-raw '[ { "email": "example@synerise.com", "uuid": "4f82f7a9-0745-55a3-b028-e301b19bf8ec", "agreements": { "email": true, "sms": true }, "tags": [ "exampleTag" ], "attributes": { "customAttribute1": true, "customAttribute2": "string", "customAttribute3": 42 } }, { "email": "example@synerise.com", "uuid": "35a1c1d8-2468-4c47-9be2-f2c2edf9f526" } ]'
See curl example (customId)

The highlighted properties are required, the others are optional. For a comprehensive list of properties you can send, see API reference.

curl --location --request POST '{SYNERISE_API_BASE_PATH}/v4/clients/batch' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Api-Version: 4.4' \ --header 'Authorization: Bearer eyJ...yeIc' \ --data-raw '[ { "customId": "example.customId", "uuid": "d2bdec3a-96d9-5805-9ca2-1557aec691b1", "agreements": { "email": true, "sms": true }, "tags": [ "exampleTag" ], "attributes": { "customAttribute1": true, "customAttribute2": "string", "customAttribute3": 42 } }, { "customId": "example.customId", "uuid": "35a1c1d8-2468-4c47-9be2-f2c2edf9f526" } ]'
1. Send a `form.submit` event. The data from the form is stored in the `params` object. API reference is available [here](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CustomEvent).
See curl example (email)
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/custom' \ --header 'Authorization: Bearer eyJh...T-hyeIc' \ --header 'Api-Version: 4.4' \ --header 'Content-Type: application/json' \ --data-raw '{ "label": "Customer submitted a form", "action": "form.submit", "client": { "email": "example@synerise.com" }, "params": { "firstname": "John", "lastname": "Doe", "formType": "exampleFormType" } }'
See curl example (customId)
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/custom' \ --header 'Authorization: Bearer eyJh...T-hyeIc' \ --header 'Api-Version: 4.4' \ --header 'Content-Type: application/json' \ --data-raw '{ "label": "Customer submitted a form", "action": "form.submit", "client": { "customId": "example@synerise.com" }, "params": { "firstname": "John", "lastname": "Doe", "formType": "exampleFormType" } }'
4. Store the new UUIDv5 in the browser in one of the following ways: - If after SDK initialization: use the `SR.client.setUuid("new_uuid");` method; replace `new_uuid` with the UUID. The UUID is written to the `_snrs_p` cookie immediately. - If the Synerise SDK is not initialized, store the UUID in the `_snrs_reset_uuid` cookie. The UUID is written to the `_snrs_p` at SDK initialization. **Result:** The customer's data is saved, a recognized profile is created. ### If identityHash has a value The customer is recognized. You need to check if the customer who filled in the HTML form is the same as the one whose data is currently saved in the `_snrs_p` cookie. 1. Generate the `identityHash` of the customer who filled in the form in one of the following ways: - If Synerise SDK is initialized, use the following function: ``` SR.client.hashIdentity("unique_id") ``` where `unique_id` is the email or custom ID - If Synerise SDK is not initialized, use the following JS code or your own version of it, which can be written in another language:
// arguments
      // data: string (email or customId) to create hash from

      // returned value
      // hash: hashed string

      hashString: function (data) {
          var hash = 0;
          if (data.length === 0) {
              return hash;
          }
          for (var i = 0; i < data.length; i++) {
              var char = data.charCodeAt(i);
              hash = ((hash << 5) - hash) + char;
              hash = hash & hash;
          }
          return hash;
      }
1. Compare the generated hash with `identityHash` from the `_snrs_p` cookie: - [`identityHash` is identical](#if-identityhash-is-identical) - [`identityHash` is not identical](#if-identityhash-is-not-identical) #### If identityHash is identical The customer who filled the form is the same as the one who visited the site previously. You can send their data. 1. Send a `form.submit` event. The data from the form is stored in the `params` object. API reference is available [here](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CustomEvent).
See curl example (email)
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/custom' \ --header 'Authorization: Bearer eyJh...T-hyeIc' \ --header 'Api-Version: 4.4' \ --header 'Content-Type: application/json' \ --data-raw '{ "label": "Customer submitted a form", "action": "form.submit", "client": { "email": "example@synerise.com" }, "params": { "firstname": "John", "lastname": "Doe", "formType": "exampleFormType" } }'
See curl example (customId)
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/custom' \ --header 'Authorization: Bearer eyJh...T-hyeIc' \ --header 'Api-Version: 4.4' \ --header 'Content-Type: application/json' \ --data-raw '{ "label": "Customer submitted a form", "action": "form.submit", "client": { "customId": "example@synerise.com" }, "params": { "firstname": "John", "lastname": "Doe", "formType": "exampleFormType" } }'
**Result:** The data from the form is saved to the customer's account. #### If identityHash is not identical The customer who filled the form is not the same who visited the site previously. 1. Generate an UUIDv5 for the customer. For details, see [this article](/developers/web/uuids#generating-uuidv5). 2. Send a create/update API call to create/update the profile which is the new context with the UUIDv5. The request body is a single-object array. The object contains the new UUIDv5 and the unique identifier. If the profile already has this UUIDv5, sending the same data again does not cause any problems. You do not need to check before sending the call. API reference is available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/BatchAddOrUpdateClients).
See curl example (email)

The highlighted properties are required, the others are optional. For a comprehensive list of properties you can send, see API reference.

curl --location --request POST '{SYNERISE_API_BASE_PATH}/v4/clients/batch' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Api-Version: 4.4' \ --header 'Authorization: Bearer eyJ...yeIc' \ --data-raw '[ { "email": "example@synerise.com", "uuid": "4f82f7a9-0745-55a3-b028-e301b19bf8ec", "agreements": { "email": true, "sms": true }, "tags": [ "exampleTag" ], "attributes": { "customAttribute1": true, "customAttribute2": "string", "customAttribute3": 42 } } ]'
See curl example (customId)

The highlighted properties are required, the others are optional. For a comprehensive list of properties you can send, see API reference.

curl --location --request POST '{SYNERISE_API_BASE_PATH}/v4/clients/batch' \ --header 'Accept: application/json' \ --header 'Content-Type: application/json' \ --header 'Api-Version: 4.4' \ --header 'Authorization: Bearer eyJ...yeIc' \ --data-raw '[ { "customId": "example.customId", "uuid": "d2bdec3a-96d9-5805-9ca2-1557aec691b1", "agreements": { "email": true, "sms": true }, "tags": [ "exampleTag" ], "attributes": { "customAttribute1": true, "customAttribute2": "string", "customAttribute3": 42 } } ]'
**Result:** The profile is created/updated with the new UUIDv5 and the additional data you sent. The UUIDv5 is always the same for a given customer, regardless of where and how it was generated. 1. Send a `form.submit` event. The data from the form is stored in the `params` object. API reference is available [here](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CustomEvent).
See curl example (email)
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/custom' \ --header 'Authorization: Bearer eyJh...T-hyeIc' \ --header 'Api-Version: 4.4' \ --header 'Content-Type: application/json' \ --data-raw '{ "label": "Customer submitted a form", "action": "form.submit", "client": { "email": "example@synerise.com" }, "params": { "firstname": "John", "lastname": "Doe", "formType": "exampleFormType" } }'
See curl example (customId)
curl --location --request POST 'https://{SYNERISE_API_BASE_PATH}/v4/events/custom' \ --header 'Authorization: Bearer eyJh...T-hyeIc' \ --header 'Api-Version: 4.4' \ --header 'Content-Type: application/json' \ --data-raw '{ "label": "Customer submitted a form", "action": "form.submit", "client": { "customId": "example@synerise.com" }, "params": { "firstname": "John", "lastname": "Doe", "formType": "exampleFormType" } }'
4. Store the new UUIDv5 in the browser in one of the following ways: - If after SDK initialization: use the `SR.client.setUuid("new_uuid");` method; replace `new_uuid` with the UUID. The UUID is written to the `_snrs_p` cookie immediately. - If the Synerise SDK is not initialized, store the UUID in the `_snrs_reset_uuid` cookie. The UUID is written to the `_snrs_p` at SDK initialization. **Result:** The customer context in the browser changes to the customer with the new UUIDv5. ## Marketing agreements See [Newsletter agreements](/developers/web/newsletter-agreements). ### Flutter # Configuring push notifications (Flutter) ## Prerequisites --- ### Firebase Cloud Messaging Google Firebase Cloud Messaging is necessary to handle [push notifications](/docs/campaign/Mobile) sent from Synerise. 1. Follow the instructions in [this article](https://firebase.google.com/docs/flutter/setup) and integrate the Firebase plugin with your application. 2. Follow the instructions in [this article](https://firebase.flutter.dev/docs/messaging/overview/) and integrate cloud messaging in your application. 3. Integrate Firebase with Synerise. See [Integration](/docs/settings/tool/firebase) section.
It's important that the Firebase plugin is initialized as early as possible in the application lifecycle and also after the Synerise SDK. Late initialization may cause compilation problems.
## Setting up - Android {id=setting-up-android} --- ### Requirements {id=android-requirements} 1. After configuring Firebase, add the `google-services.json` file to your project. 2. Add the google-services dependency to your project's `build.gradle` file.
dependencies {
       ...
       classpath 'com.google.gms:google-services:4.3.3'
       ...
     }
## Setting up - iOS {id=setting-up-ios} --- ### Requirements {id=ios-requirements} 1. Configure handling Push Notifications in your application. See [Apple Notifications](https://developer.apple.com/notifications/). 2. After configuring Firebase, add the `GoogleService-Info.plist` file to your project. 3. Make sure your `Info.plist` file contains the following snippet: ``` FirebaseAppDelegateProxyEnabled ``` ### Extensions for push notifications {id=ios-extensions-for-push-notifications} #### Notification Service Extension {id=synerise-notification-service-extension-for-ios} **Synerise Notification Service Extension** is an object that adds the notification functionality to the SDK. It implements the following operations: - Decrypting **Simple Push** communication data (if encryption is enabled). - Tracking events from **Simple Push** communication. - 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. **Notification Service Extension** should be implemented in the native part of the application. Follow the instructions in [this article](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension-configuration). #### Rich Media Notification Content Extensions {id=synerise-notification-content-extension-for-ios} **Synerise Rich Media 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). **Synerise Rich Media Notification Content Extensions** should be implemented in the native part of the application. Follow the instructions in [this article](/developers/mobile-sdk/configuring-push-notifications/ios#rich-media-in-push-notifications). ## Set up Firebase Cloud Messaging for Synerise SDK --- The following code example explains how to implement Firebase Cloud Messaging integration with Synerise: 1. Define a top-level function for handling notifications when the app is in the terminated state. 2. Request permissions from the user. 3. Set presentation options for foreground state. 4. Get Firebase FCM token and set it to deliver push notifications from Synerise. 5. Make sure that the Firebase FCM token is always up-to-date. 6. Set Firebase listener method for handling notifications when the app is in the foreground. 7. Set Firebase listener method for handling notification clicks when the app is in the background. 8. Invoke method for handling notification clicks when a user opens a notification in the app’s closed state.
```Dart class InitialViewState extends State { @override void initState() { // Initialize Synerise SDK initializeSynerise(); // Setup notifications with Firebase setupNotifications(); // 8. Invoke method for handling notification clicks when a user opens a notification in the app’s closed state (see below for definition of the method). checkForInitialNotificationMessage(); super.initState(); } Future initializeSynerise() async { Synerise.initializer() .withApiKey('YOUR_PROFILE_API_KEY') .withBaseUrl("YOUR_API_BASE_URL") .withDebugModeEnabled(true) .init(); } Future setupNotifications() async { await Firebase.initializeApp(); // 1. Define a top-level function for handling notifications when the app is in the terminated state (see below for definition of the method). FirebaseMessaging.onBackgroundMessage(backgroundHandlerForFCM); // 2. Request permissions from the user await FirebaseMessaging.instance.requestPermission( alert: true, announcement: false, badge: true, carPlay: false, criticalAlert: false, provisional: false, sound: true, ); // 3. Set presentation options for the foreground state await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions( alert: true, badge: true, sound: true, ); // 4. Get Firebase FCM token and set it to deliver push notifications from Synerise FirebaseMessaging.instance.getToken().then((token) { if (token != null) { Synerise.notifications.registerForNotifications(token, true); } }); // 5. Make sure that the Firebase FCM token is always up-to-date FirebaseMessaging.instance.onTokenRefresh.listen((event) { FirebaseMessaging.instance.getToken().then((token) { if (token != null) { Synerise.notifications.registerForNotifications( firebaseToken!, mobileAgreement: true, // true or false, should depend on device permissions and customer's agreement in the application onSuccess: () {}, onError: (error) {}, ); } }); }); Synerise.notifications.listener((listener) { listener.onRegistrationRequired = () { FirebaseMessaging.instance.getToken().then((token) { if (token != null) { Synerise.notifications.registerForNotifications( firebaseToken!, mobileAgreement: true, // true or false, should depend on device permissions and customer's agreement in the application onSuccess: () {}, onError: (error) {}, ); } }); }; }); // 6. Set Firebase listener method for handling notifications when the app is in the foreground FirebaseMessaging.onMessage.listen((RemoteMessage message) async { Map messageMap = message.toMap(); bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(messageMap); if (isSyneriseNotification == true) { Synerise.notifications.handleNotification(messageMap); } }); // 7. Set Firebase listener method for handling notification clicks when the app is in the background FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { Map messageMap = message.toMap(); bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(messageMap); if (isSyneriseNotification == true) { Synerise.notifications.handleNotificationClick(messageMap); } }); } @pragma('vm:entry-point') Future backgroundHandlerForFCM(RemoteMessage message) async { await Firebase.initializeApp(); await initializeSynerise(); Map messageMap = message.toMap(); bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(messageMap); if (isSyneriseNotification) { Synerise.notifications.handleNotification(remoteMessageMap); } } Future checkForInitialNotificationMessage() async { await Firebase.initializeApp(); RemoteMessage? message = await FirebaseMessaging.instance.getInitialMessage(); if (message != null) { Map messageMap = message.toMap(); bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(messageMap); if (isSyneriseNotification == true) { Synerise.notifications.handleNotificationClick(messageMap); } } } //... } ```
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 [Synerise.notifications.registerForNotifications(registrationToken, mobileAgreement) method in the method reference](/developers/mobile-sdk/method-reference/flutter/campaigns#register-for-push-notifications).
You must always keep the Firebase token updated. In many cases in the application lifecycle, such as authorization, destroy session, user context change, and so on, the registration needs to be updated. In these situations, the SDK invokes the [onRegistrationRequired()](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener) method (see code snippet above).
## Configure Notification Encryption --- ### Android {id=android-notification-encryption-configuration} See [Configure Notification Encryption](/developers/mobile-sdk/configuring-push-notifications/android#configure-notification-encryption). ### iOS {id=ios-notification-encryption-configuration} See [Synerise Notification Service Extension](#synerise-notification-service-extension-for-ios) and [Configure Notification Encryption](/developers/mobile-sdk/configuring-push-notifications/ios#configure-notification-encryption). ### Application implementation {id=application-notification-encryption-configuration} In the application, you must set `encryption` to `true` in the SDK initializer or in the SDK settings.
```JavaScript // WARNING: This option must be configured before Synerise SDK is initialized! Synerise.settings.notifications.encryption = true; ```
## 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).
### Synerise payload The following sample code shows how to handle notifications and check if they are from Synerise:
```Dart //... FirebaseMessaging.onMessage.listen((RemoteMessage message) { Map messageMap = message.toMap(); bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(messageMap); if (isSyneriseNotification == true) { Synerise.notifications.handleNotification(messageMap); } }); FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { Map messageMap = message.toMap(); bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(messageMap); if (isSyneriseNotification == true) { Synerise.notifications.handleNotificationClick(messageMap); } }); //... ```
### Custom payload You may send both custom push notifications and custom campaigns in [Synerise](https://app.synerise.com). The code below of one sample Firebase listener method checks the notification origin and then handles it:
```Dart //... FirebaseMessaging.onMessage.listen((RemoteMessage message) { Map messageMap = message.toMap(); bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(messageMap); if (isSyneriseNotification == true) { Synerise.notifications.handleNotification(messageMap); } else { // Handle other notifications in your own way } }); //... ```
## 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-flutter) ## Additional in-app alert from push notifications --- The Flutter SDK on iOS devices 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
Simple Push campaign with in-app alert
## Limitations compared to native platforms --- Due to platform limitations, not all notification functionalities may work as in native SDKs. - **iOS only**: Native-configured button from a Simple Push campaign always invokes the default action (if configured) or displays an in-app alert with buttons to choose. ### Flutter # Installation and configuration (Flutter) In this article you will find out how to install and initialize SDK in a Flutter mobile application. While performing the actions from this guide, keep the order presented in this article.
The [Settings](/developers/mobile-sdk/settings#pre-initialization-settings) article contains additional information about SDK behaviors you may need prior to configuration.
## Requirements You need: * Access to [workspace](/docs/settings/business-profile) * 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. * Flutter configured on your machine - [Getting Started](https://docs.flutter.dev) * VS Code / Android Studio / Xcode ## Android{id=requirements-android} For the **Android** platform it uses the [Synerise Android SDK](https://github.com/Synerise/android-sdk). The development and debugging can be done with Android Studio. * Recommended environment: - Minimum Android SDK version - 24 - Supported targetSDKVersion - 33 ## iOS {id=requirements-ios} For the **iOS** platform it uses the [Synerise iOS SDK](https://github.com/Synerise/synerise-ios-sdk). The development and debugging can be done with Xcode. * Recommended environment: - Xcode 16 - iOS SDK 18 * Target deployment: * iOS 13.0+ for SDK versions 2.0.0 and higher * iOS 9.0+ for SDK versions lower than 2.0.0 --- ## Installation ### CLI ``` $ flutter pub add synerise_flutter_sdk ``` This will add a line similar to this to your package's `pubspec.yaml` and run an implicit `flutter pub get`: ``` dependencies: synerise_flutter_sdk: ^0.7.4 ``` Alternatively, your editor might support `flutter pub get`. Check the docs for your editor to learn more. ### Path dependency First you will need to add the Synerise Flutter SDK to your mobile application. To do that you can use the path dependency method in your `pubspec.yaml` as follows: via ssh: ``` synerise_flutter_sdk: git: url: git@github.com:Synerise/synerise-flutter-sdk.git ``` or via https: ``` synerise_flutter_sdk: git: url: https://github.com/Synerise/synerise-flutter-sdk.git ``` After that you can run `flutter pub get` to resolve the new dependency. --- ### Importing Synerise SDK You will need to import **Synerise.dart** from the **synerise_flutter_sdk** plugin.
```Dart import 'package:synerise_flutter_sdk/synerise.dart'; ```
## Android gradle & configuration 1. In the Android part of your application, add ``maven { url 'https://pkgs.dev.azure.com/Synerise/AndroidSDK/_packaging/prod/maven/v1' }`` to the `android/build.gradle`: 2. Make sure you included the following repositories: `` google() mavenCentral() `` The whole build.gradle snippet must look as follows: ``` repositories { google() mavenCentral() maven { url 'https://pkgs.dev.azure.com/Synerise/AndroidSDK/_packaging/prod/maven/v1' } } ``` then in your MainActivity file add:
```Dart public class MainActivity extends FlutterActivity { @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); SyneriseMethodChannel.configureChannel(flutterEngine); }} ```
## iOS configuration In iOS portion of your application (/ios) you will need to run `pod update` ## Initialization --- ### Basic initialization Initialize the Synerise SDK and provide the [Profile API Key](/docs/settings/tool/api).
Initialize Synerise SDK in the application workflow as early as possible.
```Dart Synerise.initializer() .withApiKey("YOUR_PROFILE_API_KEY") // 1 .setRequestValidationSalt("YOUR_REQUEST_VALIDATION_SALT") // 2 .withDebugModeEnabled(false) // 3 .withCrashHandlingEnabled(true) // 4 .setMessagingServiceType(MessagingServiceType.SERVICE_TYPE) // 5 .init(); ```
1. `.withApiKey('YOUR_PROFILE_API_KEY')` - Sets Profile API Key for Synerise SDK initialization. 2. `.withRequestValidationSalt('YOUR_REQUEST_VALIDATION_SALT')` - Sets salt string for request validation. 3. `.withDebugModeEnabled(false)` - Enables debug mode. See [Debug mode](/developers/mobile-sdk/installation-and-configuration/react-native#debug-mode) section for more information. 4. `.withCrashHandlingEnabled(true)` - Enables crash handling. Synerise SDK sends a crash event automatically when an uncaught exception occurs. 5. `.setMessagingServiceType(MessagingServiceType.SERVICE_TYPE)` - defines the messaging services your app uses: - `gms` for Google Mobile Services. This is the default option. - `hms` for Huawei Mobile Services. This can only be used on Huawei devices.
Secure sensitive keys (for example, `apiKey` and `requestValidationSalt`) with mechanisms like string obfuscation or encryption.
### Initialization with custom API environment You can change the base URL of the API for on-premise installations. Use the following initialization method:
```Dart Synerise.initializer() .withApiKey('YOUR_PROFILE_API_KEY') .withBaseUrl("YOUR_API_BASE_URL") .init(); ```
## Running example app - Open project folder in selected IDE - `flutter pub get` in the terminal (dependencies pull) - select the device/emulator in your IDE (for ios part it is required to run `pod update` in example/ios directory) - `cd example` and `flutter run` ## Debug mode --- You can enable debug logs for Synerise SDK by using the `.withDebugModeEnabled(true)` method in `Synerise.initializer` when you initialize the SDK.
Do not use debug mode in a release version of your application.
You can receive logs about: - **Core**: push notifications - **Tracker**: declarative events, sending process - **Client**: customer state, authorization - **Injector**: campaigns - **Content**: content widget, documents, recommendations ## Main Synerise listeners --- ### Injector Listeners You can specify your custom action when a customer clicks on simple push, banner or walkthrough. Synerise SDK implements two main actions that a customer may invoke - open URL and Deeplink: - listener.onOpenUrl = (url) - This method is called when Synerise handles URL action from campaign activities. - listener.onDeepLink = (deepLink) - This method is called when Synerise handles deeplink action from campaign activities. Note: For more information about handling actions from the Synerise SDK, see the Campaigns section.
```Dart Synerise.injector.listener((listener) { listener.onOpenUrl = (url) { ... }; listener.onDeepLink = (deepLink) { ... }; }); ### Notifications Listeners When you want to deal with Push Notifications: - listener.onRegistrationRequired - This method is called when Synerise needs registration for Push Notifications. Synerise.notifications.listener((listener) { listener.onRegistrationRequired = () { FirebaseMessaging.instance.getToken().then((value) { if (value != null) { Synerise.notifications.registerForNotifications(value, true); } }); }; }); ```
### Events ### Event Main event abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete subclasses instead.
**Declared In:** lib/model/tracker/event.dart **Declaration:**
abstract class Event
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **type** | String | no | Event type | | **label** | String | no | Can't be empty. This value isn't saved in persistent storage and can't be used in Decision or Automation Hubs. It isn't shown on a Profile card. | | **action** | String | no | Event action | | **parameters** | bool | no | Event parameters | --- --- ### CustomEvent
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
Represents a custom client event. **Declared In:** lib/model/tracker/custom_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) **Declaration:**
class CustomEvent extends Event
**Initializers:**
CustomEvent(String label, String action, Map<String, Object> parameters)
**Example:**
```Dart final paramMap = { "firstKeyCustomParam": "TEST_1", "secondKeyCustomParam": "TEST_2", }; CustomEvent event = CustomEvent("LABEL", "ACTION", paramMap); ```
--- --- ### PushViewedEvent Represents a 'client viewed push' event. This event is used for push message interaction tracking. **Declared In:** lib/events/push/push_viewed_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class PushViewedEvent extends CustomEvent
**Initializers:**
PushViewedEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### PushClickedEvent Represents a 'client clicked push' event. This event is used for push message interaction tracking. **Declared In:** lib/events/push/push_clicked_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class PushClickedEvent extends CustomEvent
**Initializers:**
PushClickedEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### PushCancelledEvent Represents a 'client dismissed push' event. This event is used for push message interaction tracking. **Declared In:** lib/events/push/push_cancelled_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class PushCancelledEvent extends CustomEvent
**Initializers:**
PushCancelledEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### CartEvent Main cart action abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `CartEvent` subclasses instead.
**Declared In:** lib/events/cart/cart_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class CartEvent extends CustomEvent
**Initializers:**
CartEvent(String label, String action, String sku, UnitPrice finalPrice, int quantity, Map<String, Object>? parameters)
**Methods:** This method sets a value for the `name` parameter.
void setName(String name)
--- This method sets a value for the `category` parameter.
void setCategory(String category)
--- This method sets values for the `categories` parameter.
void setCategories(List<String> categories)
--- This method sets a value for the `offline` parameter.
void setOffline(bool offline)
--- This method sets the value of the `regularPrice` parameter.
void setRegularPrice(UnitPrice regularPrice)
--- This method sets the value of the `discountedPrice` parameter.
void setDiscountedPrice(UnitPrice discountedPrice)
--- This method sets the value of the `url` parameter.
void setUrl(String url)
--- This method sets the value of the `producer` parameter (producer can signify a brand of the item).
void setProducer(String producer)
--- --- ### UnitPrice **Declared In:** lib/model/tracker/unit_price.dart **Declaration:**
class UnitPrice
**Initializers:**
UnitPrice(
   int amount,
   String currency)
--- --- ### ProductAddedToCartEvent Represents a 'client added product to cart' event. **Declared In:** lib/events/cart/product_added_to_cart_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class ProductAddedToCartEvent extends CartEvent
**Initializers:**
ProductAddedToCartEvent(String label, String sku, UnitPrice finalPrice, int quantity, Map<String, Object>? parameters)
--- --- ### ProductRemovedFromCartEvent Represents a 'client removed product from cart' event. **Declared In:** lib/events/cart/product_removed_from_cart_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class ProductRemovedFromCartEvent extends CartEvent
**Initializers:**
ProductRemovedFromCartEvent(String label, String sku, UnitPrice finalPrice, int quantity, Map<String, Object>? parameters)
--- --- ### ProductViewedEvent Represents a 'client viewed product' event. **Declared In:** lib/events/product/product_viewed_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class ProductViewedEvent extends CustomEvent
**Initializers:**
ProductViewedEvent(
    String label,
    String productId,
    String name,
    Map<String, Object>? parameters,
  )
**Methods:** This method sets a value for the `category` parameter.
void setCategory(String category)
--- This method sets the value of the `url` parameter.
void setUrl(String url)
--- --- ### ProductAddedToFavoritesEvent Represents a 'client added product to favorites' event. **Declared In:** lib/events/product/product_added_to_favorites_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class ProductAddedToFavouritesEvent extends CustomEvent
**Initializers:**
ProductAddedToFavoritesEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### LoggedInEvent Represents a 'client logged in' event. **Declared In:** lib/events/auth/logged_in_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class LoggedInEvent extends CustomEvent
**Initializers:**
LoggedInEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### LoggedOutEvent Represents a 'client logged out' event. **Declared In:** lib/events/auth/logged_out_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class LoggedOutEvent extends CustomEvent
**Initializers:**
LoggedOutEvent(String label, Map<String, Object>? parameters)
--- --- ### RegisteredEvent Represents a 'client registered' event. **Declared In:** lib/events/auth/registered_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class RegisteredEvent extends CustomEvent
**Initializers:**
RegisteredEvent(String label, Map<String, Object>? parameters)
--- --- ### RecommendationEvent Main recommendation abstract class for inheriting classes.
This is an abstract class and it is not meant to be instantiated directly. You should use concrete `RecommendationEvent` subclasses instead.
**Declared In:** lib/events/recommendation/recommendation_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class RecommendationEvent extends CustomEvent
**Initializers:**
RecommendationEvent(String label, String action, Map<String, Object>? parameters)
--- --- ### RecommendationSeenEvent Represents a 'client saw a recommendation' event. **Declared In:** lib/events/recommendation/recommendation_seen_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class RecommendationSeenEvent extends RecommendationEvent
**Initializers:**
RecommendationSeenEvent(String label, String action, String productId, String productName, String campaignId, String campaignHash, Map<String, Object>? parameters)
--- --- ### RecommendationViewEvent Represents a 'client viewed a recommendation' event. **Declared In:** lib/events/recommendation/recommendation_view_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class RecommendationViewEvent extends RecommendationEvent
**Initializers:**
RecommendationViewEvent(String label, String action, List<String>? items, String campaignId, String campaignHash, String correlationId, Map<String, Object>? parameters)
--- --- ### RecommendationClickEvent Represents a 'client clicked a recommendation' event. **Declared In:** lib/events/recommendation/recommendation_click_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) [RecommendationEvent](/developers/mobile-sdk/class-reference/flutter/events#recommendationevent) **Declaration:**
class RecommendationClickEvent extends RecommendationEvent
**Initializers:**
RecommendationClickEvent(String label, String action, String productId, String productName, String campaignId, String campaignHash,
      Map<String, Object>? parameters)
--- --- ### VisitedScreenEvent Represents a 'client visited screen' event. This can be used for mobile screen usage tracking. **Declared In:** lib/events/other/visited_screen_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class VisitedScreenEvent extends CustomEvent
**Initializers:**
VisitedScreenEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### HitTimerEvent Represents a 'client hit timer' event. This could be used for profiling or activity time monitoring - you can send a `HitTimerEvent` when your client starts doing something and send it once again when they finish, but this time with the different time signature. Then you can use our analytics engine to measure, for example, average activity time. **Declared In:** lib/events/other/hit_timer_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class HitTimerEvent extends CustomEvent
**Initializers:**
HitTimerEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### SearchedEvent Represents a 'client searched' event. **Declared In:** lib/events/other/searched_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class SearchedEvent extends CustomEvent
**Initializers:**
SearchedEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### SharedEvent Represents a 'client shared' event. **Declared In:** lib/events/other/shared_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class SharedEvent extends CustomEvent
**Initializers:**
SharedEvent(
    String label,
    Map<String, Object>? parameters,
  )
--- --- ### AppearedInLocationEvent Represents a 'client appeared in location' event. **Declared In:** lib/events/other/appeared_in_location_event.dart **Inherits From:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Declaration:**
class AppearedInLocationEvent extends CustomEvent
**Initializers:**
AppearedInLocationEvent(
    String label,
    double lat,
    double lon,
    Map<String, Object>? parameters,
  )
### Campaigns ### SyneriseSource **Declared In:** lib/classes/models/Misc/SyneriseSource.js **Declaration:**
enum SyneriseSource {
  NotSpecified = 'NOT_SPECIFIED',
  SimplePush = 'SIMPLE_PUSH',
  Banner = 'BANNER',
  Walkthrough = 'WALKTHROUGH',
  InAppMessage = 'IN_APP_MESSAGE'
}
**Functions:** Converts from **SyneriseSource** to **string**.
function SyneriseSourceToString(source: SyneriseSourceToString): string
--- Converts from **string** to **SyneriseSource**.
function SyneriseSourceFromString(string: string): SyneriseSource
--- --- ### InAppMessageData Model representing an in-app message data.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/classes/models/Misc/InAppMessageData.js **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class InAppMessageData extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **campaignHash** | string | no | Identifier of the in-app message campaign. | | **variantIdentifier** | string | no | Identifier of the in-app message campaign variant. | | **additionalParameters** | Object | yes | Parameters additionally provided by the campaign. | | **isTest** | boolean | no | Specifies if the object is from a test campaign. | ### Customer session --- ## Refresh customer token --- This method refreshes the customer’s current token.
Returns an error if the token has expired and cannot be refreshed.
**Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public refreshToken(onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.refreshToken(function(token) { // success }, function(error) { // failure }); ```
## Retrieve customer token --- This method retrieves the customer’s current, active token.
Returns an error if the token has expired and cannot be retrieved.
**Declared In:** lib/main/modules/ClientModule.js **Related To:** [Token](/developers/mobile-sdk/class-reference/react-native/client#token) **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public retrieveToken(onSuccess: (token: Token) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.retrieveToken(function(token) { // success }, function(error) { // failure }); ```
## Get current customer UUID --- This method retrieves the customer’s current UUID. **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public getUUID(): string
**Return Value:** The method returns the customer's UUID as string. **Example:**
```JavaScript let uuid = Synerise.Client.getUUID(); ```
## 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.10 | 3.3.5 | 0.9.0 | 0.7.0 | **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public regenerateUUID()
**Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.regenerateUUID(); ```
## Regenerate customer with identifier --- 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier The optional `clientIdentifier` parameter is a seed for UUID generation. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.5 | 3.6.4 | 0.9.10 | 0.7.2 | **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public regenerateUUIDWithClientIdentifier(clientIdentifier: string)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientIdentifier** | string | no | - | Seed for UUID generation |
The **clientIdentifier** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. ## Destroy current session --- This method destroys the session completely. This method clears all session data (both client and anonymous) and removes cached data. Then, it regenerates the UUID and creates the new anonymous session. **Declared In:** lib/main/modules/ClientModule.js **Class:** [ClientModule](/developers/mobile-sdk/class-reference/react-native/modules#client) **Declaration:**
public destroySession()
**Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Client.destroySession(); ```
### Customer devices A workspace [may be configured](/developers/api/clients/security#device-authorization) so that customers must confirm logging in from unknown devices. When a customer registers, the device they are using is added to the list of known devices automatically. ## Authenticating devices by email token Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/authenticateDevice). **Prerequisites**: [Email sender integration](/docs/settings/tool/integrating-email-providers) must be enabled. When a customer logs in from a new device, an authentication token is sent to the customer's email address. The device is not allowed to log in to the customer's account until that token is sent.
curl --request GET 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/client/device-control/53b1e613-826b-4b9e-8ee3-2ff7dde2f1e4
## Adding device to current account Method reference available [here](https://developers.synerise.com/ClientManagement/ClientManagement.html#operation/LinkAClientDeviceToCurrentlyLoggedInClient). You can add a device to the trusted device list of the currently authenticated customer. `deviceId` is the only obligatory parameter. The format of the ID depends on the OS.
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/v4/my-account/linked-devices 
  --header 'authorization: Bearer eyJh...JxkM5o' 
  --data '{
      "deviceId":"ec9d4410-4048-43e5-b755-f7d53d00656c",
    }'
### Customer session --- ## Refresh customer token --- This method refreshes the customer’s current token.
Returns an error if the token has expired and cannot be refreshed.
**Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> refreshToken({required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.refreshToken(onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<bool> refreshToken() async
**Return Value:** **true** if the operation is success, otherwise it throws an error. **Example:**
await  Synerise.client.refreshToken().catchError((error)
## Retrieve customer token --- This method retrieves the customer’s current, active token.
Returns an error if the token has expired and cannot be retrieved.
**Declared In:** lib/modules/client/client_impl.dart **Related To:** [Token](/developers/mobile-sdk/class-reference/flutter/client#token) **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> retrieveToken({required void Function(Token) onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **onSuccess** | Function([Token](/developers/mobile-sdk/class-reference/flutter/client#token) token) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.retrieveToken(onSuccess: (Token token) {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<Token> retrieveToken() async
**Return Value:** [Token](/developers/mobile-sdk/class-reference/flutter/client#token) **Example:**
Token token = await  Synerise.client.retrieveToken().catchError((error)
## Get current customer UUID --- This method retrieves the customer’s current UUID. **Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<String> getUUID() async
**Return Value:** String **Example:**
await Synerise.client
        .getUUID()
        .then((result) => {
        //result handling
        });
**Declaration:**
Future<String> getUUID() async
**Return Value:** String **Example:**
String uuid = await  Synerise.client.getUUID().catchError((error)
## 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.10 | 3.3.5 | 0.9.0 | 0.7.0 | **Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client) **Declaration:**
Future<void> regenerateUUID() async
**Return Value:** No value is returned. **Example:**
await Synerise.client
        .regenerateUUID()
        .then((result) => {
        //result handling
        });
## Regenerate customer with identifier --- 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier The optional `clientIdentifier` parameter is a seed for UUID generation. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.5 | 3.6.4 | 0.9.10 | 0.7.2 | **Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client) **Declaration:**
Future<void> regenerateUUIDWithClientIdentifier(String clientIdentifier) async
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **clientIdentifier** | String | no | Seed for UUID generation |
The **clientIdentifier** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. **Example:**
await Synerise.client
        .regenerateUUIDWithClientIdentifier(clientIdentifier)
        .then((result) => {
        //result handling
        });
## Destroy current session --- This method destroys the session completely. This method clears all session data (both client and anonymous) and removes cached data. Then, it regenerates the UUID and creates the new anonymous session. **Declared In:** lib/modules/client/client_impl.dart **Class:** [ClientImpl](/developers/mobile-sdk/class-reference/flutter/modules#client)
**Declaration:**
Future<void> destroySession({required void Function() onSuccess, required void Function(SyneriseError) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.client.destroySession(onSuccess: () {
  //onSuccess handling
}, onError: (SyneriseError error) {
  //onError handling
});
**Declaration:**
Future<void> destroySession() async
**Return Value:** No value is returned. **Example:**
await  Synerise.client.destroySession().catchError((error)
### Campaigns ### SyneriseSource **Declared In:** lib/enums/injector/synerise_source.dart **Declaration:**
enum SyneriseSource {
  notSpecified('NOT_SPECIFIED'),
  simplePush('SIMPLE_PUSH'),
  banner('BANNER'),
  walkthrough('WALKTHROUGH'),
  inAppMessage('IN_APP_MESSAGE');
**Functions:** Converts from **String** to **SyneriseSource**.
```Dart static SyneriseSource getSyneriseSourceFromString(String string) ```
--- --- ### InAppMessageData Model representing an in-app message data.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/model/in_app/in_app_message_data.dart **Declaration:**
class InAppMessageData
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **campaignHash** | String | no | Identifier of the in-app message campaign. | | **variantIdentifier** | String | no | Identifier of the in-app message campaign variant. | | **additionalParameters** | Map | yes | Parameters additionally provided by the campaign. | | **isTest** | bool | no | Specifies if the object is from a test campaign. | ### Flutter # Flutter listeners ### NotificationsListener {id=notifications-listener} A listener to handle actions from the notifications module.
```Dart Synerise.notifications.listener((listener) { // The following method is called when registration for Push Notifications is needed. listener.onRegistrationRequired = () { ... }; }); ```
After invoking **onRegistrationRequired()** function, you must invoke the [Synerise.notifications.registerForNotifications(registrationToken, mobileAgreement)](/developers/mobile-sdk/method-reference/flutter/campaigns#register-for-push-notifications) method again.
--- --- ### InjectorListener {id=injector-listener} A listener to handle URL and deeplink actions from the injector module.
```Dart Synerise.injector.listener((listener) { // The following method is called when Synerise handles URL action from campaign activities // It is required function listener.onOpenUrl = (url) { ... }; // The following method is called when Synerise handles deep link action from campaign activities // It is required function listener.onDeepLink = (deepLink) { ... }; }); ```
--- --- ### InjectorInAppMessageListener {id=injector-in-app-message-listener} A listener to handle the states of [in-app messages](/developers/mobile-sdk/campaigns/in-app-message).
```Dart Synerise.injector.inAppMessageListener((listener) { // The following method is called after an in-app message appears listener.onPresent = (data) { ... }; // The following method is called after an in-app message disappears listener.onHide = (data) { ... }; // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. listener.onOpenUrl = (data, url) { ... }; // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. listener.onDeepLink = (data, deepLink) { ... }; // This method is called when the // SRInApp.handleCustomAction(name, params) method is used in an in-app message. listener.onCustomAction = (data, name, parameters) { ... }; }) ```
--- --- ## InjectorWalkthroughListener {id=injector-walkthrough-listener}
**InjectorWalkthroughListener** was removed in SDK version 2.0.0.
--- --- ## InjectorBannerListener {id=injector-banner-listener}
**InjectorBannerListener** was removed in SDK version 2.0.0.
### Flutter # Method reference - Flutter ### Configuring push notifications In this section, you will learn how to implement push notifications in your mobile application. ### External providers This article contains instruction to implement third parties approaches to authenticating a customer in a mobile application. ## Facebook Login --- For those Applications that rely on Facebook Login as authentication, Synerise has a separate method that provides you with a Synerise JWT token based on Facebook login. Currently, there are no dedicated settings related to Facebook authentication on the user interface in the Synerise platform. You just have to implement RESTful API or SDK methods to authenticate through Facebook. To authenticate a customer using Facebook, implement the following methods: | OS | Method | |--------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Android | - [Client.authenticate()](/developers/mobile-sdk/method-reference/android/client-authentication#authenticate-customer-by-identityprovider) | | iOS | - [Client.authenticate(token:clientIdentityProvider:authID:context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-by-identityprovider)
- [Client.authenticateConditionally(token:clientIdentityProvider:authID:context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider) | | React Native | - [Synerise.Client.authenticate(token, clientIdentityProvider, authID, context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-identityprovider)
- [Synerise.Client.authenticateConditionally(token, clientIdentityProvider, authID context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-conditionally-by-identityprovider) | | Flutter | - [Synerise.client.authenticate(clientAuthContext, clientIdentityProvider, token)](/developers/mobile-sdk/method-reference/flutter/client-authentication#authenticate-customer-by-identityprovider)) |
**authId/authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
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) - [Custom ID overwriting](/docs/settings/tool/iam-for-apps/general#custom-id-overwriting) - [External ID overwriting](/docs/settings/tool/iam-for-apps/general#external-id-overwriting) ## Sign in with Apple --- For integrating with the Apple platform, Synerise has a separate method that returns a Synerise JWT token based on Sign in with Apple credentials. You can read more about the configuration of the Sign in with Apple option in the Synerise platform [here](/docs/settings/tool/iam-for-apps/third-party#apple). In this case, the authentication process works in the following way: 1. A customer authenticates by Sign in with Apple. 2. Apple provides authentication credentials. 3. Your app uses these credentials and creates `ClientAppleSignInAuthenticationContext`. 4. The context is passed to Synerise by using: | OS | Method | |--------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | iOS | - [Client.authenticate(token:clientIdentityProvider:authID:context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider)
- [Client.authenticateConditionally(token:clientIdentityProvider:authID:context:success:failure:)](/developers/mobile-sdk/method-reference/ios/client-authentication#authenticate-customer-conditionally-by-identityprovider) | | React Native | - [Synerise.Client.authenticate(token, clientIdentityProvider, authID, context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-by-identityprovider)
- [Synerise.Client.authenticateConditionally(token, clientIdentityProvider, authID context, onSuccess, onError)](/developers/mobile-sdk/method-reference/react-native/client-authentication#authenticate-customer-conditionally-by-identityprovider) | | Flutter | - [Synerise.client.authenticate(clientAuthContext, clientIdentityProvider, token)](/developers/mobile-sdk/method-reference/flutter/client-authentication#authenticate-customer-by-identityprovider)) |
**authId/authID** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
5. If the authentication was successful, Synerise provides your application with our JWT access token for the customer. 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) - [Custom ID overwriting](/docs/settings/tool/iam-for-apps/general#custom-id-overwriting) - [External ID overwriting](/docs/settings/tool/iam-for-apps/general#external-id-overwriting) ## The list of methods --- ### Check if a customer is signed in This method checks if a customer is signed in through oAuth, Facebook, Sign in with Apple, or RaaS.
This method returns `false` if a customer is authenticated through [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication).
| OS | Method | |--------------|-------------------------------------------------------------------------------------------------------------------------------------------| | Android | [Client.isSignedIn()](/developers/mobile-sdk/method-reference/android/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | iOS | [Client.isSignedIn()](/developers/mobile-sdk/method-reference/ios/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | React Native | [Synerise.Client.isSignedIn()](/developers/mobile-sdk/method-reference/react-native/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | | Flutter | [Synerise.client.isSignedIn()](/developers/mobile-sdk/method-reference/flutter/client-authentication#check-if-a-customer-is-signed-in-via-raas-oauth-facebook-apple) | ### 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). ### Context Some recommendation and search requests allow you to use a context whose attributes will be used when building a filter. For example, you can recommend items in context of an item or items currently in the basket; or in context of the profile which created the basket. This allows you to build dynamic filters instead of using hardcoded values, resulting increased personalization of your recommendations. ## Item context In the following example, the `brand` attribute of a context item is used to filter the results of a request to items which have the same brand: ``` brand == context.brand ``` If the value of the context item's `brand` is `abcd`, the result is the following filter: ``` brand == "abcd" ```
If the context consists of multiple items, the value of that context's is an array of values from all the context items.
**Example:** In the following example, the filter matches items whose `brand` attribute is in the array of context item brands: ``` brand IN context.brand ``` If the context items' brands are `abcd` and `efgh`, the result is the following filter: ``` brand IN ["abcd","efgh"] ``` **Example:** In the following example, the filter matches items whose `price.value` attribute is higher than the [average](/developers/iql/functions#numeric-functions) `price.value` attribute of multiple context items: ``` price.value > AVG(context.price.value) ``` If the context items' prices are 10.49, 1.99, and 62.99, the result is the following filter: ``` price.value > AVG([10.49, 1.99, 62.99]) ```
The item context is taken from the item catalog instead of the index. Because of this: - attributes do **not** need to be configured as filterable to be used as context. - the context's array-type attributes are **not** affected by the behavior described in ["Indexing attributes in arrays"](/developers/iql/filters#indexing-attributes-in-arrays-recommendations-only).
## Profile context When the context is a profile, you can use attributes, tags, segmentations, expressions, and aggregates as filter values. ### Limits In one request, you can use: - up to 20 profile attributes - 1 segmentation - 2 aggregates OR 2 expressions OR 1 expression and 1 aggregate The limits apply to unique elements. For example, you can refer to the same segmentation a few times, but you can't include 2 different segmentations.
- If the request refers to a campaign (for example, in the ["Get recommendations by campaign" endpoint](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#operation/GetRecommendationsByCampaignV2)), the campaign's filters and the additional filters share the limit. - If the request uses boosting strategies (for example, in the ["Scoring be metric" endpoint](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#operation/PostRecommendLastViewedForUserItems)), the boosting strategies and the filters share the limit.
### Profile attributes In the following example, the brand of the item must be the same as the profile's `favoriteBrand` attribute: ``` brand == client.attributes.favoriteBrand ``` If the `favoriteBrand` attribute has the value `"abcd"`, the result is the following filter: ``` brand == "abcd" ``` If the attribute doesn't exist in the profile, the filter is ignored. ### Profile tags In the following example, the tag `"vip"` must exist in the profile's tags: ``` "tag" IN client.tags ``` **Example:** A profile has the `"vip"` tag. When you create the following [IF statement](/developers/iql/logic#if): ``` IF("vip" IN client.tags, discount > 0, discount == 0) ``` it evaluates to: ``` discount > 0 ``` ### Profile segmentations You can check if a profile belongs to a [segmentation](/docs/analytics/segmentations). The segmentation is identified by its UUID and calculated at the time of the request. ``` client.segmentations HAS ``` **Example:** A profile belongs to segmentation `39d39ad1-6d7b-4401-b067-998bf7d56d9f`. When you create the following [IF statement](/developers/iql/logic#if): ``` IF(client.segmentations HAS "39d39ad1-6d7b-4401-b067-998bf7d56d9f", discount > 0, discount == 0) ``` it evaluates to: ``` discount > 0 ``` ### Profile expressions You can access the result of an [expression](/docs/analytics/expressions) calculated for the context profile. The expression is identified by UUID and calculated at the time of the request. ``` client.expressions.uuid ``` **Example:** Expression `0abc195a-548e-460d-a904-1e285b8adb96` returns `15.0` for the context profile. If you create the following filter: ``` discount > client.expressions.0abc195a-548e-460d-a904-1e285b8adb96 ``` it evaluates to: ``` discount > 15.0 ``` If the expression does not exist, its value in the filter is `null`. ### Profile aggregates You can access the result of an [aggregate](/docs/analytics/aggregates) calculated for the context profile. The aggregate is identified by UUID and calculated at the time of the request. ``` client.aggregates.uuid ``` **Example:** Aggregate `08dfe176-2a37-3234-bf4f-3fa9b3b309bc` returns `180.0` for the context profile. If you create the following filter: ``` price.value < client.aggregates.08dfe176-2a37-3234-bf4f-3fa9b3b309bc ``` it evaluates to: ``` price.value < 180.0 ``` If the aggregate does not exist, its value in the filter is `null`. ## What happens if an attribute does not exist in the context? If an attribute does not exist in the context, its value becomes `null == true` and the filter which uses it becomes unprocessable. If that filter is part of a larger expression, it is ignored. **Example 1:** The following filter matches NO ITEMS: ``` discount == context.thisAttributeDoesNotExist ``` **Example 2:** The following filter matches items whose `discount == 0`, because the other condition is unprocessable. ``` discount == 0 AND discount == context.thisAttributeDoesNotExist ``` ### Check if a value exists The `IS DEFINED` operator allows you to check if an attribute exists and has a non-null value. The following filter uses an [IF statement](/developers/iql/logic#if) to check if an attribute exists and act accordingly: ``` IF(context.thisAttributeDoesNotExist IS DEFINED, discount > 0, discount == 0) ``` The context attribute does not exist, so the `discount == 0` filter is applied. ### Campaigns ### SyneriseSource This enum contains values which describe the source of campaign. **Declared In:** `com.synerise.sdk.injector.callback.SyneriseSource` **Declaration:**
```Java public enum SyneriseSource ```
```Kotlin public enum SyneriseSource ```
**Values:** | Property | Description | | --- | --- | | **SIMPLE_PUSH** | Simple push campaign | | **IN_APP_MESSAGE** | In-app message campaign | --- --- ### Campaign Class model for campaigns. **Declared In:** `com.synerise.sdk.injector.net.model.Campaign` **Declaration:**
```Java public class Campaign implements Serializable ```
```Kotlin class Campaign : Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **hashId** | String | no | - | Campaign hash ID | | **variantId** | int | no | - | Campaign variant's ID | | **title** | String | no | - | Campaign title | | **type** | String | no | - | Campaign type |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves a value for the `hashId` parameter.
public String getHashId()
--- This method retrieves a value for the `variantId` parameter.
public int getVariantId()
--- This method retrieves a value for the `title` parameter.
public String getTitle()
--- This method retrieves a value for the `type` parameter.
public String getType()
--- --- --- ### SynerisePushResponse Class model for SynerisePushResponse. **Declared In:** `com.synerise.sdk.injector.net.model.push.notification.SynerisePushResponse` **Declaration:**
```Java public class SynerisePushResponse ```
```Kotlin class SynerisePushResponse ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **contentAvailable** | Boolean | no | - | Informs if content is available | | **data** | SynerisePush | no | - | Synerise push data | | **notification** | [SimpleNotification](/developers/mobile-sdk/class-reference/android/campaigns#simplenotification) | no | - | Synerise simple notification |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method checks if content is available.
public boolean isContentAvailable()
--- This method retrieves a value for the `data` parameter.
public SyneriseData getData()
--- This method retrieves a value for the `notification` parameter.
public SimpleNotification getNotification()
--- This method checks if the push is a simple push.
public boolean isSimplePush()
--- --- --- ### SimpleNotification Class model for simple notification. **Declared In:** `com.synerise.sdk.injector.net.model.push.notification.SimpleNotification` **Declaration:**
```Java public class SimpleNotification implements Serializable ```
```Kotlin class SimpleNotification : Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **title** | String | no | - | Notification title | | **body** | String | no | - | Notification body |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method checks if the notification has a title.
public boolean hasTitle()
--- This method retrieves a value for the `title` parameter (notification title).
public String getTitle()
--- This method checks if the notification has a body.
public boolean hasBody()
--- This method retrieves a value for the `body` parameter (notification body).
public String getBody()
--- --- --- ### NotificationInfo This enum contains values for a voucher code status. **Declared In:** `com.synerise.sdk.injector.callback.model` **Declaration:**
```Java public class NotificationInfo ```
```Kotlin public class NotificationInfo ```
#### Values | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **campaignHashId** | String | no | - | Identifier of the notification campaign. | | **campaignTitle** | String | no | - | Identifier of the notification title. | | **payload** | HashMap | no | - | Payload of the notification. | **Methods:** This method retrieves the value of the `campaignHashId` parameter.
public String getCampaignHashId()
--- This method defines the value of the `campaignHashId` parameter.
public void setCampaignHashId(String campaignHashId)
--- This method retrieves the value of the `CampaignTitle` parameter.
public String getCampaignTitle()
--- This method defines the value of the `CampaignTitle` parameter.
public void setCampaignTitle(String campaignTitle)
--- This method retrieves the contents of the `payload` parameter.
public HashMap<String, String> getPayload()
--- This method defines the contents of the `payload` parameter.
public void setPayload(HashMap<String, String> payload)
--- --- --- ### PushRegistrationOrigin This enum contains values for the `origin` parameter of push registration listener methods. **Declared In:** `com.synerise.sdk.core.types.enums` **Declaration:**
```Java public enum PushRegistrationOrigin ```
```Kotlin public enum PushRegistrationOrigin ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **APP_STARTED** | "APP_STARTED" | After a `client.applicationStarted` event is sent. | | **CLIENT_CONTEXT_CHANGE** | "CLIENT_CONTEXT_CHANGE" | After the client context changes. | | **PERIODIC_JOB** | "PERIODIC_JOB" | After a periodic job of a background task starts. | | **SECURITY_REASON** | "SECURITY_REASON" | After a security threat | **Methods:** There are no methods. --- --- --- ### TemplateBanner Class model for banners. **Declared In:** `com.synerise.sdk.injector.net.model.push.banner.TemplateBanner` **Declaration:**
```Java public class TemplateBanner extends BasePageMapper implements Parcelable, Validable ```
```Kotlin class TemplateBanner : BasePageMapper(), Parcelable, Validable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **campaign** | [Campaign](/developers/mobile-sdk/class-reference/android/campaigns#campaign) | no | - | Campaign class | | **trigger** | String | yes | - | Banner trigger | | **notification** | [SimpleNotification](/developers/mobile-sdk/class-reference/android/campaigns#simplenotification) | no | - | Notification class | | **autoDisappear** | [AutoDisappear](/developers/mobile-sdk/class-reference/android/campaigns#autodisappear) | no | - | Auto disappear | | **page** | NetGenericPageData | yes | - | Page data |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves the value of the `campaign` parameter.
public Campaign getCampaign()
--- This method retrieves the value of the `value` object.
public Object getValue()
--- This method checks if a banner has a trigger.
public boolean hasTrigger()
--- This method retrieves the `trigger` parameter from a banner.
public String getTrigger()
--- This method retrieves the value of the `notification` parameter.
public SimpleNotification getNotification()
--- This method retrieves the value of the `page` parameter.
public PageItem getPage()
--- This method retrieves the value of the `autodisappear` parameter.
public AutoDisappear getAutoDisappear()
--- --- --- ### SilentCommand Class model for silent command. **Declared In:** `com.synerise.sdk.injector.SilentCommand` **Declaration:**
```Java public class SilentCommand implements Validable ```
```Kotlin class SilentCommand : Validable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **className** | String | no | - | Class name | | **methodName** | String | no | - | Method name | | **methodParameterList** | List<[MethodParameter](/developers/mobile-sdk/class-reference/android/campaigns#methodparameter)> | no | - | Method parameters |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves a value of the `className` parameter.
public String getClassName()
--- This method retrieves a value of the `methodName` parameter.
public String getMethodName()
--- This method retrieves a list of values of the `methodParameters` parameter.
public List<MethodParameter> getMethodParameterList()
--- --- --- ### MethodParameter Class model for method parameter. **Declared In:** `com.synerise.sdk.injector.MethodParameter` **Declaration:**
```Java public class MethodParameter implements Validable ```
```Kotlin class MethodParameter : Validable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **className** | String | no | - | Class name | | **value** | Object | no | - | Parameter value | | **position** | int | no | - | Parameter position |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves a value of the `className` parameter.
public String getClassName()
--- This method retrieves a value of the `value` parameter.
public Object getValue()
--- This method retrieves a value of the `position` parameter.
public int getPosition()
--- --- --- ### AutoDisappear Class model for AutoDisappear. **Declared In:** `com.synerise.sdk.injector.net.model.push.model.banner.AutoDisappear` **Declaration:**
```Java public class AutoDisappear implements Serializable ```
```Kotlin class AutoDisappear : Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **isEnabled** | Boolean | no | - | Informs if auto disappear is enabled | | **timeout** | int | no | - | Disappear timeout |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method checks if auto disappear is enabled.
public boolean isEnabled()
--- This method retrieves the value of the `timeout` parameter.
public int getTimeout()
--- --- --- ### InAppMessageData Model for in-app messaging communication. **Declared In:** com.synerise.sdk.injector.inapp.InAppMessageData **Declaration:**
```Java public InAppMessageData(String campaignHash, String variantId, HashMap additionalParameters, Boolean isTest) ```
```Kotlin public InAppMessageData(campaignHash: String, variantId: String, additionalParameters: HashMap , isTest: Boolean) ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **campaignHash** | String | no | Identifier of the in-app message campaign. | | **variantId** | String | no | Identifier of the in-app message campaign variant. | | **additionalParameters** | HashMap | yes | Parameters additionally provided by the campaign. | | **url** | URL | yes | URL value from the action of the activity. | | **deeplink** | String | yes | Deep link value from the action of the activity. | | **isTest** | Bool | no | Specifies if the object is from a test campaign. |
All the properties above are accessible by using getters.
**Methods:** There are only getters for the above properties. --- --- ### SyneriseMethod Enum with a list of SDK methods that can be called from JavaScript in an in-app. See [Using in-app template builder](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#use-a-mobile-sdk-method) ### Web # Synerise for Web This section explains how to use Synerise with your website. ### Huawei integration in Flutter SDK ## Enable integration in the Synerise platform Before you start integrating Huawei services in your app, you must configure the integration in Synerise platform. For instructions, see ["Huawei integration"](/docs/settings/tool/huawei-integration). ## Configuration In order to integrate Huawei Mobile Services (HMS) with Synerise, you must add `.setMesaggingServiceType(MessagingServiceType.hms)` to your `Synerise.initializer`. We recommend passing `MessagingServiceType.hms` as an argument when you build the app for AppGallery.
More information about `Synerise.initializer` is available in ["Initialization"](/developers/mobile-sdk/installation-and-configuration/flutter#initialization).
## Implementing Huawei notifications in applications 1. Add the Huawei push library as a dependency and integrate it: [https://pub.dev/packages/huawei_push](https://pub.dev/packages/huawei_push). 2. Add an `onTokenEvent` callback to receive the HMS token. In the callback, send the token to Synerise by using [`Synerise.notifications.registerForNotifications`](/developers/mobile-sdk/method-reference/flutter/campaigns#register-for-push-notifications) method:
void _onTokenEvent(String event) {
       // Requested tokens can be obtained here
       setState(() {
         _token = event;
       });
       if (event != null && event.isNotEmpty) {
         Synerise.notifications.registerForNotifications(
           event,
           mobileAgreement: true,
           onSuccess: () {},
           onError: (error) {},
         );
         print("TokenEvent: " + _token);
       }
     }
3. Add a listener to trigger `getToken()` from the Huawei push library whenever the [`onRegistrationRequired`](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener) callback is called:
Synerise.notifications.listener((listener) {
         listener.onRegistrationRequired = () {
           getToken();
         };
       });
4. Add the `onMessageReceived` callback from the Huawei push library and pass the data to Synerise SDK:
Future<void> _onMessageReceived(RemoteMessage remoteMessage) async {
       // Called when a data message is received
       Map<String, String>? data = remoteMessage.getDataOfMap;
       if (data != null) {
         bool isSyneriseNotification =
         await Synerise.notifications.isSyneriseNotification(data);
         if (isSyneriseNotification == true) {
           Synerise.notifications.handleNotification(data);
           bool isSyneriseNotificationEncrypted = await Synerise.notifications
               .isNotificationEncrypted(data);
           if (isSyneriseNotificationEncrypted) {
             Map decryptedPayload =
             await Synerise.notifications.decryptNotification(data);
             developer.log(decryptedPayload.toString());
           }
         }
       }
     }
5. To make sure your callbacks work, use streams:
Future<void> initTokenStream() async {
       if (!mounted) return;
       Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError);
     }

     void getToken() {
       // Call this method to request for a token
       Push.getToken("");
     }

     Future<void> initMessageStream() async {
       if (!mounted) return;
       Push.onMessageReceivedStream
           .listen(_onMessageReceived, onError: _onMessageReceiveError);
     }
## Links and Deep Links In order to implement links and deep links, refer to [this](/developers/mobile-sdk/campaigns/action-handling#handling-actions-from-campaigns-in-android) instruction. ## Configuring notification encryption Instructions for encrypting push notifications are available [here](/developers/mobile-sdk/configuring-push-notifications/flutter#configure-notification-encryption). ### Customer account management ## Get customer account information --- This method gets a customer’s account information. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_READ` permission from the **Client** group.
**Method name:** Client.getAccount() **Declaration:**
```Java public static IDataApiCall getAccount() ```
```Kotlin fun getAccount():IDataApiCall ```
**Parameters:** No parameters required. **Return Value:** [IDataApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#idataapicall)<[GetAccountInformation](/developers/mobile-sdk/class-reference/android/client#getaccountinformation)> object to execute the request. **Example:**
```Java private IDataApiCall getAccountCall; private void getAccount(boolean isFacebook) { if (getAccountCall != null) getAccountCall.cancel(); getAccountCall = Client.getAccount(); getAccountCall.execute(({ this.onGetAccountSuccessful() }), ({ this.onGetAccountFailure() }); } ```
```Kotlin private val getAccountCall:IDataApiCall private fun getAccount(isFacebook:Boolean) { if (getAccountCall != null) getAccountCall.cancel() getAccountCall = Client.getAccount() getAccountCall.execute(({ this.onGetAccountSuccessful() }), ({ this.onGetAccountFailure() }) } ```
## Get customer's events --- This method retrieves events for an authenticated customer. This method requires customer authentication. **Method name:** Client.getEvents(clientEventsQuery) **Declaration:**
```Java public static IDataApiCall> getEvents(ClientEventsQuery clientEventsQuery) ```
```Kotlin fun getEvents(clientEventsQuery:ClientEventsQuery):IDataApiCall> ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientEventsQuery** | ClientEventsQuery | yes | - | Object to create clientEvent query | **Return Value:** [IDataApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#idataapicall)> object to execute the request. **Example:**
```Java private IDataApiCall> getEventClientsCall; if (getEventClientsCall != null) getEventClientsCall.cancel(); getEventClientsCall = Client.getEvents(clientEventsQuery); getEventClientsCall.execute(({ this.onSuccess() }), ({ this.onFailure() }); ```
```Kotlin private val getEventClientsCall:IDataApiCall> if (getEventClientsCall != null) getEventClientsCall.cancel() getEventClientsCall = Client.getEvents(clientEventsQuery) getEventClientsCall.execute(({ this.onSuccess() }), ({ this.onFailure() }) ```
## Update customer account basic information --- This method updates a customer’s account’s basic information (without identification data: uuid, customId, email). This method requires the context object with the customer’s account information. Omitted fields are not modified. This method does not require customer authentication and can be used by anonymous profiles. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.22.0 | 5.21.0 | 0.24.0 | 1.4.0 |
The API key must have the `API_BASIC_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Method name:** Client.updateAccountBasicInformation(accountInformation) **Declaration:**
```Java public static IApiCall updateAccountBasicInformation(@NonNull UpdateAccountBasicInformation accountInformation) ```
```Kotlin fun updateAccountBasicInformation(@NonNull accountInformation:UpdateAccountBasicInformation):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accountInformation** | [UpdateAccountBasicInformation](/developers/mobile-sdk/class-reference/android/client#updateaccountbasicinformation) | yes | - | Builder Pattern object with the Customer's basic account information | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java if (apiCall != null) apiCall.cancel(); apiCall = Client.updateAccountBasicInformation(accountInformation); apiCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin if (apiCall != null) apiCall.cancel() apiCall = Client.updateAccountBasicInformation(accountInformation) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Update customer account information --- This method updates a customer’s account information. This method requires the context object with the customer’s account information. Omitted fields are not modified. This method requires customer authentication.
The API key must have the `API_PERSONAL_INFORMATION_CLIENT_UPDATE` permission from the **Client** group.
**Method name:** Client.updateAccount(accountInformation) **Declaration:**
```Java public static IApiCall updateAccount(@NonNull UpdateAccountInformation accountInformation) ```
```Kotlin fun updateAccount(@NonNull accountInformation:UpdateAccountInformation):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accountInformation** | [UpdateAccountInformation](/developers/mobile-sdk/class-reference/android/client#updateaccountinformation) | yes | - | Builder Pattern object with the Customer's account information | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java if (apiCall != null) apiCall.cancel(); apiCall = Client.updateAccount(accountInformation); apiCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin if (apiCall != null) apiCall.cancel() apiCall = Client.updateAccount(accountInformation) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Change customer's account password --- This method changes a customer’s password. This method requires customer authentication.
Returns the HTTP 403 status code if the provided old password is invalid.
The API key must have the `SAUTH_CHANGE_PASSWORD_CLIENT_UPDATE` permission from the **Client** group.
**Method name:** Client.changePassword(oldPassword, password) **Declaration:**
```java public static IApiCall changePassword(@NonNull String oldPassword, @NonNull String password) ```
```kotlin fun changePassword(@NonNull oldPassword:String, @NonNull password:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **oldPassword** | String | yes | - | Client's old password | | **password** | String | yes | --- | Client's new password | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java private IApiCall apiCall; if (apiCall != null) apiCall.cancel(); apiCall = Client.changePassword(oldPassword, password); apiCall.execute(this::onSuccess, this::onFailure); ```
```kotlin val apiCall:IApiCall if (apiCall != null) apiCall.cancel() apiCall = Client.changePassword(oldPassword, password) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Request password reset for customer account --- This method requests a customer’s password reset with email. The customer will receive a token to the provided email address. That token is then used for the confirmation of password reset. This method requires the customer’s email. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.requestPasswordReset(resetRequest) **Declaration:**
```Java public static IApiCall requestPasswordReset(@NonNull PasswordResetRequest resetRequest) ```
```Kotlin fun requestPasswordReset(@NonNull resetRequest:PasswordResetRequest):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **resetRequest** | PasswordResetRequest | yes | - | PasswordResetRequest object with the Client's email. | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java if (call != null) call.cancel(); call = Client.requestPasswordReset(new PasswordResetRequest(email)); EspressoTestingIdlingResource.increment(); call.execute(this::onSuccess, this::onFailure); ```
```Kotlin if (call != null) call.cancel() call = Client.requestPasswordReset(PasswordResetRequest(email)) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Confirm password reset for customer account --- This method confirm a customer’s password reset with the new password and token provided by password reset request. This method requires the customer’s new password and the confirmation token received by e-mail. This method is a global operation and doesn't require customer authentication.
The API key must have the `SAUTH_PASSWORD_RESET_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.confirmPasswordReset(resetConfirmation) **Declaration:**
```java public static IApiCall confirmPasswordReset(@NonNull PasswordResetConfirmation resetConfirmation) ```
```kotlin fun confirmPasswordReset(@NonNull resetConfirmation:PasswordResetConfirmation):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **resetConfirmation** | PasswordResetConfirmation | yes | - | PasswordResetConfirmation object with the Client's new password and confirmation token. | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java private IApiCall call; if (call != null) call.cancel(); call = Client.confirmPasswordReset(confirmation); call.execute(this::onSuccess, this::onFailure); ```
```Kotlin val call:IApiCall if (call != null) call.cancel() call = Client.confirmPasswordReset(confirmation) call.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Request email change for customer account --- This method requests a customer's email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token or the password is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Method name:** Client.requestEmailChange(email, password, externalToken, authId) **Declaration:**
```Java public static IApiCall requestEmailChange(String email, String password, @Nullable String externalToken, @Nullable String authId) ```
```Kotlin fun requestEmailChange(email:String, password:String, @Nullable externalToken:String, @Nullable authId: String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer's email | | **password** | String | yes | -| Customer's password | | **externalToken** | String | no | - | ExternalToken should be used for Facebook, Oauth. For Synerise account, pass null | | **authId** | String | no | - | Optional identifier of authorization. For Synerise account, pass null. | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall apiCall; apiCall = Client.requestEmailChange(email, password, null, null); apiCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val apiCall:IApiCall apiCall = Client.requestEmailChange(email, password, null, null) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Confirm email change for customer account --- This method confirms an email change. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided token is invalid.
The API key must have the `SAUTH_CHANGE_EMAIL_CLIENT_UPDATE` permission from the **Client** group.
**Method name:** Client.confirmEmailChange(token, newsletterAgreement) **Declaration:**
```java public static IApiCall confirmEmailChange(String token, boolean newsletterAgreement) ```
```kotlin fun confirmEmailChange(token:String, newsletterAgreement:Boolean):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **token** | String | yes | - | Token from customer's email | | **newsletterAgreement** | boolean | yes | - | Newsletter agreement | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```java IApiCall apiCall; apiCall = Client.confirmEmailChange(token, newsletterAgreement.isChecked()); apiCall.execute(this::onSuccess, this::onFailure); ```
```kotlin val apiCall:IApiCall apiCall = Client.confirmEmailChange(token, newsletterAgreement.isChecked()) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Request phone update on customer account --- This method requests a customer's phone update. A confirmation code is sent to the phone number. This method is a global operation and doesn't require customer authentication.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.requestPhoneUpdate(phone) **Declaration:**
```Java public static IApiCall requestPhoneUpdate(String phone) ```
```Kotlin fun requestPhoneUpdate(phone:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **phone** | String | yes | - | Customer's phone number. | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall apiCall; apiCall = Client.requestPhoneUpdate(phone); apiCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val apiCall:IApiCall apiCall = Client.requestPhoneUpdate(phone) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Confirm phone update on customer account --- This method confirms a phone number update. This action requires the new phone number and confirmation code as parameters. This method is a global operation and doesn't require customer authentication.
Returns the HTTP 403 status code if the provided UUID does not exist or the password is invalid.
The API key must have the `API_PERSONAL_PHONE_CLIENT_CREATE` permission from the **Client** group.
**Method name:** Client.confirmPhoneUpdate(phone, confirmationCode, smsAgreement) **Declaration:**
```Java public static IApiCall confirmPhoneUpdate(String phone, String confirmationCode, @Nullable Boolean smsAgreement) ```
```Kotlin fun confirmPhoneUpdate(phone:String, confirmationCode:String, @Nullable smsAgreement:Boolean):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **phone** | String | yes | - | Phone number that will be confirmed | | **confirmationCode** | String | yes | - | Code received in SMS | | **smsAgreement** | Boolean | no | - | Optional SMS marketing agreement | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall apiCall; apiCall = Client.confirmPhoneUpdate(phone, code, enableAgreement.isChecked() ? null : smsAgreement.isChecked()); apiCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val apiCall:IApiCall apiCall = Client.confirmPhoneUpdate(phone, code, if (enableAgreement.isChecked()) null else smsAgreement.isChecked()) apiCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Delete customer account by Identity Provider --- This method deletes a customer's account. This method requires customer authentication.
HTTP 403 status code is returned if the provided password or token is invalid.
The API key must have the `SAUTH_CLIENT_DELETE`, `SAUTH_OAUTH_CLIENT_DELETE`, `SAUTH_FACEBOOK_CLIENT_DELETE`, `SAUTH_APPLE_CLIENT_DELETE` permissions from the **Client** group.
**Method name:** Client.deleteAccount(clientAuthFactor, clientIdentityProvider, authId) **Declaration:**
```Java public static IApiCall deleteAccount(String clientAuthFactor, ClientIdentityProvider clientIdentityProvider, @Nullable String authId) ```
```Kotlin fun deleteAccount(clientAuthFactor:String, clientIdentityProvider:ClientIdentityProvider, authId:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientAuthFactor** | String | yes | - | In case of oauth, fb, or google this is token. If you have synerise account this is password. | | **clientIdentityProvider** | [ClientIdentityProvider](/developers/mobile-sdk/class-reference/android/client#clientidentityprovider) | yes | - | Provider of your account. Example: FACEBOOK, OAUTH, SYNERISE, GOOGLE | | **authId** | String | no | - | Customer's optional unique identifier | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall deleteCall = Client.deleteAccount(password, ClientIdentityProvider.SYNERISE, null); deleteCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val deleteCall = Client.deleteAccount(password, ClientIdentityProvider.SYNERISE, null) deleteCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
## Removed methods ### Delete customer account {#delete-customer-account} --- This method deletes a customer's account. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
Returns the HTTP 403 status code is returned if the provided password is invalid.
The API key must have the `SAUTH_CLIENT_DELETE` permission from the **Client** group.
**Replaced By:** [Delete customer account by Identity Provider](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account-by-identity-provider) **Method name:** Client.deleteAccount(password) **Declaration:**
```Java public static IApiCall deleteAccount(String password) ```
```Kotlin fun deleteAccount(password:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **password** | String | yes | - | Customer's current password. | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall deleteCall = Client.deleteAccount(password); deleteCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val deleteCall = Client.deleteAccount(password) deleteCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
### Delete customer account by OAuth {#delete-customer-account-by-oauth} --- This method deletes a customer's account by OAuth. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.11 | 3.6.13 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `SAUTH_CLIENT_DELETE` and `SAUTH_OAUTH_CLIENT_DELETE` permissions from the **Client** group.
**Replaced By:** [Delete customer account by Identity Provider](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account-by-identity-provider) **Method name:** Client.deleteAccountByOAuth(accessToken, uuid) **Declaration:**
```Java public static IApiCall deleteAccountByOAuth(String accessToken, @Nullable String uuid) ```
```Kotlin fun deleteAccountByOAuth(accessToken:String, @Nullable uuid:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **accessToken** | String | yes | - | user's token | | **uuid** | String | no | --- | Optional Customer UUID, internal UUID is used if this parameter is null | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall deleteCall = Client.deleteAccountByOAuth(accessToken, uuid) deleteCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val deleteCall = Client.deleteAccountByOAuth(accessToken, uuid) deleteCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
### Delete customer account by Facebook {#delete-customer-account-by-facebook} --- This method deletes a customer's account by Facebook. This method requires customer authentication. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.8 | 3.3.0 | 0.9.12 | n/a | | Deprecated in: | 3.6.19 | 3.6.19 | 0.14.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `SAUTH_CLIENT_DELETE` and `SAUTH_FACEBOOK_CLIENT_DELETE` permissions from the **Client** group.
**Replaced By:** [Delete customer account by Identity Provider](/developers/mobile-sdk/method-reference/android/client-account#delete-customer-account-by-identity-provider) **Method name:** Client.deleteAccountByFacebook(facebookToken, uuid) **Declaration:**
```Java public static IApiCall deleteAccountByFacebook(String facebookToken, @Nullable String uuid) ```
```Kotlin fun deleteAccountByFacebook(facebookToken:String, @Nullable uuid:String):IApiCall ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **facebookToken** | String | yes | - | Customer's facebook token | | **uuid** | String | no | --- | Optional Customer UUID, internal UUID is used if this parameter is null | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall deleteCall = Client.deleteAccountByFacebook(facebookToken, uuid) deleteCall.execute(this::onSuccess, this::onFailure); ```
```Kotlin val deleteCall = Client.deleteAccountByFacebook(facebookToken, uuid) deleteCall.execute(({ this.onSuccess() }), ({ this.onFailure() })) ```
### Customer session ## Refresh customer token --- This method refreshes the customer’s current token.
Returns an error if the token has expired and cannot be refreshed.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func refreshToken(success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)refreshTokenWithSuccess:(nonnull void (^)(void))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift Client.refreshToken(success: { _ in Client.retrieveToken(success: { (token) in // success let tokenString: String = token.tokenString let tokenOrigin: TokenOrigin = token.tokenOrigin }, failure: { (error) in // failure }) }, failure: { (error) in // failure }) ```
```Objective-C [SNRClient refreshTokenWithSuccess:^() { [SNRClient retrieveTokenWithSuccess:^(SNRToken *token) { // success NSString *tokenString = token.tokenString; SNRTokenOrigin tokenOrigin = token.tokenOrigin; } failure:^(SNRApiError *error) { // failure }]; } failure:^(SNRApiError *error) { // failure }]; ```
## Retrieve customer token --- This method retrieves the customer’s current, active token.
Returns an error if the token has expired and cannot be retrieved.
**Declared In:** Headers/SNRClient.h **Related To:** [Token](/developers/mobile-sdk/class-reference/ios/client#token) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func retrieveToken(success: ((Token) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)retrieveTokenWithSuccess:(nonnull void (^)(SNRToken *token))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | **success** | ((Token) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift Client.retrieveToken(success: { (token) in // success let tokenString: String = token.tokenString let tokenOrigin: TokenOrigin = token.tokenOrigin }, failure: { (error) in // failure }) ```
```Objective-C [SNRClient retrieveTokenWithSuccess:^(SNRToken *token) { // success NSString *tokenString = token.tokenString; SNRTokenOrigin tokenOrigin = token.tokenOrigin; } failure:^(SNRApiError *error) { // failure }]; ```
## Get current customer UUID --- This method retrieves the customer’s current UUID. **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func getUUID() -> String ```
```Objective-C + (NSString *)getUUID; ```
**Return Value:** The method returns the customer's UUID as string. **Example:**
```Swift let clientUUID: String = Client.getUUID() ```
```Objective-C NSString *clientUUID = [SNRClient getUUID]; ```
## Get customer UUID for use in authentication --- This method retrieves the current UUID or generates a new one from a seed. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.15.0 | 5.15.0 | n/a | n/a |
This operation doesn't affect the customer session in the SDK.
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func getUUIDForAuthentication(authID: String) -> String ```
```Objective-C + (NSString *)getUUIDForAuthenticationWithAuthID:(NSString *)authID ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **authID** | String | yes | - | Seed for UUID generation | **Return Value:** The method returns the UUID for use in authentication as a string. **Example:**
```Swift let clientUUID: String = Client.getUUIDForAuthentication(authID: "AUTH_ID") ```
```Objective-C NSString *clientUUID = [SNRClient getUUIDForAuthenticationWithAuthID:@"AUTH_ID"]; ```
## 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.10 | 3.3.5 | 0.9.0 | 0.7.0 | **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func regenerateUUID() -> Void ```
```Objective-C + (void)regenerateUUID; ```
**Return Value:** No value is returned. ## Regenerate customer with identifier --- 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier The optional `clientIdentifier` parameter is a seed for UUID generation. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.5 | 3.6.4 | 0.9.10 | 0.7.2 | **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func regenerateUUID(clientIdentifier: String?) -> Void ```
```Objective-C + (void)regenerateUUIDWithClientIdentifier:(NSString *)clientIdentifier; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientIdentifier** | String | no | - | Seed for UUID generation |
The **clientIdentifier** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** No value is returned. ## Destroy current session --- This method destroys the session completely. This method clears all session data (both client and anonymous) and removes cached data. Then, it regenerates the UUID and creates the new anonymous session. **Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func destroySession() ```
```Objective-C + (void)destroySession ```
**Return Value:** No value is returned. **Example:**
```Swift Client.destroySession() ```
```Objective-C [SNRClient destroySession]; ```
### Recommendation API responses The response depends on the type of recommendation and the configuration of the item feed.
When [configuring the item feed](/docs/settings/configuration/ai-engine-configuration/engine-configuration-for-recommendations#selecting-response-attributes), in the **Response attributes** section, add only the attributes that you plan to use.
### Item recommendations These recommendations offer items. In an item recommendation response: - the `data` array lists items as objects. `itemId` is always included in each item's object. Adding more details can be enabled in the ["Response attributes" settings of the item feed](/docs/settings/configuration/ai-engine-configuration/engine-configuration-for-recommendations#selecting-response-attributes). - the `extras` object contains: - Slots (if applicable) with the IDs of the items they include. The details of those items are in `data`. - IDs of context items, if applicable. - A `correlationId` used for identifying [which events result from which request](/developers/api/recommendations/events). This is used in [recommendation statistics](/docs/ai-hub/recommendations-v2/recommendation-statistics) and in analytics. To display the results, you need to get item details from `data`. If you use multiple slots, you can use the data from `extras.slots` to arrange the results in the customer's view. **Response example**:
{
    // an array of items in the recommendation:
    "data": [
        { // one item as an object
            "itemId": "0196818716fta", // unique ID of the item from the item feed

            // additional attributes from item feed configuration:
            "title": "Baseball cap", 
            // the `link` attribute is automatically enriched with campaign/request metadata for tracking in Decision Hub and Automation Hub
            "link": "https://example.com/baseball-cap?snrai_campaign=DkhvrZoTKthD&snrai_id=75ea91a9-3a27-4dbf-addc-b7006cf70d52",
            "color": "red"
        },
        ... // more items from the recommendation:
        {
            ...
        },
        {
            ...
        }
    ],

    // other data:
    "extras": {
        "contextItems": null, // context items, if applicable
        "correlationId": "75ea91a9-3a27-4dbf-addc-b7006cf70d52", // unique ID of this recommendation request

        // items sorted into slots:
        "slots": [
            { // one slot as an object
                "id": 2, // ID of the slot
                // a list of items in this slot (only IDs): 
                "itemIds": [
                    "0196818716fta", // a single item ID
                    ...
                ],
                "name": "no shoes", // name of the slot
                "rows": null // not used in item recommendation campaigns
            },
            // more slots:
            {
                ...
            },
            {
                ...
            }
        ]
    }
}
### Section page recommendations This type of recommendation offers items sorted into sections. The sections are created by selecting an attribute. All items within one section will have the same attribute value. To learn about creating section page recommendations, read [Creating section page recommendations](/docs/ai-hub/recommendations-v2/creating-section-recommendations). In a section page recommendation response: - the `data` array contains the details of all the items in the recommendation. It works the same as in [item recommendations](#item-recommendations). - the `extras` objects contains slots. In each slot, the `rows` array is a list of sections (objects) with item IDs and the attribute value that is common for the items in that section. The number of sections and items in each section is defined separately for each slot. To display the items, you need to take the section data from `extras.slots.rows` and the item details from `data`. You can also use data from the metadata catalog, such as item descriptions or image URLs. **Response example**: In this example: - the campaign contains 1 slot. - the slot contains 2 sections. - each section contains 3 items. - the selected attribute for creating sections is `color`
{
      // an array of items in the recommendation:
      "data": [
          { // one item as an object
              "itemId": "0196818719002", // unique ID of the item from the item feed

              // additional attributes from item feed configuration:
              "title": "Baseball cap", 
              // the `link` attribute is automatically enriched with campaign/request metadata for tracking in Decision Hub and Automation Hub
              "link": "https://example.com/baseball-cap?snrai_campaign=DkhvrZoTKthD&snrai_id=75ea91a9-3a27-4dbf-addc-b7006cf70d52",
          },
          ... // more items from the recommendation:
          {
              ...
          },
          {
              ...
          }
      // other data:
      ],
      "extras": {
          "contextItems": null, // context items, if applicable
          "correlationId": "75ea91a9-3a27-4dbf-addc-b7006cf70d52", // unique ID of this recommendation request

          // items sorted into slots and sections:
          "slots": [
              { // one slot as an object
                  "id": 0, // ID of the slot
                  "itemIds": null, // not used in section page recommendations
                  "name": "red items", // name of the slot

                  // sections of the recommendation:
                  "rows": [
                      {
                          "attributeValue": "red", // the common value of the selected attribute (color)
                          "itemIds": [
                              "0196818719002", // a single item ID
                              "0196499574457",
                              "0196996669878"
                          ],
                          "metadata": {
                              "imageLink": "https://example.com/section-images/red.png",
                              "title": "Red items"
                          }
                      },
                      {
                          "attributeValue": "green",
                          "itemIds": [
                              "0195953880516",
                              "0196895673303",
                              "0886614236611"
                          ],
                          "metadata": {
                              "imageLink": "https://example.com/section-images/green.png",
                              "title": "Green items"
                          }
                      }
                  ]
              }
          ]
      }
  }
### Attribute recommendations Attribute recommendations are functionally similar to item recommendations. However, instead of merchandise, they return attributes of that merchandise. To learn about creating attribute recommendations, see [Creating attribute recommendations](/docs/ai-hub/recommendations-v2/creating-attribute-recommendations). In an attribute recommendation response: - the `data` array includes the recommended attributes. By default, only the `itemId` (attribute name) is returned. If you want to use more attributes, such as a link to a page listing items with that attribute, you must configure a metadata catalog (see [Creating attribute recommendations](/docs/ai-hub/recommendations-v2/creating-attribute-recommendations)). - the `extras` objects contain slots. Each slot contains the IDs of the attributes it includes. To recommend items, you can: 1. Use the metadata catalog to add links as parameters of the recommended attributes. You can also include other metadata, such as images, titles, descriptions, and so on. 2. Use the links to redirect users to pages that show items with a given attribute. **Response example**: In this example: - the campaign has 2 slots. - both slots use the `color` attribute as **Item attribute**. - a metadata catalog is enabled for the recommendation and includes a `url` attribute for each attribute value.
{
      // an array of attribute values in the recommendation:
      "data": [
          {
              "itemId": "brown", // unique ID of the attribute value

              // additional data from the metadata catalog:
              "url": "https://example.com/items-by-color/brown",
              "imageUrl": "https://example.com/attribute-images/brown.png",
              "description": "Autumn colors for you"
          },
          {
              "itemId": "blonde",
              ...
          },
          {
              "itemId": "blue",
              ...
          },
          {
              "itemId": "orange",
              ...
          },
          {
              "itemId": "white",
              ...
          },
          {
              "itemId": "pink",
              ...
          }
      ],
      "extras": {
          "contextItems": null, // context items, if applicable
          "correlationId": "839f6ae5-af2f-4771-b501-ea609a8e2611", // unique ID of this recommendation request

          // attribute values sorted into slots:
          "slots": [
              {
                  "id": 0, // ID of the slot
                  "itemIds": [
                      "brown", // a single attribute value
                      "blonde",
                      "blue"
                  ],
                  "name": "Unnamed slot",
                  "rows": null // not used in attribute recommendations
              },
              {
                  "id": 1,
                  "itemIds": [
                      "orange",
                      "white",
                      "pink"
                  ],
                  "name": "Unnamed slot",
                  "rows": null
              }
          ]
      }
  }
### Event tracking --- ## Set custom identifier for events --- This method sets a custom identifier in the parameters of every event. You can pass a custom identifier to match your customers in our database. **Declared In:** lib/main/modules/TrackerModule.js **Class:** [TrackerModule](/developers/mobile-sdk/class-reference/react-native/modules#tracker) **Declaration:**
public setCustomIdentifier(identifier: string)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identifier** | string | yes | - | Customer's custom identifier | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Tracker.setCustomIdentifier("CUSTOM_IDENTIFIER"); ```
## Set custom email for events --- This method sets a custom email in the parameters of every event. You can pass a custom email to match your customers in our database. **Declared In:** lib/main/modules/TrackerModule.js **Class:** [TrackerModule](/developers/mobile-sdk/class-reference/react-native/modules#tracker) **Declaration:**
public setCustomEmail(email: string)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | string | yes | - | Customer's custom email | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Tracker.setCustomEmail("CUSTOM_EMAIL"); ```
## Send event --- This method sends an event.
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
- The tracker caches and enqueues all your events locally, so they all will be sent eventually. - The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
**Declared In:** lib/main/modules/TrackerModule.js **Related To:** [Event](/developers/mobile-sdk/class-reference/react-native/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/react-native/events#customevent) **Class:** [TrackerModule](/developers/mobile-sdk/class-reference/react-native/modules#tracker) **Declaration:**
public send(event: Event)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **event** | **Event** | yes | - | Event object | **Return Value:** No value is returned. **Example:**
```JavaScript let parameters = { "name": "John", "surname": "Rise", "company": "Synerise", "age": 25, "lastOrder": 380.50 }; let event = new CustomEvent("label", "my.action", parameters); Synerise.Tracker.send(event); ```
## Flush events from Tracker --- This method forces sending the events from the queue to the server.
The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
**Declared In:** lib/main/modules/TrackerModule.js **Class:** [TrackerModule](/developers/mobile-sdk/class-reference/react-native/modules#tracker) **Declaration:**
public flushEvents(onSuccess: () => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Tracker.flushEvents(function() { // success }); ```
### Event tracking ## Set Tracker Delegate --- This method sets an object for Tracker module delegate methods. **Declared In:** Headers/SNRTracker.h **Related To:** [TrackerDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#tracker-delegate) **Class:** [Tracker](/developers/mobile-sdk/class-reference/ios/modules#tracker) **Declaration:**
```Swift static func setDelegate(_ delegate: TrackerDelegate) ```
```Objective-C + (void)setDelegate:(SNRTrackerDelegate *)delegate ```
**Discussion:** Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#tracker-delegate). ## Get customer's events --- This method retrieves events for an authenticated customer. This method requires customer authentication. **Declared In:** Headers/SNRClient.h **Related To:** [ClientEventsApiQuery](/developers/mobile-sdk/class-reference/ios/client#clienteventsapiquery) **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func getEvents(apiQuery: ClientEventsApiQuery, success: (([ClientEventData]) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getEventsWithApiQuery:(nonnull SNRClientEventsApiQuery *)apiQuery success:(nonnull void (^)(NSArray *events))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiQuery** | [ClientEventsApiQuery](/developers/mobile-sdk/class-reference/ios/client#clienteventsapiquery) | yes | - | Object responsible for storing all query parameters | | **success** | (([ClientEventData]) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. ## Set custom identifier for events --- This method sets a custom identifier in the parameters of every event. You can pass a custom identifier to match your customers in our database. **Declared In:** Headers/SNRTracker.h **Class:** [Tracker](/developers/mobile-sdk/class-reference/ios/modules#tracker) **Declaration:**
```Swift static func setCustomIdentifier(customIdentifier: String?) -> Void ```
```Objective-C + (void)setCustomIdentifier:(nullable NSString *)customIdentifier; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **customIdentifier** | String | no | - | Customer's custom identifier | **Return Value:** No value is returned. ## Set custom email for events --- This method sets a custom email in the parameters of every event. You can pass a custom email to match your customers in our database. **Declared In:** Headers/SNRTracker.h **Class:** [Tracker](/developers/mobile-sdk/class-reference/ios/modules#tracker) **Declaration:**
```Swift static func setCustomEmail(customEmail: String?) -> Void ```
```Objective-C + (void)setCustomEmail:(nullable NSString *)customEmail; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **customEmail** | String | no | - | Customer's custom email | **Return Value:** No value is returned. ## Send event --- This method sends an event.
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
- The tracker caches and enqueues all your events locally, so they all will be sent eventually. - The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
**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) **Class:** [Tracker](/developers/mobile-sdk/class-reference/ios/modules#tracker) **Declaration:**
```Swift static func send(_: Event) -> Void ```
```Objective-C + (void)send:(SNREvent *)event ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **event** | [Event](/developers/mobile-sdk/class-reference/ios/events#event) | yes | - | [Event](/developers/mobile-sdk/class-reference/ios/events#event) object | **Return Value:** No value is returned. **Example:** You may use standard objects in SDK, for example `ProductAddedToCartEvent` that represents a 'customer added a product to cart' event:
```Swift let event: ProductAddedToCartEvent = ProductAddedToCartEvent(label: "Product added!", sku: "12345", finalPrice: UnitPrice(amount: 100.0), quantity: 1) event.setCategory("Smartphones") event.setName("iPhone") event.setProducer("Apple") Tracker.send(event) ```
```Objective-C SNRProductAddedToCartEvent *event = [[SNRProductAddedToCartEvent alloc] initWithLabel:@"Product added!" sku:@"12345" finalPrice:[[SNRUnitPrice alloc] initWithAmount:100.0f] quantity:1]; [event setCategory:@"Smartphones"]; [event setName:@"iPhone"]; [event setProducer:@"Apple"]; [SNRTracker send:event]; ```
You can also pass additional parameters along with `ProductAddedToCartEvent` and other events, like in the example below:
```Swift let params: TrackerParams = TrackerParams.make { (builder) in builder.setString("12345", forKey: "snr_sku") builder.setInt(1, forKey: "snr_quantity") builder.setDouble(100.0, forKey: "snr_finalPrice") } let event: ProductAddedToCartEvent = ProductAddedToCartEvent(label: "Product added!", sku: "12345", finalPrice: UnitPrice(amount: 100.0), quantity: 1, params: params) event.setCategory("Smartphones") event.setName("iPhone") event.setProducer("Apple") Tracker.send(event) ```
```Objective-C SNRTrackerParams *params = [SNRTrackerParams makeWithBuilder:^(SNRTrackerParamsBuilder *builder) { [builder setString:@"12345" forKey:@"snr_sku"]; [builder setInt:1 forKey:@"snr_quantity"]; [builder setDouble:100.0f forKey:@"snr_finalPrice"]; }]; SNRProductAddedToCartEvent *event = [[SNRProductAddedToCartEvent alloc] initWithLabel:@"Product added!" sku:@"12345" finalPrice:[[SNRUnitPrice alloc] initWithAmount:100.0f] quantity:1 andParams:params]; [event setCategory:@"Smartphones"]; [event setName:@"iPhone"]; [event setProducer:@"Apple"]; [SNRTracker send:event]; ```
If you want to track a fully customizable event, you should use `CustomEvent`:
```Swift let params: TrackerParams = TrackerParams.make { (builder) in builder.setString("12345", forKey:"key_string"); builder.setInt(1, forKey:"key_integer"); builder.setDouble(1.0, forKey:"key_double"); builder.setFloat(1.0, forKey:"key_float"); builder.setBool(true, forKey:"key_bool"); builder.setObject(["key": "value"], forKey:"key_object"); } let event: CustomEvent = CustomEvent(label: "custom event", action: "custom event action", params: params) Tracker.send(event) ```
```Objective-C SNRTrackerParams *params = [SNRTrackerParams makeWithBuilder:^(SNRTrackerParamsBuilder *builder) { [builder setString:@"string" forKey:@"key_string"]; [builder setInt:1 forKey:@"key_integer"]; [builder setDouble:1.0f forKey:@"key_double"]; [builder setFloat:1.0f forKey:@"key_float"]; [builder setBool:YES forKey:@"key_bool"]; [builder setObject:@{ @"key" : @"value" } forKey:@"key_object"]; }]; SNRCustomEvent *event = [[SNRCustomEvent alloc] initWithLabel:"custom event" action:@"custom event action" andParams:params]; [SNRTracker send:event]; ```
## Flush events from Tracker --- This method forces sending the events from the queue to the server.
The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
**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) **Class:** [Tracker](/developers/mobile-sdk/class-reference/ios/modules#tracker) **Declaration:**
```Swift static func flushEvents(completionHandler: (() -> Void)?) -> Void ```
```Objective-C + (void)flushEventsWithCompletionHandler:(nullable void (^)(void))completion ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **completionHandler** | (() -> Void) | no | - | Block/Closure to be executed when the tracker has finished flushing events to Synerise backend, no matter the result | **Return Value:** No value is returned. ### Promotions and Vouchers ## Promotions --- ### PromotionResponse Class model for a promotion response. **Declared In:** `com.synerise.sdk.promotions.model.promotion.PromotionResponse` **Declaration:**
```Java public class PromotionResponse ```
```Kotlin class PromotionResponse ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **promotionMetadata** | [PromotionMetadata](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotionmetadata) | no | - | Metadata | | **promotions** | List<[Promotion](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotion)> | no | - | List of promotions |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves the value of the `promotionMetadata` parameter.
public PromotionMetadata getPromotionMetadata()
--- This method retrieves a list of promotions.
public List<Promotion> getPromotions()
--- --- --- ### SinglePromotionResponse Class model for a single promotion response. **Declared In:** `com.synerise.sdk.promotions.model.promotion.SinglePromotionResponse` **Declaration:**
```Java public class SinglePromotionResponse ```
```Kotlin class SinglePromotionResponse ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **promotion** | [Promotion](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotion) | no | - | Promotion |
All the properties above are accessible by using getters and setters.
**Initializers:** There are no initializers. **Methods:** There are only getters and setters for the above properties. This method retrieves the value of the `promotion` parameter.
public Promotion getPromotion()
--- This method defines the value of the `promotion` parameter.
public void setPromotion(Promotion data)
--- --- --- ### PromotionMetadata Class model for a promotion metadata. **Declared In:** `com.synerise.sdk.promotions.model.promotion.PromotionMetadata` **Declaration:**
```Java public class PromotionMetadata implements Serializable ```
```Kotlin class PromotionMetadata : Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **totalCount** | int | no | - | Total count of promotions | | **totalPages** | int | no | - | Total count of pages | | **page** | int | no | - | Page | | **limit** | int | no | - | Limit of promotions per page | | **code** | int | no | - | Code |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves the value of the `totalCount` parameter.
public int getTotalCount()
--- This method retrieves the value of the `totalPages` parameter.
public int getTotalPages()
--- This method retrieves the value of the `page` parameter.
public int getPage()
--- This method retrieves the value of the `limit` parameter.
public int getLimit()
--- This method retrieves the value of the `code` parameter.
public int getCode()
--- --- --- ### Promotion Class model for a promotion. **Declared In:** `com.synerise.sdk.promotions.model.promotion.Promotion` **Declaration:**
```Java public class Promotion extends BaseModel implements Serializable ```
```Kotlin class Promotion : BaseModel, Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | no | - | Promotion UUID | | **code** | String | no | - | Promotion code | | **status** | String | no | - | Promotion status | | **type** | String | no | - | Promotion type | | **redeemLimitPerClient** | int | no | - | Redemption limit per client | | **redeemQuantityPerActivation** | int | no | - | Redemption quantity per activation | | **currentRedeemedQuantity** | int | no | - | Current redeemed quantity | | **currentRedeemLimit** | int | no | - | Current redemption limit | | **activationCounter** | int | no | - | Activation counter | | **discountType** | String | no | - | Discount type | | **discountValue** | int | no | - | Discount value | | **requireRedeemedPoints** | int | no | - | Required redeemed points | | **name** | String | no | - | Promotion name | | **headline** | String | no | - | Promotion headline | | **description** | String | no | - | Promotion description | | **images** | List | no | - | List of promotion images | | **startAt** | Date | no | - | Start time of a promotion | | **expireAt** | Date | no | - | Expiration time of a promotion | | **lastingAt** | Date | no | - | How long a promotion lasts | | **params** | HashMap | no | - | Promotion custom parameters | | **catalogIndexItems** | List | no | - | List of item indexes | | **price** | long | no | - | Item price | | **priority** | int | no | - | Promotion priority |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. --- --- --- ### PromotionStatus This enum contains values for a promotion status. **Declared In:** `com.synerise.sdk.promotions.model.promotion.PromotionStatus` **Declaration:**
```Java public enum PromotionStatus ```
```Kotlin public enum PromotionStatus ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **ASSIGNED** | "ASSIGNED" | Promotion status | | **ACTIVE** | "ACTIVE" | Promotion status | | **REDEEMED** | "REDEEMED" | Promotion status | | **UNKNOWN** | "UNKNOWN" | Promotion status | **Methods:** This method retrieves a promotion status.
public static PromotionStatus getByPromotionStatus(String status)
--- --- --- ### PromotionType This enum contains values for a promotion type. **Declared In:** `com.synerise.sdk.promotions.model.promotion.PromotionType` **Declaration:**
```Java public enum PromotionType ```
```Kotlin public enum PromotionType ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **GENERAL** | "GENERAL" | Promotion type | | **CUSTOM** | "CUSTOM" | Promotion type | | **MEMBERS_ONLY** | "MEMBERS_ONLY" | Promotion type | | **UNKNOWN** | "UNKNOWN" | Promotion type | **Methods:** This method retrieves a promotion type.
public static PromotionType getByPromotionType(String type)
--- --- --- ### PromotionIdentifier Class model for a promotion identifier. **Declared In:** `com.synerise.sdk.promotions.model.promotion.PromotionIdentifier` **Declaration:**
```Java public class PromotionIdentifier implements Serializable ```
```Kotlin class PromotionIdentifier : Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **key** | String | no | - | Promotion key identifier | | **value** | String | no | - | Promotion identifier value | **Initializers:** There is a constructor. **Methods:** There are no methods. --- --- ### PromotionsApiQuery Class responsible for creating a promotion query. **Declared In:** `com.synerise.sdk.promotions.model.promotion.PromotionsApiQuery` **Declaration:**
```Java public class PromotionsApiQuery ```
```Kotlin class PromotionsApiQuery ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **statuses** | List<[PromotionStatus](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotionstatus)> | yes | - | List of promotion states | | **types** | List<[PromotionType](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotiontype)> | yes | - | List of promotion types | | **sortParameters** | LinkedHashMap | yes | - | Sort parameters. If you add more than one sorting attribute, the importance of each attribute depends on its position. The first one is the most important. | | **limit** | int | no | 100 | Limit of promotions per page | | **page** | int | no | 1 | Page number | | **includeMeta** | Boolean | no | false | If true, the response includes metadata |
All the properties above are accessible by using setters.
**Initializers:** There are no initializers. **Methods:** There are only setters for above properties. --- --- ## Vouchers --- ### AssignVoucherResponse Class model of AssignVoucherResponse. **Declared In:** `com.synerise.sdk.promotions.model.AssignVoucherResponse` **Declaration:**
```Java public class AssignVoucherResponse ```
```Kotlin class AssignVoucherResponse ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **message** | String | no | - | Message | | **data** | [AssignVoucherData](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#assignvoucherdata) | no | - | Voucher data |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. This method retrieves the value of the `message` parameter.
public String getMessage()
--- This method retrieves the value of the `data` parameter.
public AssignVoucherData getData()
--- --- --- ### VoucherCodesResponse Class model of VoucherCodesResponse. **Declared In:** `com.synerise.sdk.promotions.model.VoucherCodesResponse` **Declaration:**
```Java public class VoucherCodesResponse ```
```Kotlin class VoucherCodesResponse ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **data** | List<[VoucherCodesData](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#vouchercodesdata)> | no | - | Voucher data |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. This method retrieves the list of values of the `data` parameter.
public List<VoucherCodesData> getData()
--- --- --- ### AssignVoucherData Class model of AssignVoucherData. **Declared In:** `com.synerise.sdk.promotions.model.AssignVoucherData` **Declaration:**
```Java public class AssignVoucherData ```
```Kotlin class AssignVoucherData ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | no | - | Code | | **expireIn** | Date | no | - | Date of expiration | | **redeemAt** | Date | no | - | Redemption at date | | **assignedAt** | Date | no | - | Date of assigning voucher | | **createdAt** | Date | no | - | Date of creation | | **updatedAt** | Date | no | - | Date of voucher update |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. This method retrieves the value of the `code` parameter.
public String getCode()
--- This method retrieves the value of the `ExpireIn` parameter.
public Date getExpireIn()
--- This method retrieves the value of the `RedeemAt` parameter.
public Date getRedeemAt()
--- This method retrieves the value of the `AssignedAt` parameter.
public Date getAssignedAt()
--- This method retrieves the value of the `CreatedAt` parameter.
public Date getCreatedAt()
--- This method retrieves the value of the `UpdateAt` parameter.
public Date getUpdatedAt()
--- --- --- ### VoucherCodesData Class model of VoucherCodesData. **Declared In:** `com.synerise.sdk.promotions.model.VoucherCodesData` **Declaration:**
```Java public class VoucherCodesData ```
```Kotlin class VoucherCodesData ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | no | - | Voucher code | | **status** | String | no | - | Voucher status | | **clientUuid** | String | no | - | Profile's UUID | | **poolUuid** | String | no | - | Pool UUID | | **expireIn** | Date | no | - | Voucher expiration date | | **assignedAt** | Date | no | - | Voucher assignment date | | **createdAt** | Date | no | - | Voucher creation date | | **updatedAt** | Date | no | - | Voucher update date |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. --- --- --- ### VoucherCodesStatus This enum contains values for a voucher code status. **Declared In:** `com.synerise.sdk.client.model.client.VoucherCodeStatus` **Declaration:**
```Java public enum VoucherCodeStatus ```
```Kotlin public enum VoucherCodeStatus ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **ASSIGNED** | "ASSIGNED" | Assigned | | **UNASSIGNED** | "UNASSIGNED" | Unassigned | | **REDEEMED** | "REDEEMED" | Redeemed | | **CANCELED** | "CANCELED" | Canceled | **Methods:** This method retrieves the voucher status.
public String getStatus()
--- This method retrieves the voucher status.
public static VoucherCodeStatus getStatus(String status)
--- ### Customer session ## Refresh customer token --- This method refreshes the customer’s current token.
Returns an error if the token has expired and cannot be refreshed.
**Method name:** Client.refreshToken() **Declaration:**
```Java public static IApiCall refreshToken() ```
```Kotlin fun refreshToken():IApiCall ```
**Parameters:** No parameters required. **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java boolean success = Client.refreshToken(); ```
```Kotlin var success = Client.refreshToken() ```
## Retrieve customer token --- This method retrieves the customer’s current, active token.
Returns an error if the token has expired and cannot be retrieved.
**Method name:** Client.retrieveToken()
This method replaces `Client.getToken()`.
**Declaration:**
```Java public static IDataApiCall retrieveToken() ```
```Kotlin fun retrieveToken():IDataApiCall ```
**Parameters:** No parameters required. **Return Value:** [IDataApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#idataapicall)<[Token](/developers/mobile-sdk/class-reference/android/client#token)> object to execute the request. **Example:**
```Java IDataApiCall retrieveTokenCall = Client.retrieveToken(); retrieveTokenCall.execute(success -> onSuccess(), this::onFailure); ```
```Kotlin val retrieveTokenCall = Client.retrieveToken() retrieveTokenCall.execute({ success-> onSuccess() }, ({ this.onFailure() })) ```
## Get current customer UUID --- This method retrieves the customer’s current UUID. **Method name:** Client.getUuid() **Declaration:**
```Java public static String getUuid() ```
```Kotlin fun getUuid():String ```
**Parameters:** No parameters required. **Return Value:** Customer's UUID as a string. **Example:**
```Java Client.getUuid() ```
```Kotlin Client.getUuid() ```
## Get customer UUID for use in authentication --- This method retrieves the current UUID or generates a new one from a seed. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.15.0 | 5.15.0 | n/a | n/a |
This operation doesn't affect the customer session in the SDK.
**Method name:** Client.getUuidForAuthentication() **Declaration:**
```Java public static String getUuidForAuthentication(@NonNull String authId) ```
```Kotlin fun getUuidForAuthentication( authId: String ): String ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **authId** | String | yes | --- | Seed for UUID generation | **Return Value:** The UUID for use in authentication as a string. **Example:**
```Java Client.getUuidForAuthentication(authId) ```
```Kotlin Client.getUuidForAuthentication(authId) ```
## 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.3.10 | 3.3.5 | 0.9.0 | 0.7.0 | **Method name:** Client.regenerateUuid() **Declaration:**
```Java public static boolean regenerateUuid() ```
```Kotlin fun regenerateUuid():Boolean ```
**Parameters:** No parameters required. **Return Value:** Returns true if the current Customer is anonymous and the operation succeeds. **Example:**
```Java boolean success = Client.regenerateUuid(); ```
```Kotlin var success = Client.regenerateUuid() ```
## Regenerate customer with identifier --- 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. This operation clears the authentication token, login (if applicable), custom email, and custom identifier The optional `clientIdentifier` parameter is a seed for UUID generation. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.6.5 | 3.6.4 | 0.9.10 | 0.7.2 | **Method name:** Client.regenerateUuid(clientIdentifier) **Declaration:**
```Java public static boolean regenerateUuid(clientIdentifier) ```
```Kotlin fun regenerateUuid(clientIdentifier):Boolean ```
**Parameters:** | Parameter | Type | Mandatory | Description | | --- | --- | --- | --- | | **clientIdentifier** | String | no | Seed for UUID generation |
The **clientIdentifier** parameter is used for decreasing the number of UUID refreshes, so it must be unique for every customer.
**Return Value:** Returns true if the current Client is anonymous and the operation succeeds. **Example:**
```Java boolean success = Client.regenerateUuid(clientIdentifier); ```
```Kotlin var success = Client.regenerateUuid(clientIdentifier) ```
## Destroy current session --- This method destroys the session completely. This method clears all session data (both client and anonymous) and removes cached data. Then, it regenerates the UUID and creates the new anonymous session. **Method name:** Client.destroySession() **Declaration:**
```Java public static void destroySession() ```
```Kotlin fun destroySession() ```
**Parameters:** No parameters required. **Return Value:** Method is void type. **Example:**
```Java Client.destroySession(); ```
```Kotlin Client.destroySession() ```
### Recommendations and Documents ## Recommendations --- ### RecommendationResponse Model representing a response with recommendations.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/model/content/recommendation_response.dart **Related To:** [Recommendation](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendation) **Declaration:**
class RecommendationResponse
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **name** | String | no | Name of the recommendation campaign | | **campaignHash** | String | no | Hash (UUID) of the recommendation campaign | | **campaignID** | String | no | ID of the recommendation campaign | | **items** | List<[Recommendation](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendation)> | no | List of items in the recommendation | | **correlationID** | String | no | Recommendation's correlation ID. It can be added to a `recommendation.click` event to associate it with the recommendation request | | **schema** | String | no | Schema of the document which contains the recommendation | | **slug** | String | no | Slug of the document | | **uuid** | String | no | UUID of the document | --- --- ### Recommendation Model representating a recommendation item data.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/model/content/recommendation.dart **Related To:** [RecommendationResponse](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationresponse) **Declaration:**
class Recommendation
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **itemID** | String | no | Product's GTIN | | **attributes** | Map | no | Product's recommendation attributes | --- --- ### RecommendationOptions **Declared In:** lib/model/content/recommendation_options.dart **Related To:** [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationfiltersjoinerrule) **Declaration:**
class RecommendationOptions
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **slug** | String | no | Unique identifier of a document which includes a recommendation insert | | **productID** | String | yes | Item identifier (for single ID) | | **itemsIds** | List | yes | List of item identifiers (for multiple IDs) | | **itemsExcluded** | List | yes | Items that will be excluded from the generated recommendations | | **additionalFilters** | String | yes | Additional filters. These are merged with the campaign's own filters according to the logic in **filtersJoiner** | | **filtersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationfiltersjoinerrule) | yes | Defines the logic of merging additionalFilters with the campaign's existing filters | | **additionalElasticFilters** | String | yes | Additional elastic filters. These are merged with the campaign's own elastic filters according to the logic in **elasticFiltersJoiner** | | **elasticFiltersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationfiltersjoinerrule) | yes | Defines the logic of merging **additionalElasticFilters** with the campaign's existing elastic filters | | **displayAttribute** | List | yes | An array of item attributes which value will be returned in a recommendation response | | **includeContextItems** | bool | yes | When true, the recommendation response will include context item metadata | **Initializers:**
RecommendationOptions recommendationOptions = RecommendationOptions(
        slug: slug,
        productID: productId);
--- --- ### RecommendationFiltersJoinerRule **Declared In:** lib/model/content/recommendation_options.dart **Declaration:**
enum RecommendationFiltersJoinerRule {
  and('and'),
  or('or'),
  replace('replace');
**Functions:** Converts from **RecommendationFiltersJoinerRule** to **String**.
```Dart String recommendationFiltersJoinerRuleAsString() ```
Converts from **String** to **RecommendationFiltersJoinerRule**.
```Dart static RecommendationFiltersJoinerRule? getRecommendationFiltersJoinerRuleFromString(String string) ```
--- --- ## Documents --- --- ### DocumentApiQuery Object for setting parameters to facilitate fetching documents from the API. **Declared In:** lib/model/content/document_api_query.dart **Declaration:**
class DocumentApiQuery
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **slug** | String | no | Unique identifier of a document | **Properties used only if the document includes a recommendation insert:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **productId** | String | yes | Item identifier of the context item | | **itemsIds** | List | yes | List of item identifiers, used for multiple item context | | **itemsExcluded** | List | yes | Items that will be excluded from the generated recommendations | | **additionalFilters** | String | yes | Additional filters. These are merged with the campaign's own filters according to the logic in **filtersJoiner** | | **filtersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationfiltersjoinerrule) | no | Defines the logic of merging additionalFilters with the campaign's existing filters | | **additionalElasticFilters** | String | yes | Additional elastic filters. These are merged with the campaign's own elastic filters according to the logic in **elasticFiltersJoiner** | | **elasticFiltersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#recommendationfiltersjoinerrule) | no | Defines the logic of merging **additionalElasticFilters** with the campaign's existing elastic filters | | **displayAttribute** | List | yes | An array of item attributes which value will be returned in a recommendation response | | **includeContextItems** | bool | yes | When true, the recommendation response will include context item metadata | **Initializers:**
DocumentApiQuery({
  required this.slug,
  this.productId,
  this.itemsIds,
  this.itemsExcluded,
  this.additionalFilters,
  this.filtersJoiner,
  this.additionalElasticFilters,
  this.elasticFiltersJoiner,
  this.displayAttribute,
  this.includeContextItems = false
});
--- --- ### Document **Declared In:** lib/model/content/document.dart **Declaration:**
class Document
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **uuid** | String | no | Document's identifier (this parameter was called **identifier** before version 2.0.0)| | **slug** | String | no | Document's slug | | **schema** | String | no | Document's schema type | | **content** | Map | yes | Document's content |
All properties are read-only.
--- --- ## Removed symbols --- ### DocumentsApiQuery{#documentsapiquery} The object to set parameters easily for fetching documents from API. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.5.10 | 3.5.1 | 0.9.10 | 0.2.0 | | Deprecated in: | 4.13.0 | 5.5.0 | 0.17.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | The object to set parameters easily for fetching documents from API. **Declared In:** lib/model/content/documents_api_query.dart **Related To:** [DocumentsApiQueryType](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#documentsapiquerytype) **Declaration:**
class DocumentsApiQuery
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **type** | [DocumentsApiQueryType](/developers/mobile-sdk/class-reference/flutter/recommendations-and-documents#documentsapiquerytype) | no | .bySchema | Query type | | **typeValue** | String | no | null | Value for query type | | **version** | String | yes | null | Specifies the document version | **Initializers:**
DocumentsApiQuery({required this.type, required this.typeValue, this.version})
--- --- ### DocumentsApiQueryType{#documentsapiquerytype} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.5.10 | 3.5.1 | 0.9.10 | 0.2.0 | | Deprecated in: | 4.13.0 | 5.5.0 | 0.17.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/enums/content/documents_api_query_type.dart **Declaration:**
enum DocumentsApiQueryType {
  schema('by-schema');
}
### Profile identification, authentication, and management ### Promotions and Vouchers ## Promotions --- ### PromotionResponse **Declared In:** Headers/SNRPromotionResponse.h **Related To:** [PromotionResponseMetadata](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponsemetadata) [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionResponse: BaseModel ```
```Objective-C @interface SNRPromotionResponse : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **metadata** | [PromotionResponseMetadata](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponsemetadata) | yes | Metadata of the promotion response | | **items** | [[Promotion]](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotion) | no | List of promotion items |
All properties are read-only.
--- --- ### PromotionResponseMetadata **Declared In:** Headers/SNRPromotionResponseMetadata.h **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionResponseMetadata: BaseModel ```
```Objective-C @interface SNRPromotionResponseMetadata : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **totalCount** | Int | no | Total count of promotions | | **totalPages** | Int | no | Total count of pages | | **page** | Int | no | Current page | | **limit** | Int | no | Limit of promotions per page | | **code** | Int | no | HTTP code of the response |
All properties are read-only.
--- --- ### Promotion **Declared In:** Headers/SNRPromotion.h **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse) [PromotionStatus](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionstatus) [PromotionType](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiontype) [PromotionDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondetails) [PromotionItemScope](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionitemscope) [PromotionDiscountType](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscounttype) [PromotionDiscountMode](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountmode) [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountmodedetails) [PromotionImage](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionimage) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class Promotion: BaseModel ```
```Objective-C @interface SNRPromotion : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **uuid** | String | no | Promotion's UUID | | **code** | String | no | Promotion's code | | **status** | [PromotionStatus](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionstatus) | no | Promotion's status | | **type** | [PromotionType](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiontype) | no | Promotion's type | | **details** | [PromotionDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondetails) | yes | Promotion's details | | **redeemLimitPerClient** | NSNumber | yes | Redemption limit per customer | | **redeemQuantityPerActivation** | NSNumber | yes | Redemption quantity per activation | | **currentRedeemedQuantity** | NSNumber | no | Current redemption quantity | | **currentRedeemLimit** | NSNumber | no | Current redemption limit | | **activationCounter** | NSNumber | no | Promotion's activation counter | | **possibleRedeems** | NSNumber | no | Maximum number of promotion redemptions | | **requireRedeemedPoints** | NSNumber | yes | Required redeemed points | | **discountType** | [PromotionDiscountType](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscounttype) | no | Discount type | | **discountValue** | NSNumber | no | Discount value | | **discountMode** | [PromotionDiscountMode](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountmode) | no | Discount mode | | **discountModeDetails** | [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountmodedetails) | yes | Discount mode details | | **priority** | NSNumber | no | Promotion's priority | | **price** | NSNumber | no | Item price | | **itemScope** | [PromotionItemScope](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionitemscope) | no | Promotion's item scope | | **minBasketValue** | NSNumber | yes | Minimum basket value | | **maxBasketValue** | NSNumber | yes | Maximum basket value | | **name** | String | no | Promotion's name | | **headline** | String | yes | Promotion's headline | | **descriptionText** | String | yes | Promotion's description | | **images** | [[PromotionImage](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionimage)] | yes | List of promotion images | | **startAt** | Date | yes | Start time of a promotion | | **expireAt** | Date | yes | Expiration time of the promotion | | **lastingAt** | Date | yes | Date when the promotion expires for the current profile | | **lastingTime** | NSNumber | yes | Duration of the promotion in seconds | | **displayFrom** | String | yes | Date as a string when the promotion starts being displayed | | **displayTo** | String | yes | Date as a string when the promotions ends being displayed | | **catalogIndexItems** | [String] | yes | List of item indexes | | **params** | [AnyHashable: Any] | yes | Promotion's custom parameters | | **tags** | [AnyObject] | yes | Promotion's custom tags |
All properties are read-only.
--- --- ### PromotionStatus **Declared In:** Headers/SNRPromotionStatus.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Declaration:**
```Swift enum PromotionStatus: Int { none, active, assigned, redeemed } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPromotionStatus) { SNRPromotionStatusNone = 0, SNRPromotionStatusActive, SNRPromotionStatusAssigned, SNRPromotionStatusRedeemed } ```
**Functions:** Converts from **PromotionStatus** to **String**.
```Swift func SNR_PromotionStatusToString(_: PromotionStatus) -> String ```
```Objective-C NSString * SNR_PromotionStatusToString(SNRPromotionStatus type) ```
--- Converts from **String** to **PromotionStatus**.
```Swift func SNR_StringToPromotionStatus(_: String) -> PromotionStatus ```
```Objective-C SNRPromotionStatus SNR_StringToPromotionStatus(NSString * _Nullable string) ```
**Note:** The following string constants can be used in [PromotionsApiQuery](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionsapiquery) object: - SNR_PROMOTION_STATUS_NONE - SNR_PROMOTION_STATUS_ACTIVE - SNR_PROMOTION_STATUS_ASSIGNED - SNR_PROMOTION_STATUS_REDEEMED --- --- ### PromotionType **Declared In:** Headers/SNRPromotionType.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Declaration:**
```Swift enum PromotionType: Int { unknown, membersOnly, custom, general, handbill } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPromotionType) { SNRPromotionTypeUnknown = 0, SNRPromotionTypeMembersOnly, SNRPromotionTypeCustom, SNRPromotionTypeGeneral, SNRPromotionTypeHandbill } ```
**Functions:** Converts from **PromotionType** to **String**.
```Swift func SNR_PromotionTypeToString(_: PromotionType) -> String ```
```Objective-C NSString * SNR_PromotionTypeToString(SNRPromotionType type) ```
--- Converts from **String** to **PromotionType**.
```Swift func SNR_StringToPromotionType(_: String) -> PromotionType ```
```Objective-C SNRPromotionType SNR_StringToPromotionType(NSString * _Nullable string) ```
**Note:** The following string constants can be used in [PromotionsApiQuery](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionsapiquery) object: - SNR_PROMOTION_TYPE_UNKNOWN - SNR_PROMOTION_TYPE_MEMBERS_ONLY - SNR_PROMOTION_TYPE_CUSTOM - SNR_PROMOTION_TYPE_GENERAL --- --- ### PromotionItemScope **Declared In:** Headers/SNRPromotionItemScope.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Declaration:**
```Swift enum PromotionItemScope: Int { lineItem, basket } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPromotionItemScope) { SNRPromotionItemScopeLineItem = 0, SNRPromotionItemScopeBasket } ```
**Functions:** Converts from **PromotionItemScope** to **String**.
```Swift func SNR_PromotionItemScopeToString(_: PromotionItemScope) -> String ```
```Objective-C NSString * SNR_PromotionItemScopeToString(SNRPromotionItemScope scope) ```
--- Converts from **String** to **PromotionItemScope**.
```Swift func SNR_StringToPromotionItemScope(_: String) -> PromotionItemScope ```
```Objective-C SNRPromotionItemScope SNR_StringToPromotionItemScope(NSString * _Nullable string) ```
--- --- ### PromotionDetails **Declared In:** Headers/SNRPromotionDetails.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) [PromotionDiscountTypeDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscounttypedetails) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionDetails: BaseModel ```
```Objective-C @interface SNRPromotionDetails : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountType** | [PromotionDiscountTypeDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscounttypedetails) | no | Discount details |
All properties are read-only.
--- --- ### PromotionDiscountTypeDetails **Declared In:** Headers/SNRPromotionDiscountTypeDetails.h **Related To:** [PromotionDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondetails) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionDiscountTypeDetails: BaseModel ```
```Objective-C @interface SNRPromotionDiscountTypeDetails : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **name** | String | no | Discount's name | | **outerScope** | Bool | no | When `true`, the items required to trigger the promotion are different than the items included in that promotion. | | **requiredItemsCount** | Int | no | Number of items required to qualify for the discount | | **discountedItemsCount** | Int | no | Number of discounted items |
All properties are read-only.
--- --- ### PromotionDiscountMode **Declared In:** Headers/SNRPromotionDiscountType.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Declaration:**
```Swift enum PromotionDiscountMode: Int { static, step } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPromotionDiscountMode) { SNRPromotionDiscountModeStatic = 0, SNRPromotionDiscountModeStep } ```
**Functions:** Converts from **PromotionDiscountMode** to **String**.
```Swift func SNR_PromotionDiscountModeToString(_: PromotionDiscountMode) -> String ```
```Objective-C NSString * SNR_PromotionDiscountModeToString(SNRPromotionDiscountMode mode) ```
--- Converts from **String** to **PromotionDiscountMode**.
```Swift func SNR_StringToPromotionDiscountMode(_: String) -> PromotionDiscountMode ```
```Objective-C SNRPromotionDiscountMode SNR_StringToPromotionDiscountMode(NSString * _Nullable string) ```
--- --- ### PromotionDiscountModeDetails **Declared In:** Headers/SNRPromotionDiscountModeDetails.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) [PromotionDiscountStep](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountstep) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionDiscountModeDetails: BaseModel ```
```Objective-C @interface SNRPromotionDiscountModeDetails : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountSteps** | [[SNRPromotionDiscountStep]](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotion) | no | List of discount steps | | **discountUsageTrigger** | [PromotionDiscountUsageTrigger](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountusagetrigger) | no | Usage trigger for the discount |
All properties are read-only.
--- --- ### PromotionDiscountStep **Declared In:** Headers/SNRPromotionDiscountStep.h **Related To:** [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountmodedetails) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionDiscountStep: BaseModel ```
```Objective-C @interface SNRPromotionDiscountStep : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountValue** | NSNumber | no | Value of the discount | | **usageThreshold** | NSNumber | no | Usage threshold |
All properties are read-only.
--- --- ### PromotionDiscountUsageTrigger **Declared In:** Headers/SNRPromotionDiscountUsageTrigger.h **Related To:** [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotiondiscountmodedetails) **Declaration:**
```Swift enum PromotionDiscountUsageTrigger: Int { transaction, redeem } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPromotionDiscountUsageTrigger) { SNRPromotionDiscountUsageTriggerTransaction = 0, SNRPromotionDiscountUsageTriggerRedeem } ```
**Functions:** Converts from **PromotionDiscountUsageTrigger** to **String**.
```Swift func SNR_PromotionDiscountUsageTriggerToString(_: PromotionDiscountUsageTrigger) -> String ```
```Objective-C NSString * SNR_PromotionDiscountUsageTriggerToString(SNRPromotionDiscountUsageTrigger trigger) ```
--- Converts from **String** to **PromotionDiscountUsageTrigger**.
```Swift func SNR_StringToPromotionDiscountUsageTrigger(_: String) -> PromotionDiscountUsageTrigger ```
```Objective-C SNRPromotionDiscountUsageTrigger SNR_StringToPromotionDiscountUsageTrigger(NSString * _Nullable string) ```
--- --- ### PromotionImage **Declared In:** Headers/SNRPromotion.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) [PromotionImageType](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionimagetype) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionImage: BaseModel ```
```Objective-C @interface SNRPromotionImage : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **url** | String | no | Image's URL | | **type** | [PromotionImageType](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionimagetype) | no | Image type |
All properties are read-only.
--- --- ### PromotionImageType **Declared In:** Headers/SNRPromotionImageType.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Declaration:**
```Swift enum PromotionImageType: Int { image, thumbnail } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPromotionImageType) { SNRPromotionImageTypeImage = 0, SNRPromotionImageTypeThumbnail } ```
**Functions:** Converts from **PromotionImageType** to **String**.
```Swift func SNR_PromotionImageTypeToString(_: PromotionImageType) -> String ```
```Objective-C NSString * SNR_PromotionImageTypeToString(SNRPromotionImageType type) ```
--- Converts from **String** to **PromotionImageType**.
```Swift func SNR_StringToPromotionImageType(_: String) -> PromotionImageType ```
```Objective-C SNRPromotionImageType SNR_StringToPromotionImageType(NSString * _Nullable string) ```
--- --- ### PromotionDiscountType **Declared In:** Headers/SNRPromotionDiscountType.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Declaration:**
```Swift enum PromotionDiscountType: Int { none, percent, amount, 2For1, points, multibuy, exactPrice } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRPromotionDiscountType) { SNRPromotionDiscountTypeNone = 0, SNRPromotionDiscountTypePercent, SNRPromotionDiscountTypeAmount, SNRPromotionDiscountType2For1, SNRPromotionDiscountTypePoints, SNRPromotionDiscountTypeMultibuy, SNRPromotionDiscountTypeExactPrice } ```
**Functions:** Converts from **PromotionDiscountType** to **String**.
```Swift func SNR_PromotionDiscountTypeToString(_: PromotionDiscountType) -> String ```
```Objective-C NSString * SNR_PromotionDiscountTypeToString(SNRPromotionDiscountType type) ```
--- Converts from **String** to **PromotionDiscountType**.
```Swift func SNR_StringToPromotionDiscountType(_: String) -> PromotionDiscountType ```
```Objective-C SNRPromotionDiscountType SNR_StringToPromotionDiscountType(NSString * _Nullable string) ```
--- --- ### PromotionIdentifier **Declared In:** Headers/SNRPromotionIdentifier.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class PromotionIdentifier: BaseModel ```
```Objective-C @interface SNRPromotionIdentifier : SNRBaseModel ```
**Initializers:**
```Swift init(uuid: String) ```
```Objective-C - (instancetype)initWithUUID:(NSString *)UUID ```
---
```Swift init(code: String) ```
```Objective-C - (instancetype)initWithCode:(NSString *)code ```
--- --- ### PromotionsApiQuery Object for setting parameters to facilitate fetching promotions from the API. **Declared In:** Headers/SNRPromotionsApiQuery.h **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse) [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) [ApiQuerySortingOrderString](/developers/mobile-sdk/class-reference/ios/miscellaneous#apiquerysortingorder) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class PromotionsApiQuery: NSObject ```
```Objective-C @interface SNRPromotionsApiQuery : NSObject ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **statuses** | [[SNRPromotionStatusString]](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotionstatus) | no | [] | List of promotion statuses for query | | **types** | [[SNRPromotionTypeString]](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotiontype) | no | [] | List of promotion types for query | | **sorting** | [[SNRPromotionSortingKey: SNRApiQuerySortingOrderString]] | yes | [] | Specifies sorting rules for items in the response | | **limit** | Int | no | 100 | Limit of items per page in the response | | **page** | Int | no | 1 | Page number | | **includeMeta** | Bool | no | false | Specifies if meta data should be included in the response |
- Check the list of promotion sorting keys available in [Loyalty - Promotion sorting options](/developers/mobile-sdk/loyalty#promotion-sorting-options) section. - See [ApiQuerySortingOrderString](/developers/mobile-sdk/class-reference/ios/miscellaneous#apiquerysortingorder) to check ordering options.
**Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
--- --- ## Vouchers --- ### AssignVoucherResponse **Declared In:** Headers/SNRAssignVoucherResponse.h **Related To:** [AssignVoucherData](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherdata) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class AssignVoucherResponse: BaseModel ```
```Objective-C @interface SNRAssignVoucherResponse : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **message** | String | no | Message from the Voucher assignment response | | **assignVoucherData** | [AssignVoucherData](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherdata) | yes | List of vouchers in a pool |
All properties are read-only.
--- --- ### VoucherCodesResponse **Declared In:** Headers/SNRVoucherCodesResponse.h **Related To:** [SNRVoucherCodesData](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#vouchercodesdata) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class VoucherCodesResponse: BaseModel ```
```Objective-C @interface SNRVoucherCodesResponse : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **items** | [[VoucherCodesData]](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#vouchercodesdata) | no | List of voucher items |
All properties are read-only.
--- --- ### AssignVoucherData **Declared In:** Headers/SNRAssignVoucherData.h **Related To:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherresponse) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class AssignVoucherData: BaseModel ```
```Objective-C @interface SNRAssignVoucherData : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **code** | String | no | Voucher's code | | **expireIn** | Date | yes | Voucher's expiration date | | **redeemAt** | Date | yes | Voucher's redemption date | | **assignedAt** | Date | yes | Voucher's assignment date | | **createdAt** | Date | no | Voucher's creation date | | **updatedAt** | Date | no | Voucher's update date |
All properties are read-only.
--- --- ### VoucherCodesData **Declared In:** Headers/SNRVoucherCodesData.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class VoucherCodesData: BaseModel ```
```Objective-C @interface SNRVoucherCodesData : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **code** | String | no | Voucher's code | | **status** | [VoucherStatus](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#voucherstatus) | no | Voucher's status | | **clientId** | String | no | ID of the customer to whom the voucher is assigned | | **clientUuid** | String | no | UUID of the customer to whom the voucher is assigned | | **poolUuid** | String | no | Voucher's pool ID | | **expireIn** | Date | no | Voucher's expiration date | | **redeemAt** | Date | no | Voucher's redemption date | | **assignedAt** | Date | no | Voucher's assignment date | | **createdAt** | Date | no | Voucher's creation date | | **updatedAt** | Date | no | Voucher's update date|
All properties are read-only.
--- --- ### VoucherStatus **Declared In:** Headers/SNRVoucherStatus.h **Declaration:**
```Swift enum VoucherStatus: Int { unassigned, assigned, redeemed, canceled } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRVoucherStatus) { SNRVoucherStatusUnassigned = 0, SNRVoucherStatusAssigned, SNRVoucherStatusRedeemed, SNRVoucherStatusCanceled } ```
**Functions:** Converts from **VoucherStatus** to **String**.
```Swift func SNR_VoucherStatusToString(_: VoucherStatus) -> String ```
```Objective-C NSString * SNR_VoucherStatusToString(SNRVoucherStatus type) ```
--- Converts from **String** to **VoucherStatus**.
```Swift func SNR_StringToVoucherStatus(_: String) -> VoucherStatus ```
```Objective-C SNRVoucherStatus SNR_StringToVoucherStatus(NSString * _Nullable string) ```
### IP access control Within the scope of a single workspace, you can limit access to a pool of IP addresses. Users trying to access the profile from other addresses are denied. ## Checking IP policy Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getUserBpIpPolicyUsingGET). **Request:**
curl --location --request \
GET 'https://{SYNERISE_API_BASE_PATH}/uauth/settings/user-bp-ip-policy' \
--header 'Authorization: Bearer eyJhbGc..._tNS0B28LLHc'
The following response shows that IP access control is disabled.
{
    "enabled": false,
    "enableSupportSubnets": true,
    "ipPolicy": []
}
## Updating IP policy Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateUserBpIpPolicyUsingPOST). The following request enables IP allowlisting, with two addresses allowed. It also allows access from Synerise support subnets. The subnet IPs depend on the configuration.
You must send a complete list of allowed IPs every time - if a list already exists, it is overwritten by the request.
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/uauth/settings/user-bp-ip-policy' \
--header 'Authorization: Bearer eyJhbGc..._tNS0B28LLHc' \
--header 'Content-Type: application/json' \
--data-raw '{
    "enabled": true,
    "enableSupportSubnets": true,
    "ipPolicy": [
        "192.0.2.12",
        "192.0.2.15"
    ]
}'
The response includes the new settings:
{
    "enabled": true,
    "enableSupportSubnets": true,
    "ipPolicy": [
        "192.0.2.12",
        "192.0.2.15"
    ]
}
### Event tracking --- ## Set custom identifier for events --- This method sets a custom identifier in the parameters of every event. You can pass a custom identifier to match your customers in our database. **Declared In:** lib/modules/tracker/tracker_impl.dart **Class:** [TrackerImpl](/developers/mobile-sdk/class-reference/flutter/modules#tracker) **Declaration:**
Future<void> setCustomIdentifier(String customIdentifier)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identifier** | String | yes | - | Customer’s custom identifier | **Return Value:** No value is returned. **Example:**
```Dart await Synerise.tracker.setCustomIdentifier("CUSTOM_IDENTIFIER"); ```
## Set custom email for events --- This method sets a custom email in the parameters of every event. You can pass a custom email to match your customers in our database. **Declared In:** lib/modules/tracker/tracker_impl.dart **Class:** [TrackerImpl](/developers/mobile-sdk/class-reference/flutter/modules#tracker) **Declaration:**
Future<void> setCustomEmail(String customEmail)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **email** | String | yes | - | Customer’s custom email | **Return Value:** No value is returned. **Example:**
```Dart await Synerise.tracker.setCustomEmail("CUSTOM_EMAIL"); ```
## Send event --- This method sends an event.
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
- The tracker caches and enqueues all your events locally, so they all will be sent eventually. - The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
**Declared In:** lib/modules/tracker/tracker_impl.dart **Related To:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Class:** [TrackerImpl](/developers/mobile-sdk/class-reference/flutter/modules#tracker) **Declaration:**
Future<void> send(Event event)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **event** | [Event](/developers/mobile-sdk/class-reference/flutter/events#event) | yes | - | Event object | **Return Value:** No value is returned. **Example:**
```Dart final paramMap = {"firstKeyCustomParam": "TEST"}; CustomEvent event = CustomEvent("label", "flutter", paramMap); await Synerise.tracker.send(event); ```
## Flush events from Tracker --- This method forces sending the events from the queue to the server.
The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
**Declared In:** lib/modules/tracker/tracker_impl.dart **Related To:** [Event](/developers/mobile-sdk/class-reference/flutter/events#event) [CustomEvent](/developers/mobile-sdk/class-reference/flutter/events#customevent) **Class:** [TrackerImpl](/developers/mobile-sdk/class-reference/flutter/modules#tracker) **Declaration:**
Future<void> flush()
**Return Value:** No value is returned. **Example:**
```Dart await Synerise.tracker.flush(); ```
### Promotions and Vouchers ## Promotions --- ### PromotionResponse **Declared In:** lib/classes/models/Promotions/PromotionResponse.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class PromotionResponse extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **totalCount** | number | no | Total count of promotions | | **totalPages** | number | no | Total count of pages | | **page** | number | no | Current page | | **limit** | number | no | Limit of promotions per page | | **code** | number | no | HTTP code of the response | | **items** | [Array](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) | no | List of promotion items | --- --- ### Promotion **Declared In:** lib/classes/models/Promotions/Promotion.js **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionresponse) [PromotionStatus](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionstatus) [PromotionType](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiontype) [PromotionDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondetails) [PromotionItemScope](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionitemscope) [PromotionDiscountType](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscounttype) [PromotionDiscountMode](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountmode) [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountmodedetails) [PromotionImage](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionimage) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class Promotion extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **uuid** | string | no | Promotion's UUID | | **code** | string | no | Promotion's code | | **status** | [PromotionStatus](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionstatus) | yes | Promotion's status | | **type** | [PromotionType](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiontype) | yes | Promotion's type | | **details** | [PromotionDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondetails) | yes | Promotion's details | | **redeemLimitPerClient** | number | yes | Redemption limit per customer | | **redeemQuantityPerActivation** | number | yes | Redemption quantity per activation | | **currentRedeemedQuantity** | number | no | Current redemption quantity | | **currentRedeemLimit** | number | no | Current redemption limit | | **activationCounter** | number | no | Promotion's activation counter | | **possibleRedeems** | number | no | Maximum number of promotion redemptions | | **requireRedeemedPoints** | number | yes | Required redeemed points | | **discountType** | [PromotionDiscountType](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscounttype) | yes | Discount type | | **discountValue** | number | no | Discount value | | **discountMode** | [PromotionDiscountMode](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountmode) | no | Discount mode | | **discountModeDetails** | [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountmodedetails) | yes | Discount mode details | | **priority** | number | no | Promotion's priority | | **price** | number | no | Item price | | **itemScope** | [PromotionItemScope](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionitemscope) | no | Promotion's item scope | | **minBasketValue** | number | yes | Minimum basket value | | **maxBasketValue** | number | yes | Maximum basket value | | **name** | string | no | Promotion's name | | **headline** | string | yes | Promotion's headline | | **descriptionText** | string | yes | Promotion's description | | **images** | [Array<[PromotionImage](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionimage)> | yes | List of promotion images | | **startAt** | Date | yes | Start time of a promotion | | **expireAt** | Date | yes | Expiration time of the promotion | | **lastingAt** | Date | yes | Date when the promotion expires for the current profile | | **lastingTime** | number | yes | Duration of the promotion in seconds | | **displayFrom** | string | yes | Date as a string when the promotion starts being displayed | | **displayTo** | string | yes | Date as a string when the promotions ends being displayed | | **catalogIndexItems** | Array | yes | List of item indexes | | **params** | object | yes | Promotion's custom parameters | | **tags** | Array | yes | Promotion's custom tags | --- --- ### PromotionStatus **Declared In:** lib/classes/models/Promotions/PromotionStatus.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionStatus {
  None = 'NONE',
  Active = 'ACTIVE',
  Assigned = 'ASSIGNED',
  Redeemed = 'REDEEMED',
}
**Functions:** Converts from **PromotionStatus** to **string**.
function PromotionStatusToString(promotionStatus: PromotionStatus): string
--- Converts from **string** to **PromotionStatus**.
function PromotionStatusFromString(string: string): PromotionStatus
--- --- ### PromotionType **Declared In:** lib/classes/models/Promotions/PromotionType.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionType {
  Unknown = 'UNKNOWN',
  MembersOnly = 'MEMBERS_ONLY',
  Custom = 'CUSTOM',
  General = 'GENERAL',
}
**Functions:** Converts from **PromotionType** to **string**.
function PromotionTypeToString(promotionType: PromotionType): string
--- Converts from **string** to **PromotionType**.
function PromotionTypeFromString(string: string): PromotionType
--- --- ### PromotionItemScope **Declared In:** lib/classes/models/Promotions/PromotionItemScope.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionItemScope {
    LineItem = 'LINE_ITEM',
    Basket = 'BASKET'
}
**Functions:** Converts from **PromotionItemScope** to **string**.
function PromotionItemScopeToString(promotionItemScope: PromotionItemScope): string
--- Converts from **string** to **PromotionItemScope**.
function PromotionItemScopeFromString(string: string): PromotionItemScope
--- --- ### PromotionDetails **Declared In:** lib/classes/models/Promotions/PromotionDetails.js **Related To:** [PromotionDiscountTypeDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscounttypedetails) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class PromotionDetails extends BaseModel {
  discountType: PromotionDiscountTypeDetails;
}
**Properties:** Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountType** | [PromotionDiscountTypeDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscounttypedetails) | yes | Discount details | --- --- ### PromotionDiscountTypeDetails **Declared In:** lib/classes/models/Promotions/PromotionDiscountTypeDetails.js **Related To:** [PromotionDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondetails) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class PromotionDiscountTypeDetails extends BaseModel {
  name: string;
  outerScope: boolean;
  requiredItemsCount: number;
  discountedItemsCount: number;
}
**Properties:** Property | Type | Optional | Description | | --- | --- | --- | --- | | **name** | string | no | Discount’s name | | **outerScope** | boolean | no | When `true`, the items required to trigger the promotion are different than the items included in that promotion. | | **requiredItemsCount** | number | no | Number of items required to qualify for the discount | | **discountedItemsCount** | number | no | Number of discounted items | --- --- ### PromotionDiscountMode **Declared In:** lib/classes/models/Promotions/PromotionDiscountMode.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionDiscountMode {
    Static = 'STATIC',
    Step = 'STEP'
}
**Functions:** Converts from **PromotionDiscountMode** to **string**.
function PromotionDiscountModeToString(promotionDiscountMode: PromotionDiscountMode): string
--- Converts from **string** to **PromotionDiscountMode**.
function PromotionDiscountModeFromString(string: string): PromotionDiscountMode
--- --- ### PromotionDiscountModeDetails **Declared In:** lib/classes/models/Promotions/PromotionDiscountModeDetails.js **Related To:** [PromotionDiscountStep](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountstep) [PromotionDiscountUsageTrigger](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountusagetrigger) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class PromotionDiscountModeDetails extends BaseModel {
  discountSteps: Array<PromotionDiscountStep>;
  discountUsageTrigger: PromotionDiscountUsageTrigger;
}
**Properties:** Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountSteps** | Array<[PromotionDiscountStep](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountstep)> | no | List of discount steps | | **discountUsageTrigger** | [PromotionDiscountUsageTrigger](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountusagetrigger) | no | Usage trigger for the discount | --- --- ### PromotionDiscountStep **Declared In:** lib/classes/models/Promotions/PromotionDiscountStep.js **Related To:** [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiondiscountmodedetails) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class PromotionDiscountStep extends BaseModel {
  discountValue: number;
  usageThreshold: number;
}
**Properties:** Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountValue** | number | no | Value of the discount | | **usageThreshold** | number | no | Usage threshold | --- --- ### PromotionDiscountUsageTrigger **Declared In:** lib/classes/models/Promotions/PromotionDiscountUsageTrigger.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionDiscountUsageTrigger {
    Transaction = 'TRANSACTION',
    Redeem = 'REDEEM'
}
**Functions:** Converts from **PromotionDiscountUsageTrigger** to **string**.
function PromotionDiscountUsageTriggerToString(promotionDiscountUsageTrigger: PromotionDiscountUsageTrigger): string
--- Converts from **string** to **PromotionDiscountUsageTrigger**.
function PromotionDiscountUsageTriggerFromString(string: string): PromotionDiscountUsageTrigger
--- --- ### PromotionImage **Declared In:** lib/classes/models/Promotions/PromotionImage.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) [PromotionImageType](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionimagetype) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class PromotionImage extends BaseModel {
  url: string;
  type: PromotionImageType;
}
**Properties:** Property | Type | Optional | Description | | --- | --- | --- | --- | | **url** | string | no | URL of the image | | **type** | [PromotionImageType](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionimagetype) | no | Image type | --- --- ### PromotionImageType **Declared In:** lib/classes/models/Promotions/PromotionImageType.js **Related To:** [PromotionImage](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionimage) **Declaration:**
enum PromotionImageType {
  Image = 'image',
  Thumbnail = 'thumbnail'
}
**Functions:** Converts from **PromotionImageType** to **string**.
function PromotionImageTypeToString(promotionImageType: PromotionImageType): string
--- Converts from **string** to **PromotionImageType**.
function PromotionImageTypeFromString(string: string): PromotionImageType
--- --- ### PromotionDiscountType **Declared In:** lib/classes/models/Promotions/PromotionDiscountType.js **Related To:** [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionDiscountType {
  None = 'NONE',
  Percent = 'PERCENT',
  Amount = 'AMOUNT',
  TwoForOne = '2_FOR_1',
  Points = 'POINTS',
  Multibuy = 'MULTIBUY',
}
**Functions:** Converts from **PromotionDiscountType** to **string**.
function PromotionDiscountTypeToString(promotionDiscountType: PromotionDiscountType): string
--- Converts from **string** to **PromotionDiscountType**.
function PromotionDiscountTypeFromString(string: string): PromotionDiscountType
--- --- ### PromotionIdentifier **Declared In:** lib/classes/models/Promotions/PromotionIdentifier.js **Declaration:**
class PromotionIdentifier {
  key: string;
  value: string;
}
**Properties:** Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **key** | string | yes | | Promotion identifier type (see [PromotionIdentifierKey enum](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionidentifierkey))| | **value** | string | yes | | Promotion identifier value | **Initializers:**
constructor(key: PromotionIdentifierKey, value: string)
--- --- ### PromotionIdentifierKey **Declared In:** lib/classes/models/Promotions/PromotionIdentifierKey.js **Declaration:**
enum PromotionIdentifierKey {
  Uuid = 'UUID',
  Code = 'CODE',
}
--- --- ### PromotionsApiQuery Object for setting parameters to facilitate fetching promotions from the API. **Declared In:** lib/classes/models/api_queries/PromotionsApiQuery.js **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionresponse) [Promotion](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotion) **Inherits From:** [BaseApiQuery](/developers/mobile-sdk/class-reference/react-native/miscellaneous#baseapiquery) **Declaration:**
class PromotionsApiQuery extends BaseApiQuery
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **statuses** | [Array](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionstatus) | no | [] | List of promotion statuses for query | | **types** | [Array](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiontype) | no | [] | List of promotion types for query |
- Check the list of promotion sorting keys available in [Loyalty - Promotion sorting options](/developers/mobile-sdk/loyalty#promotion-sorting-options) section. - See [ApiQuerySortingOrderString](/developers/mobile-sdk/class-reference/react-native/miscellaneous#apiquerysortingorder) to check ordering options.
**Initializers:**
constructor()
--- --- ## Vouchers --- ### AssignVoucherResponse **Declared In:** lib/classes/models/Vouchers/AssignVoucherResponse.js **Related To:** [AssignVoucherData](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#assignvoucherdata) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class AssignVoucherResponse extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **message** | string | no | Message from the Voucher assignment response | | **assignVoucherData** | [AssignVoucherData](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#assignvoucherdata) | yes | List of vouchers in a pool | --- --- ### VoucherCodesResponse **Declared In:** lib/classes/models/Vouchers/VoucherCodesResponse.js **Related To:** [VoucherCodesData](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#vouchercodesdata) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class VoucherCodesResponse extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **items** | Array<[VoucherCodesData](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#vouchercodesdata)> | no | List of voucher items | --- --- ### AssignVoucherData **Declared In:** lib/classes/models/Vouchers/AssignVoucherData.js **Related To:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#assignvoucherresponse) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class AssignVoucherData extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **code** | string | no | Voucher's code | | **expireIn** | Date | yes | Voucher's expiration date | | **redeemAt** | Date | yes | Voucher's redemption date | | **assignedAt** | Date | yes | Voucher's assignment date | | **createdAt** | Date | no | Voucher's creation date | | **updatedAt** | Date | no | Voucher's update date | --- --- ### VoucherCodesData **Declared In:** lib/classes/models/Vouchers/VoucherCodesData.js **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class VoucherCodesData extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **code** | string | no | Voucher's code | | **status** | [VoucherCodeStatus](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#vouchercodestatus) | no | Voucher's status | | **clientId** | string | no | ID of the customer to whom the voucher is assigned | | **clientUuid** | string | no | UUID of the customer to whom the voucher is assigned | | **poolUuid** | string | no | Voucher's pool ID | | **expireIn** | string | no | Voucher's expiration date | | **redeemAt** | Date | no | Voucher's redemption date | | **assignedAt** | Date | no | Voucher's assignment date | | **createdAt** | Date | no | Voucher's creation date | | **updatedAt** | Date | no | Voucher's update date| --- --- ### VoucherCodeStatus **Declared In:** lib/classes/models/Vouchers/VoucherCodeStatus.js **Declaration:**
enum VoucherCodeStatus {
  Unassigned = 'UNASSIGNED',
  Assigned = 'ASSIGNED',
  Redeemed = 'REDEEMED',
  Canceled = 'CANCELED',
}
**Functions:** Converts from **VoucherCodeStatus** to **string**.
function VoucherCodeStatusToString(voucherCodeStatus: VoucherCodeStatus): string
--- Converts from **string** to **VoucherCodeStatus**.
function VoucherCodeStatusFromString(string: string): VoucherCodeStatus
### Events Events are used to store the history of a profile's activities (for example, visiting a page) and system activities which target the profile (for example, sending an email). This section describes elements of the event APIs. For event descriptions, configuration, enrichment, and more, see [Events](/docs/assets/events). ### Promotions and Vouchers ## Promotions --- ### PromotionResponse **Declared In:** lib/model/promotions/promotion_response.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Declaration:**
class PromotionResponse
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **totalCount** | int | no | Total count of promotions | | **totalPages** | int | no | Total count of pages | | **page** | int | no | Current page | | **limit** | int | no | Limit of promotions per page | | **code** | int | no | HTTP code of the response | | **items** | List<[Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion)> | no | List of promotion items | --- --- ### Promotion **Declared In:** lib/model/promotions/promotion.dart **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse) [PromotionStatus](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionstatus) [PromotionType](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiontype) [PromotionDiscountType](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscounttype) **Declaration:**
class Promotion
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **uuid** | String | no | Promotion's UUID | | **code** | String | no | Promotion's code | | **status** | [PromotionStatus](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionstatus) | yes | Promotion's status | | **type** | [PromotionType](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiontype) | yes | Promotion's type | | **details** | [PromotionDetails](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondetails) | yes | Promotion's details | | **redeemLimitPerClient** | int | yes | Redemption limit per customer | | **redeemQuantityPerActivation** | int | yes | Redemption quantity per activation | | **currentRedeemedQuantity** | int | no | Current redemption quantity | | **currentRedeemLimit** | int | no | Current redemption limit | | **activationCounter** | int | no | Promotion's activation counter | | **possibleRedeems** | int | no | Maximum number of promotion redemptions | | **requireRedeemedPoints** | int | yes | Required redeemed points | | **discountType** | [PromotionDiscountType](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscounttype) | yes | Discount type | | **discountValue** | int | no | Discount value | | **discountMode** | [PromotionDiscountMode](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscountmode) | no | Discount mode | | **discountModeDetails** | [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscountmodedetails) | yes | Discount mode details | | **priority** | int | no | Promotion's priority | | **price** | int | no | Item price | | **itemScope** | [PromotionItemScope](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionitemscope) | no | Promotion's item scope | | **minBasketValue** | int | yes | Minimum basket value | | **maxBasketValue** | int | yes | Maximum basket value | | **name** | String | no | Promotion's name | | **headline** | String | yes | Promotion's headline | | **descriptionText** | String | yes | Promotion's description | | **images** | List<[PromotionImage](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiontype)> | yes | List of promotion images | | **startAt** | DateTime | yes | Start time of a promotion | | **expireAt** | DateTime | yes | Expiration time of the promotion | | **lastingAt** | DateTime | yes | Date when the promotion expires for the current profile | | **lastingTime** | int | yes | Duration of the promotion in seconds | | **displayFrom** | String | yes | DateTime as a String when the promotion starts being displayed | | **displayTo** | String | yes | DateTime as a String when the promotions ends being displayed | | **catalogIndexItems** | List<String> | yes | List of item indexes | | **params** | Map | yes | Promotion's custom parameters | | **tags** | List<Object> | yes | Promotion's custom tags | --- --- ### PromotionStatus **Declared In:** lib/enums/promotions/promotion_status.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionStatus {
  none('NONE'),
  active('ACTIVE'),
  assigned('ASSIGNED'),
  redeemed('REDEEMED');
}
**Functions:** Converts from **PromotionStatus** to **String**.
String promotionStatusAsString()
--- Converts from **String** to **PromotionStatus**.
PromotionStatus getPromotionStatusFromString(String string)
--- --- ### PromotionType **Declared In:** lib/enums/promotions/promotion_type.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionType {
  unknown('UNKNOWN'),
  membersOnly('MEMBERS_ONLY'),
  custom('CUSTOM'),
  general('GENERAL'),
  handbill('HANDBILL');
}
**Functions:** Converts from **PromotionType** to **String**.
String promotionTypeAsString() {
--- Converts from **String** to **PromotionType**.
PromotionType getPromotionTypeFromString(String string) {
--- --- ### PromotionDiscountType **Declared In:** lib/enums/promotions/promotion_discount_type.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionDiscountType {
  none('NONE'),
  percent('PERCENT'),
  amount('AMOUNT'),
  twoForOne('2_FOR_1'),
  points('POINTS'),
  multibuy('MULTIBUY'),
  exactPrice('EXACT_PRICE');
}
**Functions:** Converts from **String** to **PromotionDiscountType**.
PromotionDiscountType getPromotionDiscountTypeFromString(String string)
--- --- ### PromotionItemScope **Declared In:** lib/enums/promotions/promotion_item_scope.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionItemScope {
  lineItem('LINE_ITEM'),
  basket('BASKET');
**Functions:** Converts from **PromotionItemScope** to **String**.
```Dart String promotionItemScopeAsString() ```
--- Converts from **String** to **PromotionItemScope**.
```Dart static PromotionItemScope getPromotionItemScopeFromString(String string) ```
--- --- ### PromotionDetails **Declared In:** lib/model/promotions/promotion_details.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) [PromotionDiscountTypeDetails](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscounttypedetails) **Declaration:**
class PromotionDetails
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountType** | [PromotionDiscountTypeDetails](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscounttypedetails) | no | Discount details |
All properties are read-only.
--- --- ### PromotionDiscountTypeDetails **Declared In:** lib/model/promotions/promotion_discount_type_details.dart **Related To:** [PromotionDetails](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondetails) **Declaration:**
class PromotionDiscountTypeDetails
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **name** | String | no | Discount's name | | **outerScope** | bool | no | When `true`, the items required to trigger the promotion are different than the items included in that promotion. | | **requiredItemsCount** | int | no | Number of items required to qualify for the discount | | **discountedItemsCount** | int | no | Number of discounted items |
All properties are read-only.
--- --- ### PromotionDiscountMode **Declared In:** lib/enums/promotions/promotion_discount_mode.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionDiscountMode {
  staticMode('STATIC'),
  stepMode('STEP');
**Functions:** Converts from **String** to **PromotionDiscountMode**.
```Dart static PromotionDiscountMode getPromotionDiscountModeFromString(String string) ```
--- --- ### PromotionDiscountModeDetails **Declared In:** lib/model/promotions/promotion_discount_mode_details.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) [PromotionDiscountStep](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscountstep) **Declaration:**
class PromotionDiscountModeDetails
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountSteps** | [PromotionDiscountStep](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) | no | List of discount steps | | **discountUsageTrigger** | [PromotionDiscountUsageTrigger](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscountusagetrigger) | no | Usage trigger for the discount |
All properties are read-only.
--- --- ### PromotionDiscountStep **Declared In:** lib/model/promotions/promotion_discount_step.dart **Related To:** [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscountmodedetails) **Declaration:**
class PromotionDiscountStep
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **discountValue** | int | no | Value of the discount | | **usageThreshold** | int | no | Usage threshold |
All properties are read-only.
--- --- ### PromotionDiscountUsageTrigger **Declared In:** lib/enums/promotions/promotion_discount_usage_trigger.dart **Related To:** [PromotionDiscountModeDetails](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiondiscountmodedetails) **Declaration:**
enum PromotionDiscountUsageTrigger {
  transaction('TRANSACTION'),
  redeem('REDEEM');
**Functions:** Converts from **PromotionDiscountUsageTrigger** to **String**.
```Dart String promotionDiscountUsageTriggerAsString() { ```
--- Converts from **String** to **PromotionDiscountUsageTrigger**.
```Dart static PromotionDiscountUsageTrigger getPromotionDiscountUsageTriggerFromString(String string) { ```
--- --- ### PromotionImage **Declared In:** lib/model/promotions/promotion_image.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) [PromotionImageType](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionimagetype) **Declaration:**
class PromotionImage
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **url** | String | no | Image's URL | | **type** | [PromotionImageType](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionimagetype) | no | Image type |
All properties are read-only.
--- --- ### PromotionImageType **Declared In:** lib/enums/promotions/promotion_image_type.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Declaration:**
enum PromotionImageType {
  image('image'),
  thumbnail('thumbnail'),
  large('large'),
  unknown('UNKNOWN');
**Functions:** Converts from **PromotionImageType** to **String**.
```Dart String promotionImageTypeAsString() { ```
--- Converts from **String** to **PromotionImageType**.
```Swift static PromotionImageType getPromotionImageTypeFromString(String string) ```
--- --- ### PromotionIdentifier **Declared In:** lib/model/promotions/promotion_identifier.dart **Declaration:**
class PromotionIdentifier {
  PromotionIdentifierKey key;
  String value;
}
**Properties:** Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **key** | String | yes | | Promotion identifier type (see [PromotionIdentifierKey enum](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionidentifierkey))| | **value** | String | yes | | Promotion identifier value | **Initializers:**
PromotionIdentifier({required this.key, required this.value});
--- --- ### PromotionIdentifierKey **Declared In:** lib/enums/promotions/promotion_identifier_key.dart **Declaration:**
enum PromotionIdentifierKey {
  uuid('UUID'),
  code('CODE');
}
--- --- ### PromotionsApiQuery Object for setting parameters to facilitate fetching promotions from the API. **Declared In:** lib/model/promotions/promotions_api_query.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) **Declaration:**
class PromotionsApiQuery
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **statuses** | List<[PromotionStatus](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionstatus)> | no | [] | List of promotion statuses for query | | **types** | List<[PromotionType](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiontype)> | no | [] | List of promotion types for query |
- Check the list of promotion sorting keys available in [Loyalty - Promotion sorting options](/developers/mobile-sdk/loyalty#promotion-sorting-options) section. - See [ApiQuerySortingOrderString](/developers/mobile-sdk/class-reference/flutter/miscellaneous#apiquerysortingorder) to check ordering options.
**Initializers:**
PromotionsApiQuery(
      {required this.statuses,
      required this.types,
      required super.sorting,
      required super.limit,
      required super.page,
      required super.includeMeta});
--- --- ## Vouchers --- ### AssignVoucherResponse **Declared In:** lib/model/vouchers/assign_voucher_response.dart **Related To:** [AssignVoucherData](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherdata) **Declaration:**
class AssignVoucherResponse
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **message** | String | no | Message from the Voucher assignment response | | **assignVoucherData** | [AssignVoucherData](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherdata) | yes | List of vouchers in a pool | --- --- ### VoucherCodesResponse **Declared In:** lib/model/vouchers/voucher_codes_response.dart **Related To:** [VoucherCodesData](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#vouchercodesdata) **Declaration:**
class VoucherCodesResponse
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **items** | List<[VoucherCodesData](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#vouchercodesdata)> | no | List of voucher items | --- --- ### AssignVoucherData **Declared In:** lib/model/vouchers/assign_voucher_data.dart **Related To:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) **Declaration:**
class AssignVoucherData
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **code** | String | no | Voucher's code | | **expireIn** | DateTime | yes | Voucher's expiration date | | **redeemAt** | DateTime | yes | Voucher's redemption date | | **assignedAt** | DateTime | yes | Voucher's assignment date | | **createdAt** | DateTime | no | Voucher's creation date | | **updatedAt** | DateTime | no | Voucher's update date | --- --- ### VoucherCodesData **Declared In:** lib/model/vouchers/voucher_codes_data.dart **Declaration:**
class VoucherCodesData
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **code** | String | no | Voucher's code | | **status** | [VoucherCodeStatus](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#vouchercodestatus) | no | Voucher's status | | **clientId** | String | no | ID of the customer to whom the voucher is assigned | | **clientUuid** | String | no | UUID of the customer to whom the voucher is assigned | | **poolUuid** | String | no | Voucher's pool ID | | **expireIn** | String | no | Voucher's expiration date | | **redeemAt** | DateTime | no | Voucher's redemption date | | **assignedAt** | DateTime | no | Voucher's assignment date | | **createdAt** | DateTime | no | Voucher's creation date | | **updatedAt** | DateTime | no | Voucher's update date| --- --- ### VoucherCodeStatus **Declared In:** lib/enums/vouchers/voucher_code_status.dart **Declaration:**
enum VoucherCodeStatus {
  unassigned('UNASSIGNED'),
  assigned('ASSIGNED'),
  redeemed('REDEEMED'),
  canceled('CANCELED');
}
**Functions:** Converts from **VoucherCodeStatus** to **String**.
String voucherCodeStatusAsString() {
--- Converts from **String** to **VoucherCodeStatus**.
VoucherCodeStatus getVoucherCodeStatusFromString(String string) {
### Customer security configuration This article presents the API methods for managing customer account security policies. ## General settings The general settings are collected under a single endpoint for your convenience. ### Checking general settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getConfigUsingGET).
curl --location --request \
GET 'https://api.{SYNERISE_API_BASE_PATH}/sauth/settings' \
--header 'Api-Version: 4.4' \
--header 'Authorization: Bearer eyJh6sNQ'
The response is a list of settings:
{
    "confirmationMailSubject": "Confirm your account",
    "confirmationMailBody": "Click <a href=\"{{client_confirmation_link}}\" > here </a> to confirm your account",
    "confirmationMailTemplateId": null,
    "tokenLifetimeInSeconds": 3600,
    "confirmationRedirectLink": null,
    "passwordResetMailTemplateId": null,
    "passwordResetMailSubject": "Reset your password",
    "passwordResetMailBody": "Password reset token: {{password_reset_hash}}",
    "voucherPoolUuid": null,
    "registrationType": "AUTOMATIC",
    "allowOverwriteCustomIdentify": false
}
### Updating general settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateAllDataUsingPOST).
When updating the settings, send values for **all settings**. Any values that are not sent will be reset to default! Before updating, you can check the current settings and copy the response into the request body, making modifications only to the settings that you want to change.
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/sauth/settings' \
--header 'Authorization: Bearer eyJ...hMpTw' \
--header 'Content-Type: application/json' \
--data-raw '{
    "confirmationMailSubject": "Confirm your account",
    "confirmationMailBody": "Click <a href=\"{{client_confirmation_link}}\" > here </a> to confirm your account",
    "confirmationMailTemplateId": null,
    "tokenLifetimeInSeconds": 1800,
    "confirmationRedirectLink": null,
    "passwordResetMailTemplateId": null,
    "passwordResetMailSubject": "Reset your password",
    "passwordResetMailBody": "Password reset token: {{password_reset_hash}}",
    "voucherPoolUuid": null,
    "registrationType": "AUTOMATIC",
    "allowOverwriteCustomIdentify": false
}'
The response returns the new settings. ## Authorization settings You can use third-party authentication mechanisms. See more in [Profile authentication](/developers/api/api-authorization/client-login). ### Checking OAuth settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getOauthSettingsUsingGET).
curl --request GET 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/oauth 
  --header 'authorization: Bearer eyJh...MpTw'
The response includes the current settings. ### Updating OAuth settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateOatuhSettingsUsingPOST).
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/oauth 
  --header 'authorization: Bearer eyJ...hMpTw' 
  --header 'content-type: application/json' 
  --data '{
    "name": "self",
    "endpoint": "https://{SYNERISE_API_BASE_PATH}/mockOauth",
    "headers": {
        "Accept": "application/json",
        "Authorization": "Bearer {{ token }}"
    },
    "mapping": {
        "firstname": "firstName",
        "phone": "phone",
        "id": "clientId",
        "email": "email",
        "lastname": "lastName"
    },
    "mappedExternal": true
}'
The response includes the new settings. ### Checking Sign in with Apple settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getAppleAuthSettingsUsingGET).
curl --request GET 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/oauth/apple 
  --header 'authorization: Bearer eyJh...MpTw'
The response includes the current settings. ### Updating Sign in with Apple settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateAppleAuthSettingsUsingPOST).
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/oauth 
  --header 'authorization: Bearer eyJ...hMpTw' 
  --header 'content-type: application/json' 
  --data '{
    "enabled": true,
    "bundle": "bundleName"
}'
The response includes the new settings. ## Password policy You can enforce the length of passwords and the kind of characters they must include. ### Checking password policy settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getPasswordPolicySettingsUsingGET).
curl --request GET 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/password-policy 
  --header 'authorization: Bearer eyJ...hMpTw'
The response includes the current settings. ### Updating password policy settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updatePasswordPolicySettingsUsingPOST).
curl --location --request \
POST 'https://{SYNERISE_API_BASE_PATH}/sauth/settings/password-policy' \
--header 'Authorization: Bearer eyJhb...jzcU' \
--header 'Content-Type: application/json' \
--data-raw '{
    "requireAtLeastOneUppercaseLetter": true,
    "requireAtLeastOneLowercaseLetter": true,
    "requireAtLeastOneNumber": true,
    "requireAtLeastOneNonAlphaNumericCharacter": true,
    "minLength": 6,
    "maxLength": 255
}'
## Bans Bans allow you to limit or block access after a number of unsuccessful log in attempts. ### Checking ban settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getBanSettingsUsingGET).
curl --request GET 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/ban 
  --header 'authorization: Bearer eyJ...hMpTw'
### Updating ban settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateBanSettingsUsingPOST).
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/ban 
  --header 'authorization: Bearer eyJ...hMpTw' 
  --header 'content-type: application/json' 
  --data '{
        "blockingForClientEnabled": true,
        "firstBanCollectingTime": 60,
        "firstBanThreshold": 3,
        "firstBanDuration": 300,
        "secondBanCollectingTime": 1200,
        "secondBanThreshold": 10,
        "secondBanDuration": 1800,
        "permanentBanCollectingTime": 86400,
        "permanentBanThreshold": 15,
        "permanentBanDuration": 31556926
}'
The response includes the new settings. ## Device authorization You can allow customers to control access from unknown devices. To authorize devices, see [Customer devices](/developers/api/clients/devices). ### Checking device authorization settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getDeviceControlSettingsUsingGET).
curl --request GET 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/device-control 
  --header 'authorization: Bearer eyJ...hMpTw'
### Updating device authorization settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateDeviceSettingsUsingPOST).
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/device-control 
  --header 'authorization: Bearer eyJ...hMpTw' 
  --header 'content-type: application/json' 
  --data '{
        "deviceControlMode": "ON",
        "hardMailTitle": "New sign-in attempt to your account",
        "hardMailBody": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n</head>\n<body>\n\n<pre>\n\nHello,\n\nWe have noticed new sign-in attempt to your account from device we do not recognise.\n\nIP: {{ ip }}\nCountry: {{ country }}\n\nTime: {{ login_time }}\n\nIf it's you who signed-in from new device please confirm by clicking below link\n    <a href=\"{{ device_control_url }}\">{{ device_control_url }}</a>\n\n    But if you do not recognise this sign-in attempt, we recommend you to change your password from within the App and also check if your email haven't been part os known password leaks, you can do that through <a href=\"https://haveibeenpwned.com/\">https://haveibeenpwned.com/</a> or <a href=\"https://monitor.firefox.com/\">https://monitor.firefox.com/</a>.\nIn case you noticed that there are results related to you on either of these sites please review your passwords across all of the online services you use.\n\nAll the best,\nSynerise Team\n</pre>\n</body>\n</html>",
        "hardTemplateId": null,
        "softMailTitle": "New sign-in to your account",
        "softMailBody": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n</head>\n<body>\n\n<pre>\n\nHello,\n\nWe have noticed a sign-in to your account from the following location.\n\nIP: {{ ip }}\nCountry: {{ country }}\n\nTime: {{ login_time }}\n\n\nBut if you do not recognise this sign-in attempt, we recommend you to change your password from within the App and also check if your email haven't been part os known password leaks, you can do that through <a href=\"https://haveibeenpwned.com/\">https://haveibeenpwned.com/</a> or <a href=\"https://monitor.firefox.com/\">https://monitor.firefox.com/</a>.\nIn case you find results related to you on either of these sites, we strongly recommend to review your passwords across all of the online services you use.\n\nAll the best,\nSynerise Team\n</pre>\n</body>\n</html>",
        "softTemplateId": null
    }'
The response includes the new settings. ## Email change These settings affect the message that a customer receives when they want to change their email address. ### Checking email change settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/getClientEmailChangeSettingsUsingGET).
curl --request GET 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/email-change 
  --header 'authorization: Bearer eyJ...hMpTw'
### Updating email change settings Method reference available [here](https://developers.synerise.com/IdentityandAccessManagement/IdentityandAccessManagement.html#operation/updateEmailClientChangeSettingsUsingPOST).
curl --request POST 
  --url https://{SYNERISE_API_BASE_PATH}/sauth/settings/email-change 
  --header 'authorization: Bearer eyJ...hMpTw' 
  --header 'content-type: application/json' 
  --data '{
        "clientEmailChangeRequestMailSubject": "Confirm your mail",
        "clientEmailChangeRequestMailBody": "To confirm your mail click <a href=\"{{client_email_change_url}}\" > here </a>",
        "clientEmailChangeRequestMailTemplateId": null,
        "clientEmailChangeNotificationMailSubject": "Your email is going to be changed",
        "clientEmailChangeNotificationMailBody": "You are going to change your mail for {{new_email}}. If it is not you please change your password as soon as possible.",
        "clientEmailChangeNotificationMailTemplateId": null
    }'
The response includes the new settings. ### Campaigns --- ## Set Injector listener --- This method sets callbacks for an injector module. **Declared In:** lib/modules/injector/injector_impl.dart **Related To:** [InjectorListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-listener) **Class:** [InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector) **Declaration:**
void listener(InjectorListenerFunction listenerFunction)
**Discussion:** Learn more about the methods and their purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-listener). ## Set In-App Message listener --- This method sets callbacks for in-app message campaigns. **Declared In:** lib/modules/injector/injector_impl.dart **Related To:** [InjectorInAppMessageListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-in-app-message-listener) **Class:** [InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector) **Declaration:**
void inAppMessageListener(InjectorInAppMessageListenerFunction listenerFunction)
**Discussion:** Learn more about the methods and their purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-in-app-message-listener). ## Close in-app message --- 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. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | ----------------------------------------------- | ----------- | --------------- | -------------------- | --------------- | | Introduced in: | 5.7.0 | 6.7.0 | 1.5.0 | 2.5.0 | **Declared In:** lib/modules/injector/injector_impl.dart **Declaration:**
void closeInAppMessage(String campaignHash)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | ---------------- | ------ | --------- | ------- | ---------------------------------------- | | **campaignHash** | string | yes | - | Unique identifier of the in-app campaign | ## Register for push notifications --- This method passes the Firebase Token to Synerise for notifications.
- You should call this method every time the user changes the system or application consent for notifications. - The API key must have the `API_PERSONAL_DEVICE_CLIENT_UPDATE` permission from the **Client** group. - If the registration fails, the SDK requests a token update again by a listener/delegate method ([Android](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener), [iOS](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed), [React Native](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener), [Flutter](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener)).
**Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications)
**Declaration:**
Future<void> registerForNotifications(String registrationToken,
      {bool? mobileAgreement,
      required void Function() onSuccess,
      required void Function(SyneriseError error) onError})
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **registrationToken** | String | yes | - | Firebase Token | | **mobileAgreement** | bool | no | null | Agreement (consent) for receiving mobile push campaigns | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned.
This method also allows using the `registerForPushWithoutAgreement` native method. The `registerForPushWithoutAgreement` method will be used when the `mobileAgreement` parameter is not filled.
**Example:**
FirebaseMessaging.instance.onTokenRefresh.listen((event) {
      FirebaseMessaging.instance.getToken().then((token) {
        if (token != null) {
          firebaseToken = token;
          Synerise.notifications.registerForNotifications(
            firebaseToken!,
            mobileAgreement: true,
            onSuccess: () {},
            onError: (error) {},
          );
        }
      });
    });
**Declaration:**
Future<void> registerForNotifications(String registrationToken, [bool? mobileAgreement])
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **registrationToken** | String | yes | - | Firebase Token | | **mobileAgreement** | bool | no | null | Agreement (consent) for receiving mobile push campaigns | **Return Value:** No value is returned.
This method also allows to use `registerForPushWithoutAgreement` native method. The `registerForPushWithoutAgreement` method will be used when the `mobileAgreement` parameter is not filled.
**Example:**
FirebaseMessaging.instance.onTokenRefresh.listen((event) {
      FirebaseMessaging.instance.getToken().then((token) {
        if (token != null) {
          firebaseToken = token;
          Synerise.notifications.registerForNotifications(
            firebaseToken!,
            mobileAgreement: true,
          );
        }
      });
    });
## Handle Synerise push notification --- This method handles a notification payload and starts activity. **Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) **Declaration:**
Future<bool> handleNotification(Map notification) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notification** | Map | yes | - | Notification’s key-value data object | **Return Value:** **true** if the notification is handled properly. **Example:**
```Dart FirebaseMessaging.onMessage.listen((RemoteMessage message,) { Synerise.notifications.handleNotification(message.toMap()); }); FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { Synerise.notifications.handleNotificationClick(message.toMap()); }); ```
## Handle Synerise push notification click --- This method handles a notification payload with a user interaction and starts activity. **Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) **Declaration:**
Future<bool> handleNotificationClick(Map notification) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notification** | Map | yes | - | Notification’s key-value data object | **Return Value:** **true** if the notification is handled properly. **Example:**
```Dart FirebaseMessaging.onMessage.listen((RemoteMessage message,) { Synerise.notifications.handleNotification(message.toMap()); }); FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { Synerise.notifications.handleNotificationClick(message.toMap()); }); ```
## Check if push notification is from Synerise --- This method verifies if a notification was sent by Synerise. **Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) **Declaration:**
Future<bool> isSyneriseNotification(Map notification) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notification** | Map | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is provided by Synerise, otherwise returns **false**. **Example:**
```Dart bool isSyneriseNotification = await Synerise.notifications.isSyneriseNotification(remoteMessageMap); ```
## 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 Simple Push campaign **Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) **Declaration:**
Future<bool> isSyneriseSimplePush(Map notification) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notification** | Map | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Simple Push provided by Synerise, otherwise returns **false**. **Example:**
```Dart bool isSyneriseSimplePush = await Synerise.notifications.isSyneriseSimplePush(remoteMessageMap); ```
## 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 Command. **Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) **Declaration:**
Future<bool> isSilentCommand(Map notification) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notification** | Map | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Silent Command provided by Synerise, otherwise returns **false**. **Example:**
```Dart bool isSilentCommand = await Synerise.notifications.isSilentCommand(remoteMessageMap); ```
## 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 Silent SDK Command. **Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) **Declaration:**
Future<bool> isSilentSDKCommand(Map notification) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notification** | Map | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Silent SDK Command provided by Synerise, otherwise returns **false**. **Example:**
```Dart bool isSilentSDKCommand = await Synerise.notifications.isSilentSDKCommand(remoteMessageMap); ```
## Removed methods ### Check if push notification is a Banner Campaign {#check-if-push-notification-is-a-banner-campaign} --- This method verifies if a notification’s sender is Synerise and if the notification is a Banner campaign. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** lib/modules/notifications/notifications_impl.dart **Class:** [NotificationsImpl](/developers/mobile-sdk/class-reference/flutter/modules#notifications) **Declaration:**
Future<bool> isSyneriseBanner(Map notification) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notification** | Map | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Banner provided by Synerise, otherwise returns **false**. **Example:**
```Dart bool isSyneriseBanner = await Synerise.notifications.isSyneriseBanner(remoteMessageMap); ```
### Get Walkthrough {#get-walkthrough} --- This method fetches a walkthrough. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 |
The API key must have the `CAMPAIGN_BACKEND_CAMPAIGN_READ` permission from the **Campaign** group.
**Declared In:** lib/modules/injector/injector_impl.dart **Class:** [InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector) **Declaration:**
void getWalkthrough()
**Return Value:** No value is returned. **Example:**
```Dart Synerise.injector.getWalkthrough(); ```
### Show Walkthrough {#show-walkthrough} --- This method shows a walkthrough when it is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/modules/injector/injector_impl.dart **Class:** [InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector) **Declaration:**
void showWalkthrough()
**Return Value:** No value is returned. **Example:**
```Dart Synerise.injector.showWalkthrough(); ```
### Check if Walkthrough is loaded {#check-if-walkthrough-is-loaded} --- This method checks if a walkthrough is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/modules/injector/injector_impl.dart **Class:** [InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector) **Declaration:**
Future<bool> isWalkthroughLoaded()
**Return Value:** **true** if the walkthrough is loaded, otherwise returns **false**. **Example:**
```Dart var isLoaded = await Synerise.injector.isWalkthroughLoaded(); ```
### Check if is loaded Walkthrough unique {#check-if-is-loaded-walkthrough-unique} --- This method checks if the walkthrough is unique compared to the previous one. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/modules/injector/injector_impl.dart **Class:** [InjectorImpl](/developers/mobile-sdk/class-reference/flutter/modules#injector) **Declaration:**
Future<bool> isLoadedWalkthroughUnique()
**Return Value:** **true** if the loaded walkthrough is unique, otherwise returns **false**. **Example:**
```Dart var isLoaded = await Synerise.injector.isLoadedWalkthroughUnique(); ```
### Event tracking ## Get customer's events --- This method retrieves events for an authenticated customer. This method requires customer authentication. **Method name:** Client.getEvents(clientEventsQuery) **Declaration:**
```Java public static IDataApiCall> getEvents(ClientEventsQuery clientEventsQuery) ```
```Kotlin fun getEvents(clientEventsQuery:ClientEventsQuery):IDataApiCall> ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **clientEventsQuery** | ClientEventsQuery | yes | - | Object to create clientEvent query | **Return Value:** [IDataApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#idataapicall)> object to execute the request. **Example:**
```Java private IDataApiCall> getEventClientsCall; if (getEventClientsCall != null) getEventClientsCall.cancel(); getEventClientsCall = Client.getEvents(clientEventsQuery); getEventClientsCall.execute(({ this.onSuccess() }), ({ this.onFailure() }); ```
```Kotlin private val getEventClientsCall:IDataApiCall> if (getEventClientsCall != null) getEventClientsCall.cancel() getEventClientsCall = Client.getEvents(clientEventsQuery) getEventClientsCall.execute(({ this.onSuccess() }), ({ this.onFailure() }) ```
## Set custom identifier for events --- This method sets a custom identifier in the parameters of every event. You can pass a custom identifier to match your customers in our database. **Method name:** Tracker.setCustomIdentifier(customIdentifier) **Declaration:**
```java public static void setCustomIdentifier(String customIdentifier) ```
```kotlin fun setCustomIdentifier(customIdentifier:String) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **customIdentifier** | String | yes | - | Client's custom identifier | **Return Value:** Void type method. **Example:**
```java Tracker.setCustomIdentifier(customIdentifier) ```
```kotlin Tracker.setCustomIdentifier(customIdentifier) ```
## Set custom email for events --- This method sets a custom email in the parameters of every event. You can pass a custom email to match your customers in our database. **Method name:** Tracker.setCustomEmail(customEmail) **Declaration:**
```java public static void setCustomEmail(String customEmail) ```
```kotlin fun setCustomEmail(customEmail:String) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **customEmail** | String | yes | - | Customer's email | **Return Value:** Void type method. **Example:**
```java private void setCustomEmail(String customEmail) { Tracker.setCustomEmail(customEmail); } ```
```kotlin private fun setCustomEmail(customEmail:String) { Tracker.setCustomEmail(customEmail) } ```
## Send event --- This method sends an event.
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
- The tracker caches and enqueues all your events locally, so they all will be sent eventually. - The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
It also supports Android O's [Background Execution Limits](https://developer.android.com/about/versions/oreo/background.html). **Method name:** Tracker.send(event) **Declaration:**
```java public static void send(Event event) ```
```kotlin fun send(event:Event) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **event** | Event | yes | - | Event object (e.g. `CustomEvent()` instance). | **Return Value:** Void type method. **Example:**
```java Tracker.send(new CustomEvent("my.action", "label")); ```
```kotlin Tracker.send(CustomEvent("my.action", "label")) ```
## Flush events from Tracker --- This method forces sending the events from the queue to the server.
The API key must have the `API_BATCH_EVENTS_CREATE` permission from the **Events** group.
**Method name:** Tracker.flush() **Declaration:**
```java public static void flush() ```
```kotlin fun flush() ```
**Parameters:** No parameters required. **Return Value:** Void type method. **Example:**
```java Tracker.flush(); ```
```kotlin Tracker.flush(); ```
### Recommendations and Documents ## Recommendations --- ### RecommendationResponse **Declared In:** lib/classes/content/RecommendationResponse.js **Related To:** [Recommendation](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#recommendation) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class RecommendationResponse extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **name** | string | no | Name of the recommendation campaign | | **campaignHash** | string | no | Hash (UUID) of the recommendation campaign | | **campaignID** | string | no | ID of the recommendation campaign | | **items** | [Array](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#recommendation) | no | List of items in the recommendation | --- --- ### Recommendation Model representating a recommendation item data.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/classes/Content/Recommendation.js **Related To:** [RecommendationResponse](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#recommendationresponse) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class Recommendation extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **itemID** | string | no | Product's GTIN | | **attributes** | Record | no | Product's recommendation attributes | --- --- ### RecommendationOptions **Declared In:** lib/classes/content/RecommendationOptions.js **Declaration:**
class RecommendationOptions
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **slug** | string | no | Unique identifier of a document which includes a recommendation insert | | **productID** | string | no | Item identifier of the context item | --- --- ### RecommendationFiltersJoinerRule **Declared In:** lib/classes/models/Content/RecommendationOptions.js **Declaration:**
enum RecommendationFiltersJoinerRule {
  And = 'AND',
  Or = 'OR',
  Replace = 'REPLACE'
}
--- --- ## Documents --- ### DocumentApiQuery The object to set parameters easily for fetching screen views from API. **Declared In:** lib/classes/api_queries/DocumentApiQuery.js **Declaration:**
class DocumentApiQuery
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **slug** | string | no | Unique identifier of a document | **Properties used only if the document includes a recommendation insert:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **productId** | string | yes | Item identifier of the context item | | **itemsIds** | Array | yes | List of item identifiers, used for multiple item context | | **itemsExcluded** | Array | yes | Items that will be excluded from the generated recommendations | | **additionalFilters** | string | yes | Additional filters. These are merged with the campaign's own filters according to the logic in **filtersJoiner** | | **filtersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#recommendationfiltersjoinerrule) | no | Defines the logic of merging additionalFilters with the campaign's existing filters | | **additionalElasticFilters** | string | yes | Additional elastic filters. These are merged with the campaign's own elastic filters according to the logic in **elasticFiltersJoiner** | | **elasticFiltersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#recommendationfiltersjoinerrule) | no | Defines the logic of merging **additionalElasticFilters** with the campaign's existing elastic filters | | **displayAttribute** | Array | yes | An array of item attributes which value will be returned in a recommendation response | | **includeContextItems** | boolean | yes | When true, the recommendation response will include context item metadata | **Initializers:**
constructor()
--- --- ### Document Model representing a highest-priority customer screen view campaign.
This is a read-only class and it is not meant to be instantiated directly.
**Declared In:** lib/classes/content/Document.js **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/react-native/miscellaneous#basemodel) **Declaration:**
class Document extends BaseModel
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **uuid** | string | no | Document's identifier (UUID) | | **slug** | string | no | Document's slug | | **schema** | string | no | Document's schema type | | **content** | object | no | Document's content | --- --- ## Removed symbols --- ### DocumentsApiQuery{#documentsapiquery} The object to set parameters easily for fetching documents from API. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.5.10 | 3.5.1 | 0.9.10 | 0.2.0 | | Deprecated in: | 4.13.0 | 5.5.0 | 0.17.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | The object to set parameters easily for fetching documents from API. **Declared In:** lib/classes/api_queries/DocumentsApiQuery.js **Related To:** [DocumentsApiQueryType](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#documentsapiquerytype) **Declaration:**
class DocumentsApiQuery
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **type** | [DocumentsApiQueryType](/developers/mobile-sdk/class-reference/react-native/recommendations-and-documents#documentsapiquerytype) | no | .bySchema | Query type | | **typeValue** | string | no | nil | Value for query type | | **version** | string | yes | nil | Specifies the document version | **Initializers:**
constructor(type: DocumentsApiQueryType, typeValue: string, version: string)
--- --- ### DocumentsApiQueryType {#documentsapiquerytype} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.5.10 | 3.5.1 | 0.9.10 | 0.2.0 | | Deprecated in: | 4.13.0 | 5.5.0 | 0.17.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/classes/api_queries/DocumentsApiQueryType.js **Declaration:**
enum DocumentsApiQueryType {
    SCHEMA = 'by-schema',
}
### Recommendations and Documents ## Recommendations --- ### RecommendationResponse **Declared In:** Headers/SNRRecommendationResponse.h **Related To:** [Recommendation](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendation) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class RecommendationResponse ```
```Objective-C @interface SNRRecommendationResponse ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **name** | String | no | Name of the recommendation campaign | | **campaignHash** | String | no | Hash (UUID) of the recommendation campaign | | **campaignID** | String | no | ID of the recommendation campaign | | **correlationID** | String | no | Recommendation's correlation ID. It can be added to a `recommendation.click` event to associate it with the recommendation request | | **extras** | RecommendationResponseExtras | yes | Additional details of the recommendation | | **schema** | String | no | Schema of the document which contains the recommendation| | **slug** | String | no | Slug of the document | | **uuid** | String | no | UUID of the document | | **items** | [[Recommendation]](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents/#recommendation) | no | List of items in the recommendation | --- --- ### Recommendation **Declared In:** Headers/SNRRecommendation.h **Related To:** [RecommendationResponse](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendationresponse) **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class Recommendation ```
```Objective-C @interface SNRRecommendation ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **itemID** | String | no | Product's GTIN | | **attributes** | [AnyHashable: Any] | no | Product’s recommendation attributes | --- --- ### RecommendationOptions **Declared In:** Headers/SNRRecommendationOptions.h **Related To:** [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendationfiltersjoinerrule) **Declaration:**
```Swift class RecommendationOptions ```
```Objective-C @interface SNRRecommendationOptions ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **slug** | String | no | Unique identifier of a document which includes a recommendation insert | | **productID** | String | no | Item identifier of the context item | | **productIDs** | [String] | no | List of item identifiers, used for multiple item context | | **itemsExcluded** | [String] | no | Items that will be excluded from the generated recommendations | | **additionalFilters** | String | no | Additional filters. These are merged with the campaign's own filters according to the logic in **filtersJoiner** | | **filtersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendationfiltersjoinerrule) | no | Defines the logic of merging additionalFilters with the campaign's existing filters | | **additionalElasticFilters** | String | no | Additional elastic filters. These are merged with the campaign's own elastic filters according to the logic in **elasticFiltersJoiner** | | **elasticFiltersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendationfiltersjoinerrule) | no | Defines the logic of merging **additionalElasticFilters** with the campaign's existing elastic filters | | **displayAttribute** | [String] | no | An array of item attributes which value will be returned in a recommendation response | | **includeContextItems** | Bool | no | When true, the recommendation response will include context item metadata | --- --- ### RecommendationFiltersJoinerRule **Declared In:** Headers/SNRRecommendationOptions.h **Declaration:**
```Swift enum RecommendationFiltersJoinerRule: Int { and, or, replace } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRRecommendationFiltersJoinerRule) { SNRRecommendationFiltersJoinerRuleAnd, SNRRecommendationFiltersJoinerRuleOr, SNRRecommendationFiltersJoinerRuleReplace } ```
**Functions:** Converts from **RecommendationFiltersJoinerRule** to **String**.
```Swift func SNR_RecommendationFiltersJoinerRuleToString(_: RecommendationFiltersJoinerRule) -> String ```
```Objective-C NSString * SNR_RecommendationFiltersJoinerRuleToString(SNRRecommendationFiltersJoinerRule rule) ```

--- --- ## Documents --- ### DocumentApiQuery The object to set parameters easily for fetching documents from API. **Declared In:** Headers/SNRDocumentApiQuery.h **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class DocumentApiQuery: NSObject ```
```Objective-C @interface SNRDocumentApiQuery : NSObject ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **slug** | String | no | nil | Unique identifier of a document | **Properties used only if the document includes a recommendation insert:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **productId** | String | yes | Item identifier of the context item | | **itemsIds** | [String] | yes | List of item identifiers, used for multiple item context | | **itemsExcluded** | [String] | yes | Items that will be excluded from the generated recommendations | | **additionalFilters** | String | yes | Additional filters. These are merged with the campaign's own filters according to the logic in **filtersJoiner** | | **filtersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendationfiltersjoinerrule) | yes | Defines the logic of merging additionalFilters with the campaign's existing filters | | **additionalElasticFilters** | String | yes | Additional elastic filters. These are merged with the campaign's own elastic filters according to the logic in **elasticFiltersJoiner** | | **elasticFiltersJoiner** | [RecommendationFiltersJoinerRule](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#recommendationfiltersjoinerrule) | yes | Defines the logic of merging **additionalElasticFilters** with the campaign's existing elastic filters | | **displayAttribute** | [String] | yes | An array of item attributes which value will be returned in a recommendation response | | **includeContextItems** | Bool | yes | When true, the recommendation response will include context item metadata | | **params** | [String: Any] | yes | Additional parameters to pass for [Inserts in the document](/developers/inserts/screen-views-documents#handling-variables-when-displaying-screen-viewsdocuments). For example, if the insert is `{{ foo }}`, you need to pass the value of `foo` | **Initializers:**
```Swift init(slug: String) ```
```Objective-C - (instancetype)initWithSlug:(NSString *)slug ```
--- --- ### Document **Declared In:** Headers/SNRDocument.h **Inherits From:** [BaseModel](/developers/mobile-sdk/class-reference/ios/miscellaneous#basemodel) **Declaration:**
```Swift class Document: BaseModel ```
```Objective-C @interface SNRDocument : SNRBaseModel ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **uuid** | String | no | Document's identifier (this parameter was called **identifier** before version 5.0.0) | | **slug** | String | no | Document's slug | | **schema** | String | no | Document's schema type | | **content** | [AnyHashable: Any] | no | Document's content |
All properties are read-only.
--- --- ## Removed symbols --- ### DocumentsApiQuery{#documentsapiquery} The object to set parameters easily for fetching documents from API. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.5.10 | 3.5.1 | 0.9.10 | 0.2.0 | | Deprecated in: | 4.13.0 | 5.5.0 | 0.17.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** Headers/SNRDocumentsApiQuery.h **Related To:** [DocumentsApiQueryType](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#documentsapiquerytype) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class DocumentsApiQuery: NSObject ```
```Objective-C @interface SNRDocumentsApiQuery : NSObject ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **type** | [DocumentsApiQueryType](/developers/mobile-sdk/class-reference/ios/recommendations-and-documents#documentsapiquerytype) | no | .bySchema | Query type | | **typeValue** | String | no | nil | Value for query type | | **version** | String | yes | nil | Specifies the document version | **Initializers:**
```Swift init(type: DocumentsApiQueryType, value: String) ```
```Objective-C - (instancetype)initWithType:(SNRDocumentsApiQueryType)type typeValue:(nonnull NSString *)typeValue ```
--- --- ### DocumentsApiQueryType{#documentsapiquerytype} **Declared In:** Headers/SNRDocumentsApiQueryType.h **Declaration:**
```Swift enum DocumentsApiQueryType: Int { bySchema } ```
```Objective-C typedef NS_ENUM(NSInteger, SNRDocumentsApiQueryType) { SNRDocumentsApiQueryTypeBySchema } ```
### Transactions and basket events Tracking transactions lets you use features such as eCommerce analytics, product purchase segmentation, or cart/transaction based automations. ## Authentication Requests to the SDK may require customer authentication. For more details, see [this article](/developers/web/jwt-auth). ## Using Google Data Layer If you use [Google Analytics 4 e-commerce](https://developers.google.com/analytics/devguides/collection/ga4/ecommerce), you can send data to it when using Synerise event tracking.
If you created the tracking code with the [generator](/developers/web/installation-and-configuration#creating-a-tracking-code), you don't need to edit it.
If your tracking code was created without the generator, add the `dataLayer` and `gaVersion` properties to `SR.init()`:
SR.init({
    "trackerKey":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "dataLayer": dataLayer,
    "gaVersion": "CHOOSE_VERSION"
});
The `gaVersion` parameter is used to set the Google Analytics implementation. You can only choose one implementation for use with Synerise tracking. - To send events to Google Analytics 4 Tag Manager implementation, set the value to `GA_4` - To send events to Google Analytics 4 gtag.js implementation, set the value to `GA_4_TAG` When you send events to Google Data Layer, some item parameters are saved in Synerise under different names than in the Data Layer request: | Parameter name in Data Layer | Parameter name in Synerise | | ---------------------------- | -------------------------------------------------------------------- | | `item_category` | `$categories` (array) | | `item_id` | `$sku` | | `price` | `$finalUnitPrice` | | `item_name` | `$title` | | `quantity` | `$quantity` | | `value`/`revenue` | `$totalAmount` | | `transaction_id` | `orderId` | | `item_*` | `item_` is removed, for example `item_variant` is saved as `variant` | Other parameters are saved without changing their names. ### Product added to shopping cart This call creates a [`product.addToCart` event](/docs/assets/events/event-reference/items#productaddtocart).
dataLayer.push({
  event: "add_to_cart",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});
gtag("event", "add_to_cart", {
  currency: "USD",
  value: 7.77,
  items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
  ]
});
### Product removed from shopping cart This call creates a [`product.removeFromCart` event](/docs/assets/events/event-reference/items#productremovefromcart).
dataLayer.push({
  event: "remove_from_cart",
  ecommerce: {
    currency: "USD",
    value: 7.77,
    items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
    ]
  }
});
gtag("event", "remove_from_cart", {
  currency: "USD",
  value: 7.77,
  items: [
    {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    }
  ]
});
### Purchase details This call creates a [`transaction.charge` event](/docs/assets/events/event-reference/items#transactioncharge) and corresponding [`product.buy` events](/docs/assets/events/event-reference/items#productbuy).
dataLayer.push({
  event: "purchase",
  ecommerce: {
      transaction_id: "T_12345",
      value: 25.42,
      tax: 4.90,
      shipping: 5.99,
      currency: "USD",
      coupon: "SUMMER_SALE",
      items: [
       {
        item_id: "SKU_12345",
        item_name: "Stan and Friends Tee",
        affiliation: "Google Merchandise Store",
        coupon: "SUMMER_FUN",
        discount: 2.22,
        index: 0,
        item_brand: "Google",
        item_category: "Apparel",
        item_category2: "Adult",
        item_category3: "Shirts",
        item_category4: "Crew",
        item_category5: "Short sleeve",
        item_list_id: "related_products",
        item_list_name: "Related Products",
        item_variant: "green",
        location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
        price: 9.99,
        quantity: 1
      },
      {
        item_id: "SKU_12346",
        item_name: "Google Grey Women's Tee",
        affiliation: "Google Merchandise Store",
        coupon: "SUMMER_FUN",
        discount: 3.33,
        index: 1,
        item_brand: "Google",
        item_category: "Apparel",
        item_category2: "Adult",
        item_category3: "Shirts",
        item_category4: "Crew",
        item_category5: "Short sleeve",
        item_list_id: "related_products",
        item_list_name: "Related Products",
        item_variant: "gray",
        location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
        price: 20.99,
        promotion_id: "P_12345",
        promotion_name: "Summer Sale",
        quantity: 1
      }]
  }
});
gtag("event", "purchase", {
    transaction_id: "T_12345",
    value: 25.42,
    tax: 4.90,
    shipping: 5.99,
    currency: "USD",
    coupon: "SUMMER_SALE",
    items: [
     {
      item_id: "SKU_12345",
      item_name: "Stan and Friends Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 2.22,
      index: 0,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "green",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 9.99,
      quantity: 1
    },
    {
      item_id: "SKU_12346",
      item_name: "Google Grey Women's Tee",
      affiliation: "Google Merchandise Store",
      coupon: "SUMMER_FUN",
      discount: 3.33,
      index: 1,
      item_brand: "Google",
      item_category: "Apparel",
      item_category2: "Adult",
      item_category3: "Shirts",
      item_category4: "Crew",
      item_category5: "Short sleeve",
      item_list_id: "related_products",
      item_list_name: "Related Products",
      item_variant: "gray",
      location_id: "ChIJIQBpAG2ahYAR_6128GcTUEo",
      price: 20.99,
      promotion_id: "P_12345",
      promotion_name: "Summer Sale",
      quantity: 1
    }]
});
## Tracking transactions without Google Data Layer If you're not integrated with Google Data Layer, you can create your own array variable and connect it to Synerise using the SDK:
SR.init({
    "trackerKey":"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "dataLayer": window["syneriseLayer"] = []
});
After this configuration, you can send objects like the ones above to the `syneriseLayer` variable instead of the `dataLayer` variable:
syneriseLayer.push({...})
### Campaigns ## Set Notification delegate --- This method sets an object for simple push campaigns delegate methods. **Declared In:** Headers/SNRSynerise.h **Related To:** [NotificationDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#notification-delegate) **Class:** Synerise **Declaration:**
```Swift static func setNotificationDelegate(_ delegate: NotificationDelegate) ```
```Objective-C + (void)setNotificationDelegate:(SNRNotificationDelegate *)delegate ```
**Discussion:** Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#notification-delegate). ## Set In-App Message delegate --- This method sets an object for in-app message campaigns delegate methods. **Declared In:** Headers/SNRInjector.h **Related To:** [InjectorInAppMessageDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#injector-in-app-message-delegate) **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func setInAppMessageDelegate(_ delegate: InjectorInAppMessageDelegate) ```
```Objective-C + (void)setInAppMessageDelegate:(SNRInjectorInAppMessageDelegate *)delegate ```
**Discussion:** Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#injector-in-app-message-delegate). ## Close In-App message --- 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. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | ----------------------------------------------- | ----------- | --------------- | -------------------- | --------------- | | Introduced in: | 5.7.0 | 6.7.0 | 1.5.0 | 2.5.0 | **Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```swift static func closeInAppMessage(campaignHash: String) -> Void ```
```objective-c + (void)closeInAppMessage:(nonnull NSString *)campaignHash ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | ---------------- | ------ | --------- | ------- | ---------------------------------------- | | **campaignHash** | string | yes | - | Unique identifier of the in-app campaign | ## Set Notification categories --- This method sets the notification categories (including Synerise categories) that your app supports. * @note All notification categories must be supported by the app to function properly. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func setNotificationCategories(_: Set) -> Void ```
```Objective-C + (void)setNotificationCategories:(NSSet *)notificationCategories ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **notificationCategories** | Set | yes | - | A set of objects containing all the actions displayed in the notification interface. | **Return Value:** No value is returned. ## Register for push notifications --- This method passes the Firebase Token to Synerise for notifications.
- You should call this method every time the user changes the system or application consent for notifications. - The API key must have the `API_PERSONAL_DEVICE_CLIENT_UPDATE` permission from the **Client** group. - If the registration fails, the SDK requests a token update again by a listener/delegate method ([Android](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener), [iOS](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed), [React Native](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener), [Flutter](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener)).
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func registerForPush(registrationToken: String, mobilePushAgreement: Bool, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)registerForPush:(nonnull NSString *)registrationToken mobilePushAgreement:(BOOL)mobilePushAgreement success:(nonnull void (^)(void))success failure:(nonnull void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **registrationToken** | String | yes | - | Firebase Token | | **mobilePushAgreement** | Bool | yes | - | Agreement (consent) for mobile push campaigns | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { Client.registerForPush(registrationToken: fcmToken, mobilePushAgreement: true, success: { // success }, failure: { (error) in // failure }) } ```
```Objective-C - (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken { [SNRClient registerForPush:fcmToken mobilePushAgreement:YES success:^() { // success } failure:^(SNRApiError * _Nonnull error) { // failure }]; } ```
## Register for push notifications without agreement --- This method passes the Firebase Token to Synerise for notifications and doesn't update the agreement of the profile. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 1.1.0 |
The API key must have the `API_PERSONAL_DEVICE_CLIENT_UPDATE` permission from the **Client** group.
If the registration fails, the SDK requests a token update again by a listener/delegate method ([Android](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener), [iOS](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed), [React Native](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener), [Flutter](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener)).
**Declared In:** Headers/SNRClient.h **Class:** [Client](/developers/mobile-sdk/class-reference/ios/modules#client) **Declaration:**
```Swift static func registerForPush(registrationToken: String, success: (() -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)registerForPush:(nonnull NSString *)registrationToken success:(nonnull void (^)(void))success failure:(nonnull void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **registrationToken** | String | yes | - | Firebase Token | | **success** | (() -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error |
Since version 5.0.0, the **success** closure does NOT contain the `isSuccess` parameter.
**Return Value:** No value is returned. **Example:**
```Swift func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) { Client.registerForPush(registrationToken: fcmToken, success: { // success }, failure: { (error) in // failure }) } ```
```Objective-C - (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken { [SNRClient registerForPush:fcmToken success:^() { // success } failure:^(SNRApiError * _Nonnull error) { // failure }]; } ```
## Check if push notification is from Synerise --- This method verifies if a notification was sent by Synerise. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func isSyneriseNotification(_ userInfo: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseNotification:(nonnull NSDictionary *)userInfo ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is provided by Synerise, otherwise returns **false**. **Example:**
```Swift //MARK: - UNUserNotificationCenterDelegate extension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfolet isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == true { // notification is from Synerise } } } ```
```Objective-C #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 == YES) { // notification is from Synerise } } ```
## 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 Simple Push campaign **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func isSyneriseSimplePush(_ userInfo: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseSimplePush:(nonnull NSDictionary *)userInfo; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Simple Push provided by Synerise, otherwise returns **false**. **Example:**
```Swift //MARK: - UNUserNotificationCenterDelegateextension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfolet isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == true { // notification is from Synerise let isSyneriseSimplePush = Synerise.isSyneriseSimplePush(userInfo) if isSyneriseSimplePush == true { // notification is Synerise Simple Push Campaign } } } } ```
```Objective-C #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 == YES) { // notification is from Synerise BOOL isSyneriseSimplePush = [SNRSynerise isSyneriseSimplePush:userInfo]; if (isSyneriseSimplePush == YES) { // notification is Synerise Simple Push Campaign } } } ```
## 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 Command. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func isSyneriseSilentCommand(_ userInfo: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseSilentCommand:(nonnull NSDictionary *)userInfo; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Silent Command provided by Synerise, otherwise returns **false**. **Example:**
```Swift //MARK: - UNUserNotificationCenterDelegateextension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfolet isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == true { // notification is from Synerise let isSyneriseSilentCommand = Synerise.isSyneriseSilentCommand(userInfo) if isSyneriseSilentCommand == true { // notification is Synerise Silent Command } } } } ```
```Objective-C #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 == YES) { // notification is from Synerise BOOL isSyneriseSilentCommand = [SNRSynerise isSyneriseSilentCommand:userInfo]; if (isSyneriseSilentCommand == YES) { // notification is Synerise Silent Command } } } ```
## 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 Silent SDK Command. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func isSyneriseSilentSDKCommand(_ userInfo: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseSilentSDKCommand:(nonnull NSDictionary *)userInfo; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Silent SDK Command provided by Synerise, otherwise returns **false**. **Example:**
```Swift //MARK: - UNUserNotificationCenterDelegate extension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo let isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == true { // notification is from Synerise let isSyneriseSilentSDKCommand = Synerise.isSyneriseSilentSDKCommand(userInfo) if isSyneriseSilentSDKCommand == true { // notification is Synerise Silent SDK Command } } } } ```
```Objective-C #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 == YES) { // notification is from Synerise BOOL isSyneriseSilentSDKCommand = [SNRSynerise isSyneriseSilentSDKCommand:userInfo]; if (isSyneriseSilentSDKCommand == YES) { // notification is Synerise Silent SDK Command } } } ```
## Check if push notification is encrypted --- This method verifies if a notification is encrypted. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func isNotificationEncrypted(_ userInfo: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isNotificationEncrypted:(nonnull NSDictionary *)userInfo ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is encrypted, otherwise returns **false**. **Example:**
```Swift func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { let isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == false { let isNotificationEncrypted = Synerise.isNotificationEncrypted(userInfo) if isNotificationEncrypted == true { // Notification is encrypted by Synerise } } //... } ```
```Objective-C - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo]; if (isSyneriseNotification == NO) { BOOL isNotificationEncrypted = [SNRSynerise isNotificationEncrypted:userInfo]; if (isNotificationEncrypted == YES) { // Notification is encrypted by Synerise } } } ```
## Decrypt push notification --- This method decrypts the notification payload.
If the notification is not encrypted, the method returns the raw payload.
If a notification is not decrypted successfully, the method returns nil.
**Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func decryptNotification(_ userInfo: [AnyHashable: Any]) -> Void ```
```Objective-C + (nullable NSDictionary *)decryptNotification:(nonnull NSDictionary *)userInfo ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** Notification’s key-value map of data with decrypted content **Example:**
```Swift func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { let isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == false { let isNotificationEncrypted = Synerise.isNotificationEncrypted(userInfo) if isNotificationEncrypted == true { // Notification is encrypted by Synerise if let userDataDecrypted = Synerise.decryptNotification(userInfo) { // Notification decryption process was successful } } } //... } ```
```Objective-C - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo]; if (isSyneriseNotification == NO) { BOOL isNotificationEncrypted = [SNRSynerise isNotificationEncrypted:userInfo]; if (isNotificationEncrypted == YES) { // Notification is encrypted by Synerise NSDictionary *userDataDecrypted = Synerise decryptNotification:userData]; if (userDataDecrypted != nil) { // Notification decryption process was successful } } } } ```
## Handle Synerise push notification --- This method handles a notification payload and starts activity. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func handleNotification(_ userInfo: [AnyHashable: Any]) -> Void ```
```Objective-C + (void)handleNotification:(nonnull NSDictionary *)userInfo; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** No value is returned. **Example:**
```Swift //MARK: - UNUserNotificationCenterDelegate extension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo let isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == true { // notification is from Synerise Synerise.handleNotification(userInfo) } } } ```
```Objective-C #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 == YES) { // notification is from Synerise [SNRSynerise handleNotification:userInfo]; } } ```
## Handle Synerise push notification with action --- This method handles a notification payload with a user interaction and starts activity. **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func handleNotification(_ userInfo: [AnyHashable: Any], actionIdentifier: String?) -> Void ```
```Objective-C + (void)handleNotification:(nonnull NSDictionary *)userInfo actionIdentifier:(nullable NSString *)actionIdentifier ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | | **actionIdentifier** | String | no | - | Identifier of action received from the notification response | **Return Value:** No value is returned. **Example:**
```Swift //MARK: - UNUserNotificationCenterDelegate extension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfolet actionIdentifier = response.actionIdentifier let isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == true { // notification is from Synerise Synerise.handleNotification(userInfo, actionIdentifier: actionIdentifier) } } } ```
```Objective-C #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; NSString *actionIdentifier = response.actionIdentifier; BOOL isSyneriseNotification = [SNRSynerise isSyneriseNotification:userInfo]; if (isSyneriseNotification == YES) { // notification is from Synerise [SNRSynerise handleNotification:userInfo actionIdentifier:actionIdentifier]; } } ```
## Removed methods ### Check if push notification is a Banner Campaign {#check-if-push-notification-is-a-banner-campaign} --- This method verifies if a notification’s sender is Synerise and if the notification is a Banner campaign. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** Headers/SNRSynerise.h **Class:** [Synerise](/developers/mobile-sdk/class-reference/ios/modules#synerise) **Declaration:**
```Swift static func isSyneriseBanner(_ userInfo: [AnyHashable: Any]) -> Bool ```
```Objective-C + (BOOL)isSyneriseBanner:(nonnull NSDictionary *)userInfo; ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **userInfo** | [AnyHashable: Any] | yes | - | Key-Value map of data | **Return Value:** **true** if the notification is Synerise Banner provided by Synerise, otherwise returns **false**. **Example:**
```Swift //MARK: - UNUserNotificationCenterDelegateextension NotificationService: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfolet isSyneriseNotification = Synerise.isSyneriseNotification(userInfo) if isSyneriseNotification == true { // notification is from Synerise let isSyneriseBanner = Synerise.isSyneriseBanner(userInfo) if isSyneriseBanner == true { // notification is Synerise Banner Campaign } } } } ```
```Objective-C #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 == YES) { // notification is from Synerise BOOL isSyneriseBanner = [SNRSynerise isSyneriseBanner:userInfo]; if (isSyneriseBanner == YES) { // notification is Synerise Banner Campaign } } } ```
### Fetch Banners {#fetch-banners} --- This method fetches banners set for mobile campaigns and caches the valid ones. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | n/a | **Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func fetchBanners(success: (([[AnyHashable: Any]]) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)fetchBannersWithSuccess:(void (^)(NSArray *banners))success failure:(void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **success** | (([[AnyHashable: Any]]) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. ### Get Banners {#get-banners} --- This method provides valid banners directly from SDK cache. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | n/a | **Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func getBanners() -> [[AnyHashable: Any]] ```
```Objective-C + (NSArray *)getBanners ```
**Return Value:** List of structures that represents cached Banners. ### Show Banner {#show-banner} --- This method shows a banner immediately. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | - | **Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func showBanner(_: [AnyHashable: Any], markPresented: Bool) -> Void ```
```Objective-C + (void)showBanner:(NSDictionary *)bannerDictionary markPresented:(BOOL)markPresented ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **bannerDictionary** | [AnyHashable: Any] | yes | - | Dictionary representation of a banner | | **markPresented** | Bool | yes | - | Sets the banner as presented and this banner instance representation will not appear again | **Return Value:** No value is returned. ### Get Walkthrough {#get-walkthrough} --- This method fetches a walkthrough. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 |
The API key must have the `CAMPAIGN_BACKEND_CAMPAIGN_READ` permission from the **Campaign** group.
**Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func getWalkthrough() -> Void ```
```Objective-C + (void)getWalkthrough ```
**Return Value:** No value is returned. ### Show Walkthrough {#show-walkthrough} --- This method shows a walkthrough when it is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func showWalkthrough() -> Void ```
```Objective-C + (void)showWalkthrough ```
**Return Value:** No value is returned. ### Check if Walkthrough is loaded {#check-if-walkthrough-is-loaded} --- This method checks if a walkthrough is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func isWalkthroughLoaded() -> Bool ```
```Objective-C + (BOOL)isWalkthroughLoaded ```
**Return Value:** **true** if the walkthrough is loaded, otherwise returns **false**. ### Check if loaded Walkthrough is unique {#check-if-loaded-walkthrough-is-unique} --- This method checks if the walkthrough is unique compared to the previous one. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func isLoadedWalkthroughUnique() -> Bool ```
```Objective-C + (BOOL)isLoadedWalkthroughUnique ```
**Return Value:** **true** if the walkthrough is unique, otherwise returns **false**. ### Get pushes {#get-pushes} --- This method fetches Push Notifications set for mobile campaigns. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `CAMPAIGN_BACKEND_COLLECTOR_READ` permission from the **Collector** group.
**Declared In:** Headers/SNRInjector.h **Class:** [Injector](/developers/mobile-sdk/class-reference/ios/modules#injector) **Declaration:**
```Swift static func getPushes(success: (([[AnyHashable: Any]]) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getPushesWithSuccess:(void (^)(NSArray *pushes))success failure:(void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **success** | (([[AnyHashable: Any]]) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. ### Recommendations and Documents ## Recommendations --- ### RecommendationRequestBody Class responsible for creating a recommendation request. **Declared In:** `com.synerise.sdk.content.model.recommendation.RecommendationRequestBody` **Declaration:**
```Java public final class RecommendationRequestBody implements Serializable ```
```Kotlin class RecommendationRequestBody:Serializable ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **productId** | String | no | - | Item identifier of the context item | | **itemsIds** | ArrayList | no | - | List of item identifiers, used for multiple item context | | **itemsExcluded** | ArrayList | no | Items that will be excluded from the generated recommendations | | **additionalFilters** | String | no | Additional filters. These are merged with the campaign's own filters according to the logic in **filtersJoiner** | | **filtersJoiner** | String | no | Defines the logic of merging additionalFilters with the campaign's existing filters | | **additionalElasticFilters** | String | no | Additional elastic filters. These are merged with the campaign's own elastic filters according to the logic in **elasticFiltersJoiner** | | **elasticFiltersJoiner** | String | no | Defines the logic of merging **additionalElasticFilters** with the campaign's existing elastic filters | | **displayAttribute** | ArrayList | no | An array of item attributes which value will be returned in a recommendation response | | **includeContextItems** | Boolean | no | When true, the recommendation response will include context item metadata | **Initializers:** There are no initializers. **Methods:** Setter for productId
public RecommendationRequestBody setProductId(String productId)
--- Setter for itemsIds
public RecommendationRequestBody setItemsIds(ArrayList<String> itemsIds)
--- --- --- ### RecommendationResponse Class responsible for receiving recommendations. **Declared In:** `com.synerise.sdk.content.model.recommendation.RecommendationResponse` **Declaration:**
```Java public class RecommendationResponse ```
```Kotlin class RecommendationResponse ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **recommended** | List<[Recommendation](/developers/mobile-sdk/class-reference/android/recommendations-and-documents#recommendation)> | no | - | List of recommendations | | **extras** | RecommendationResponseExtras | yes | - | Additional details of the recommendation | | **name** | String | no | - | Name of the recommendation campaign | | **campaignHash** | String | no | - | Hash (UUID) of the recommendation campaign | | **campaignId** | String | no | - | ID of the recommendation campaign | | **correlationId** | String | no | - | Recommendation's correlation ID. It can be added to a `recommendation.click` event to associate it with the recommendation request | | **schema** | String | no | - | Schema of the document which contains the recommendation | | **slug** | String | no | - | Slug of the document | | **uuid** | String | no | - | UUID of the document |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** This method retrieves a recommendation schema.
public String getSchema()
--- This method retrieves the value of the `slug` parameter.
public String getSlug()
--- This method retrieves the value of the `UUID` parameter.
public String getUuid()
--- This method retrieves a list of recommendations.
public List<Recommendation> getRecommendationsV2()
--- This method retrieves the value of the `campaignHash` parameter.
public String getCampaignHash()
--- This method retrieves the value of the `campaignId` parameter.
public String getCampaignId()
--- --- --- ### Recommendation Class model for a recommendation. **Declared In:** `com.synerise.sdk.content.model.recommendation.Recommendation` **Declaration:**
```Java public class Recommendation extends BaseModel ```
```Kotlin class Recommendation : BaseModel ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **itemId** | String | no | - | Product's GTIN | | **feed** | HashMap | no | - | Product’s recommendation attributes |
All the properties above are accessible by using getters and setters.
**Initializers:** There are no initializers. **Methods:** There are only getters and setters for the above properties. --- --- --- ### RecommendationAttribute Class model for custom attributes. **Declared In:** `com.synerise.sdk.content.model.recommendation.RecommendationAtribute` **Declaration:**
```Java public class RecommendationAtribute ```
```Kotlin class RecommendationAtribute ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **name** | String | no | - | Attribute name | | **type** | String | no | - | Attribute type | | **value** | String | no | - | Attribute value |
All the properties above are accessible by using getters and setters.
**Initializers:** There are no initializers. **Methods:** There are only getters and setters for the above properties. --- ## Documents --- ### DocumentApiQuery Class responsible for creating a query to the Documents API. **Declared In:** `com.synerise.sdk.content.model.DocumentApiQuery` **Declaration:**
```Java public class DocumentApiQuery ```
```Kotlin class DocumentApiQuery ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **slug** | String | no | Unique identifier of a document | **Properties used only if the document includes a recommendation insert:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **productId** | String | no | Item identifier of the context item | | **itemsIds** | ArrayList | no | List of item identifiers, used for multiple item context | | **itemsExcluded** | ArrayList | no | Items that will be excluded from the generated recommendations | | **additionalFilters** | String | no | Additional filters. These are merged with the campaign's own filters according to the logic in **filtersJoiner** | | **filtersJoiner** | String | no | Defines the logic of merging additionalFilters with the campaign's existing filters | | **additionalElasticFilters** | String | no | Additional elastic filters. These are merged with the campaign's own elastic filters according to the logic in **elasticFiltersJoiner** | | **elasticFiltersJoiner** | String | no | Defines the logic of merging **additionalElasticFilters** with the campaign's existing elastic filters | | **displayAttribute** | ArrayList | no | An array of item attributes which value will be returned in a recommendation response | | **includeContextItems** | Boolean | no | When true, the recommendation response will include context item metadata | | **params** | HashMap | yes | Additional parameters to pass for [Inserts in the document](/developers/inserts/screen-views-documents#handling-variables-when-displaying-screen-viewsdocuments). For example, if the insert is `{{ foo }}`, you need to pass the value of `foo` | **Initializers:** There is a constructor.
public DocumentApiQuery(String feedSlug)
**Methods:** Setter for feedSlug
public void setFeedSlug(String feedSlug)
--- Setter for additionalFilters
public DocumentApiQuery setAdditionalFilters(String additionalFilters)
--- Setter for itemsExcluded
public DocumentApiQuery setItemsExcluded(ArrayList<String> itemsExcluded)
--- Setter for filtersJoiner
public DocumentApiQuery setFiltersJoiner(FiltersJoinerRule filtersJoiner)
--- Setter for additionalElasticFilters
public DocumentApiQuery setAdditionalElasticFilters(String additionalElasticFilters)
--- Setter for elasticFiltersJoiner
public DocumentApiQuery setElasticFiltersJoiner(FiltersJoinerRule elasticFiltersJoiner)
--- Setter for displayAttributes
public DocumentApiQuery setDisplayAttributes(ArrayList<String> displayAttribute)
--- Setter for includeContextItems
public DocumentApiQuery setIncludeContextItems(Boolean includeContextItems)
--- Setter for itemsIds
public DocumentApiQuery setItemsIds(ArrayList<String> itemsIds)
--- Setter for productId
public DocumentApiQuery setProductId(String productId)
--- --- --- ### Document **Declared In:** `com.synerise.sdk.content.model.document` **Declaration:**
```java public class Document ```
```kotlin class Document ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **uuid** | String | no | Document's identifier (UUID) | | **slug** | String | no | Document's slug | | **schema** | String | no | Document's schema type | | **content** | [AnyHashable: Any] | no | Document's content |
All the properties above are accessible by using getters.
**Initializers:** There are no initializers. **Methods:** There are only getters for the above properties. --- --- ## Removed symbols --- ### DocumentsApiQuery{#documentsapiquery} The object to set parameters easily for fetching documents from API. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.5.10 | 3.5.1 | 0.9.10 | 0.2.0 | | Deprecated in: | 4.13.0 | 5.5.0 | 0.17.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | Class responsible for creating a query to the Documents API. **Declared In:** `com.synerise.sdk.content.model.DocumentsApiQuery` **Declaration:**
```Java public class DocumentsApiQuery ```
```Kotlin class DocumentsApiQuery ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **type** | [DocumentsApiQueryType](/developers/mobile-sdk/class-reference/android/recommendations-and-documents#documentsapiquerytype) | yes | - | Document's query type | | **typeValue** | String | yes | - | Document's query type value | | **version** | String | yes | - | Document version | **Initializers:** There are no initializers. **Methods:** This method sets query parameters.
public void setDocumentQueryParameters(DocumentsApiQueryType type, String typeValue)
--- This method sets a document version.
public void setVersion(String version)
--- --- --- ### DocumentsApiQueryType{#documentsapiquerytype} | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 3.5.10 | 3.5.1 | 0.9.10 | 0.2.0 | | Deprecated in: | 4.13.0 | 5.5.0 | 0.17.0 | n/a | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | This enum contains values for the Documents API query type. **Declared In:** `com.synerise.sdk.content.model.DocumentsApiQueryType` **Declaration:**
```Java public enum DocumentsApiQueryType ```
```Kotlin public enum DocumentsApiQueryType ```
**Values:** | Property | Value | Description | | --- | --- | --- | | **SCHEMA** | "by-schema" | Query type | **Methods:** Get by path type.
public static DocumentsApiQueryType getByPathType(String type)
--- ### Overwriting events You can overwrite an existing event, for example to change a parameter value or correct an error. This is done by sending an event (as described in [Sending events](/developers/api/events/sending-events)) with the same action, occurrence time, and event salt as an existing event. When you overwrite the event: - All data in the event payload (parameters) is overwritten with data from the new event. - The UUID stays the same. - The time of occurrence stays the same. In `v4/transaction` endpoints, this parameter is called `recordedAt`. - The time of saving in the database changes to the new event. - In Automations that use the overwritten event as a trigger, the automation is triggered if the new event is sent more than 72 hours after the original. This is because the event UUID stays the same, and Automation treats events with the same UUID within 72 hours as duplicates that were sent due to an error. ## Requirements and limitations - The original event (the one which you want to overwrite) had to be sent with an `eventSalt` parameter. - An `eventSalt` must be unique. For example, you can concatenate the action, profile ID, and timestamp. - The `eventSalt` can't be retrieved with an event! You need to implement your own mechanism for keeping the values for later use or create the value in such a way that it can be re-created. - `eventSalt` can't be added to an existing event. - Both events must have the same action. - Both events must belong to the same profile's history. - Both events must have the same `time` - In transaction events, this parameter is called `recordedAt` - It isn't possible to change the time of occurrence by overwriting an event. - This must be the time saved in the database. If your original event had a timestamp that was in the future in relation to the time of sending the event, that timestamp was rejected and you must first retrieve the event and check the time it was saved with (in such a case, it will be the same as the time of receiving the event in Synerise). ## Example ### Send first event This is the original event:
curl --location --request POST 'https://api.synerise.com/v4/events/custom' \
--header 'Authorization: Bearer ey...RtH_g' \
--header 'Api-Version: 4.4' \
--header 'Content-Type: application/json' \
--data-raw '{
    "action": "dog.bark",
    "eventSalt": "dogbark50921599992022-12-13T15:25:08.861Z",
    "client": {
        "id": 5092159999
    },
    "time": "2022-12-13T15:25:08.861Z",
    "params": {
        "loudness": 3,
        "mood": "happy",
        "mailmanScared": true
    },
    "label": "bark"
}'
### Get original event This is the event when you retrieve it (for example, by [getting all events from a profile](https://developers.synerise.com/DataManagement/DataManagement.html#operation/GetClientEvents)):
{
    "time": "2022-12-13T15:24:49Z",
    "action": "dog.bark",
    "label": "",
    "client": {
        "id": 5092159999,
        "email": "e0097757-d1e2-44ac-ba3c-d97979a354c1@anonymous.invalid",
        "uuid": "e0097757-d1e2-44ac-ba3c-d97979a354c1"
    },
    "params": {
        "eventCreateTime": "2022-12-13T15:25:08.861Z",
        "mood": "happy",
        "ip": "13.93.68.194",
        "loudness": 3,
        "mailmanScared": true
    }
}
Note that the `eventSalt` is not retrieved, and some parameters were added automatically when the event was processed. ### Overwrite event Let's overwrite the event by: - changing the `loudness` parameter - removing the `mailmanScared` parameter - adding the `mailDelivered` parameter
curl --location --request POST 'https://api.synerise.com/v4/events/custom' \
  --header 'Authorization: Bearer ey...RtH_g' \
  --header 'Api-Version: 4.4' \
  --header 'Content-Type: application/json' \
  --data-raw '{
      "action": "dog.bark",
      "eventSalt": "dogbark50921599992022-12-13T15:25:08.861Z",
      "client": {
          "id": 5092159999
      },
      "time": "2022-12-13T15:25:08.861Z",
      "params": {
          "loudness": 1,
          "mood": "happy",
          "mailDelivered": true
      },
      "label": "bark"
  }'
### Get overwritten event When you retrieve the same event: - the parameters are changed according to the new data you sent. - the `eventCreateTime` parameter is the time of saving the new instance in the database, and event retention takes the new time into account. - the occurrence time (`time`) is the same. - the updated event also replaces the original event on the [profile's card](/docs/crm/crm-profile#activity-list) view.
{
      "time": "2022-12-13T15:25:08.861Z",
      "action": "dog.bark",
      "label": "",
      "client": {
          "id": 5092159999,
          "email": "e0097757-d1e2-44ac-ba3c-d97979a354c1@anonymous.invalid",
          "uuid": "e0097757-d1e2-44ac-ba3c-d97979a354c1"
      },
      "params": {
          "eventCreateTime": "2022-12-13T15:48:02.746Z",
          "mood": "happy",
          "ip": "13.93.68.194",
          "loudness": 1,
          "mailDelivered": true
      }
  }
### Recommendations API The recommendation API lets you retrieve results from a campaign you created earlier or make ad-hoc requests (model requests). When making the requests, you can add or modify filters, set the item context, exclude items from the response, and select the attributes included in the response. In this section, you can learn how to: - make different types of recommendation requests - read the response - add or manipulate filters - send events that can be used in Decision Hub and Automation Hub ## Before you begin - Ensure that the model for the type of recommendations you want to request is enabled in the [settings of an item feed](/docs/settings/configuration/ai-engine-configuration/engine-configuration-for-recommendations#selecting-recommendation-types-and-default-filters). - You should be familiar with recommendation types and filter types: - [Recommendation types](/docs/ai-hub/recommendations-v2/recommendation-types) - [Recommendation filter types](/docs/ai-hub/recommendations-v2/recommendation-filters#filter-types) - If you want to add or change filters when making the request, you need to learn the [Items Query Language](/developers/iql). ### Jinjava tests Tests allow you to return true/false values depending on the tested value.
If you use Visual Studio Code as your editor, you can use code snippets to speed up working with inserts. You can find the snippets in our Github repository: [https://github.com/Synerise/jinja-code-snippet](https://github.com/Synerise/jinja-code-snippet)
## IsContainingAll Returns `true` if a list contains all the values from another list. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | list | yes | If this list contains all the items from the list provided in the params, the test returns `true`. | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | list | yes | The list that must be contained in the list provided as input | **Example:**
{{ [1, 2, 3] is containingall [2, 3] }}
## IsContaining Returns `true` if a list contains the provided value. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | list | yes | If this list contains the value provided in the parameters, the test returns `true`. | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The value to search for in the input list | **Example:**
{{ [1, 2, 3] is containing 2 }}
## IsDefined Returns `true` if the variable is defined. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The variable to check | **Example:**
{%- if foo is defined -%}
    {# code to render if foo is defined #}
{%- else -%}
    {# code to render if foo is not defined #}
{%- endif -%}
## IsDivisibleBy Returns `true` if a variable is divisible by a number. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The variable to check against the divisor | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The divisor | **Example:**
{%- if foo is divisibleby 5 -%}
    {# code to render if foo can be divided by 5 #}
{%- else -%}
    {# code to render if foo cannot be divided by 5 #}
{%- endif -%}
## IsEqualTo Returns `true` if an object has the same value as another object. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | First object for comparison | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | Second object for comparison | **Example:**
{%- if foo is equalto 42 -%}
    the foo attribute evaluates to the constant 42
{%- endif -%}
Usage with the selectattr filter:
{{ users|selectattr("email", "equalto", "foo@bar.invalid") }}
## IsEven Returns `true` if a value is an even number. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to check | **Example:**
{%- if foo is even -%}
    {# code to render if foo is an even number #}
{%- else -%}
    {# code to render if foo is an odd number #}
{%- endif -%}
## IsIterable Returns `true` if the object is iterable (for example, a sequence). **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The object to check | **Example:**
{%- if foo is iterable -%}
    {# code to render if foo is iterable #}
{%- endif -%}
## IsLower Returns `true` if a string is all lowercase. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to check | **Example:**
{%- if foo is lower -%}
    {# code to render if the value of foo is all lowercase #}
{%- endif -%}
## IsMapping Returns `true` if an object is a dictionary. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The object to check | **Example:**
{%- if foo is mapping -%}
    {# code to render if foo is a dictionary #}
{%- endif -%}
## IsNumber Returns `true` if the object is a number. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The object to check | **Example:**
{%- if foo is number -%}
    {{ foo * 1000000 }}
{%- else -%}
    foo is not a number.
{%- endif -%}
## IsOdd Returns `true` if a number is an odd number. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to check | **Example:**
{%- if foo is odd -%}
    {# code to render if foo is an odd number #}
{%- else -%}
    {# code to render if foo is an even number #}
{%- endif -%}
## IsSameAs Returns `true` if a variable points at same object as another variable. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The first variable to compare | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The second variable to compare | **Example:**
{%- if var_one is sameas var_two -%}
    {# code to render if the variables have identical values #}
{%- endif -%}
## IsSequence Returns `true` if the variable is a sequence. Sequences are variables that are iterable. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The object to check | **Example:**
{%- if foo is sequence -%}
    {# code to render foo is a sequence #}
{%- endif -%}
## IsStringContaining Returns `true` if an object is a string which contains a specified other string. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string that needs to contain the string provided as the parameter | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string that needs to be included in the string provided as input | **Example:**
{%- if foo is string_containing 'bar' -%}
    {# code to render if foo contains 'bar'  #}
{%- endif -%}
## IsString Returns `true` if an object is a string. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The object to check | **Example:**
{%- if foo is string -%}
    {# code to render if foo is a string #}
{%- endif -%}
## IsStringStartingWith Returns `true` if an object is a string which starts with a specified other string. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string that needs to start with the string provided as the parameter | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to check against | **Example:**
{%- if foo is string_startingwith 'bar' -%}
    {# code to render if foo starts with 'bar' #}
{%- endif -%}
## IsTruthy Returns `true` if a value is *truthy*. `IsTruthy` follows the same implicit conversion rules as `{% if %}` conditions. For `==` and `!=`, type conversion applies only when the other operand is a boolean. | Input type | Returns `true` | Returns `false` | | :--- | :--- | :--- | | Boolean | `true` | `false` | | Number | Any non-zero number | `0` | | String | Any non-empty string, except `"false"` | `""` (empty string) or `"false"` | | null | Never | Always | | Collection (list, map) | Non-empty | Empty | | Any other type | Always | Never |
The [`|bool` filter](/developers/inserts/filter#bool) uses stricter conversion rules and can return a different result from `is truthy` for the same input. For example, `'string' is truthy` returns `true`, but `'string'|bool` returns `false`.
**Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | The value to check | **Example:**
{%- if foo is truthy -%}
    {# code to render if foo is truthy #}
{%- endif -%}
For strict type-and-value equality without any boolean conversion, use the [`sameas` test](/developers/inserts/exptest#issameas). Unlike `is truthy`, `sameas` checks that two values are identical without type coercion. For example, `"1" == true` returns `true` due to boolean conversion, but `"1" is sameas true` returns `false` because the types differ.
## IsUndefined Returns `true` if an object is undefined. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The object to check | **Example:**
{%- if foo is undefined -%}
    {# code to render if foo is undefined #}
{%- endif -%}
## IsUpper Returns `true` if a string is all uppercase. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to check | **Example:**
{%- if foo is upper -%}
    {#  code to render if foo is a string and is all uppercase  #}
{%- endif -%}
## IsWithin Returns `true` if a value is contained in a list. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The value to search for in the list | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | list | yes | The list to search in | **Example:**
{{ 2 is within [1, 2, 3] }}
### Campaigns --- ## Set Injector listener --- This method sets callbacks for an injector module. **Declared In:** lib/main/modules/InjectorModule.js **Related To:** [ClientStateChangeListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-listener) **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public setListener(listener: IInjectorListener)
**Discussion:** Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-listener). ## Set In-App Message listener --- This method sets callbacks for in-app message campaigns. **Declared In:** lib/main/modules/InjectorModule.js **Related To:** [ClientStateChangeListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-in-app-message-listener) **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public setInAppMessageListener(listener: IInjectorInAppMessageListener)
**Discussion:** Learn more about the methods and the purpose of this listener [here](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-in-app-message-listener). ## Close In-App message --- 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. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | ----------------------------------------------- | ----------- | --------------- | -------------------- | --------------- | | Introduced in: | 5.7.0 | 6.7.0 | 1.5.0 | 2.5.0 | **Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public closeInAppMessage(campaignHash: string)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | ---------------- | ------ | --------- | ------- | ---------------------------------------- | | **campaignHash** | string | yes | - | Unique identifier of the in-app campaign | ## Set Notifications listener --- This method sets callbacks for notifications module. **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public setListener(listener: INotificationsListener)
## Register for push notifications --- This method passes the Firebase Token to Synerise for notifications.
- You should call this method every time the user changes the system or application consent for notifications. - The API key must have the `API_PERSONAL_DEVICE_CLIENT_UPDATE` permission from the **Client** group. - If the registration fails, the SDK requests a token update again by a listener/delegate method ([Android](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener), [iOS](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed), [React Native](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener), [Flutter](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener)).
**Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public registerForNotifications(registrationToken: string, mobileAgreement: boolean | null, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **registrationToken** | string | yes | - | Firebase Token | | **mobileAgreement** | boolean | false | null | Agreement (consent) for mobile push campaigns | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript // If you integrate Firebase Messaging in the native part of app Synerise.Notifications.setListener({ onRegistrationToken: function(registrationToken) { Synerise.Notifications.registerForNotifications(registrationToken, true, function(){ //success }, function() { //failure }); }, onNotification: function(payload) { //... } //... //other listener's methods }); // Or if you want to use Firebase Messaging in react native Synerise.Notifications.registerForNotifications("YOUR_FIREBASE_TOKEN", true, function(){ //success }, function() { //failure }); ```
## Check if push notification is from Synerise --- This method verifies if a notification was sent by Synerise. **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public isSyneriseNotification(payload: object): boolean
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** **true** if a notification was sent by Synerise, otherwise **false**. **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { if (Synerise.Notifications.isSyneriseNotification(payload)) { Synerise.Notifications.handleNotification(payload); } } //... //other listener's methods }); ```
## 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 Simple Push campaign **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public isSyneriseSimplePush(payload: object): boolean
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** **true** if a notification is a Simple Push, otherwise **false**. **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { if (Synerise.Notifications.isSyneriseSimplePush(payload)) { Synerise.Notifications.handleNotification(payload); } } //... //other listener's methods }); ```
## 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 Command. **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public isSilentCommand(payload: object): boolean
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** **true** if a notification is a Silent Command, otherwise **false**. **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { if (Synerise.Notifications.isSilentCommand(payload)) { Synerise.Notifications.handleNotification(payload); } } //... //other listener's methods }); ```
## 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 Silent SDK Command. **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public isSilentSDKCommand(payload: object): boolean
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** **true** if a notification is a Silent SDK Command, otherwise **false**. **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { if (Synerise.Notifications.isSilentSDKCommand(payload)) { Synerise.Notifications.handleNotification(payload); } } //... //other listener's methods }); ```
## Check if push notification is encrypted --- This method verifies if a notification is encrypted. **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public isNotificationEncrypted(payload: object): boolean
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** **true** if a notification is encrypted, otherwise **false**. **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { if (Synerise.Notifications.isNotificationEncrypted(payload)) { Synerise.Notifications.decryptNotification(payload); } } //... //other listener's methods }); ```
## Decrypt push notification --- This method decrypts the notification payload.
If the notification is not encrypted, the method returns the raw payload.
If a notification is not decrypted successfully, the method returns nil.
**Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public decryptNotification(payload: object): object | null
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** Notification’s key-value data object with decrypted content **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { let data = Synerise.Notifications.decryptNotification(payload) // custom notification implementation } //... //other listener's methods }); ```
## Handle Synerise push notification --- This method handles a notification payload and starts activity. **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public handleNotification(payload: object, actionIdentifier: string | null)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { Synerise.Notifications.handleNotification(payload); } //... //other listener's methods }); ```
## Removed methods ### Check if push notification is a Banner Campaign {#check-if-push-notification-is-a-banner-campaign} --- This method verifies if a notification’s sender is Synerise and if the notification is a Banner campaign. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Declared In:** lib/main/modules/NotificationsModule.js **Class:** [NotificationsModule](/developers/mobile-sdk/class-reference/react-native/modules#notifications) **Declaration:**
public isSyneriseBanner(payload: object): boolean
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | object | yes | - | Notification's key-value data object | **Return Value:** **true** if a notification is a Banner, otherwise **false**. **Example:**
```JavaScript Synerise.Notifications.setListener({ onNotification: function(payload) { if (Synerise.Notifications.isSyneriseBanner(payload)) { Synerise.Notifications.handleNotification(payload); } } //... //other listener's methods }); ```
### Fetch Banners {#fetch-banners} --- This method fetches banners set for mobile campaigns and caches the valid ones. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | n/a |
This method was removed in SDK version 0.12.0.
**Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public fetchBanners(onSuccess, onError)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. ### Get Banners {#get-banners} --- This method provides valid banners directly from SDK cache. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | n/a |
This method was removed in SDK version 0.12.0.
**Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public getBanners()
**Return Value:** No value is returned. ### Show Banner {#show-banner} --- This method shows a banner immediately. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | - |
This method was removed in SDK version 0.12.0.
**Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public showBanner(banner: object, markPresented: boolean)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **banner** | object | yes | - | Object representation of a banner | | **markPresented** | boolean | yes | - | Sets the banner as presented and this banner instance representation will not appear again | **Return Value:** No value is returned. ### Get Walkthrough {#get-walkthrough} --- This method fetches a walkthrough. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 |
The API key must have the `CAMPAIGN_BACKEND_CAMPAIGN_READ` permission from the **Campaign** group.
**Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public getWalkthrough()
**Return Value:** No value is returned. ### Show Walkthrough {#show-walkthrough} --- This method shows a walkthrough when it is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public showWalkthrough()
**Return Value:** No value is returned. ### Check if Walkthrough is loaded {#check-if-walkthrough-is-loaded} --- This method checks if a walkthrough is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public isWalkthroughLoaded(): boolean
**Return Value:** **true** if the walkthrough is loaded, otherwise returns **false**. ### Check if is loaded Walkthrough unique {#check-if-is-loaded-walkthrough-unique} --- This method checks if the walkthrough is unique compared to the previous one. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Declared In:** lib/main/modules/InjectorModule.js **Class:** [InjectorModule](/developers/mobile-sdk/class-reference/react-native/modules#injector) **Declaration:**
public isLoadedWalkthroughUnique(): boolean
**Return Value:** **true** if the loaded walkthrough is unique, otherwise returns **false**. ### Event tracking ## Overview --- Everything your customers do in your mobile application is recorded in the system in real time, queued and automatically sent in batches to Synerise. Information such as the source of the visit, the URL address they have visited, and the chain of actions that followed are saved in Synerise as events and their parameters. The scope of information gathered about events is wide. Synerise collects predefined event parameters which can be extended according to the preferences and needs of the Synerise customers. The basic information about the tracked events includes: - **Action name** – an indicator of the activity type, such as `screen.view` - **Label** – human-readable information about the activity, such as the page title. Must be at least one character.
This is a deprecated field. It's not saved in the database. so it can't be used in Decision Hub or Automation Hub.
- **Time** – the time when the event occurred - **Customer identification** – an identifier of the customer who performed the activity - **Parameters** – additional parameters, depending on the type of the event
Click here to see example of an event
{ "action": "screen.view", "eventUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "unique": null, "createDate": 1659456038993, "label": "PromotionViewScreen", "params": { "ip": "xx.xx.xxx.xxx", "source": "MOBILE_APP", "clientId": 1111111111, "uuid": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "eventUUID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "businessProfileId": 1234, "eventCreateTime": "2022-08-02T16:00:38.993Z", "time": 1659456038993, "modifiedBy": { "businessProfileApiKey": null, "clientApiKey": null, "clientId": null, "userId": null }, "clientId": 5790194467, } }
Some events are predefined, meaning they have a fixed set of fields that must be sent. For example, a `product.view` event must include the product ID.
You can [enrich events with data from catalogs in Synerise](/docs/assets/events/adding-event-parameters#enriching-events-with-data-from-catalogs), for example, a product or service event where only an ID has been provided can be enriched with other details such as the description, image URL, and more. ## Queue and flushing As a compromise between how quick events are sent and battery life, events are collected into batches and _queued_ for sending (_flushing_) after enough events are collected or too much time passes (_timeout_), according to SDK settings. Since Android SDK 5.17.0 and iOS SDK 4.17.0, the default settings flush the queue immediately when a push event is added to it. You can change the queue size, timeout, list of events which trigger flushing, and other event tracking settings as described in the ["Tracker" section of the "Settings" article](/developers/mobile-sdk/settings#tracker). To flush the queue on demand, use the following methods: | OS | Method | | ------------ | -------------------------------------------------------------------------------------------------------------------------------- | | Android | [Tracker.flush()](/developers/mobile-sdk/method-reference/android/tracking#flush-events-from-tracker) | | iOS | [flushEvents(completionHandler: (() -> Void)?)](/developers/mobile-sdk/method-reference/ios/tracking#flush-events-from-tracker) | | React Native | [flushEvents(onSuccess: () => void)](/developers/mobile-sdk/method-reference/react-native/tracking#flush-events-from-tracker) | | Flutter | [Synerise.tracker.flush()](/developers/mobile-sdk/method-reference/flutter/tracking#flush-events-from-tracker) | ## Events tracked automatically --- ### Auto-Tracking
Automatic tracking is available only for **Android SDK** and **iOS SDK**. Auto-tracking is not supported for applications built with **Jetpack Compose** and **SwiftUI**. These applications should use [declarative tracking](#declarative-tracking).
Auto-tracking allows you to monitor each type of the customer activity in your mobile application and it is enabled by default. Every interaction (such as click, view, swipe) with any element in the application can be sent as an event to Synerise together with a collection of details concerning the event, which are available in the overview on [the profile's card](/docs/crm/crm-profile). The frequency and the kind of the tracked events are customizable, as you can switch on tracking a particular types of interactions. #### Configuration {id=auto-tracking-configuration} Auto-tracking events is: - Enabled by default for Android. - Disabled by default for iOS. Available modes for auto-tracking: - `DISABLED` - Listeners are disabled (**default mode for iOS SDK**). - `PLAIN` - Listeners are set to track screen-visits only. - `FINE` - Listeners are attached to nearly everything that is clickable in your app, including screen visits that record the [visited screen event](#customer-visited-a-screen) (**default mode for Android SDK**). You may configure auto-tracking with various options to customize your expected behavior and track events you want. See possible configuration options below:
```Java Synerise.settings.tracker.autoTracking.enabled = false; // 1 ```
```Kotlin Synerise.settings.tracker.autoTracking.enabled = false; // 1 ```
```Swift Synerise.settings.tracker.autoTracking.enabled = true // 1 Synerise.settings.tracker.autoTracking.mode = .fine // 2 Synerise.settings.tracker.autoTracking.excludedClasses = [SNRSampleViewController.self] // 3 Synerise.settings.tracker.autoTracking.excludedViewTags = [1, 2] // 4 ```
```Objective-C SNRSynerise.settings.tracker.autoTracking.enabled = YES; // 1 SNRSynerise.settings.tracker.autoTracking.mode = SNRTrackerAutoTrackModeFine; // 2 SNRSynerise.settings.tracker.autoTracking.excludedClasses = @[SNRSampleViewController.class]; // 3 SNRSynerise.settings.tracker.autoTracking.excludedViewTags = @[@1, @2]; // 4 ```
1. It enables/disables auto-tracking. 2. It sets auto-tracking mode. 3. It is an array of classes that you want to exclude from auto-tracking. 4. It is an array of tag numbers for views that you want to exclude from auto-tracking. #### Events from Auto-Tracking
| Action name | Description | Label | Additional information tracked | |--------------------|-----------------------------------------------------------------------------------------|---------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | screen.view | This event is generated when any screen of a mobile app is displayed by a mobile app user. | Activity, Fragment names (for example, `ProductDetailsFragment`) | | | screen.interaction | This event is generated every time a mobile app user interacts with any element of the application UI. | `viewText` or the name of control type (if not able to read a value) | Depending on the UI element type tracked, Synerise automatically reads and passes any values that are set depending on type, such as: time, date, position, progress, state, value, or if the element has been selected. |
Depending on the UI element type tracked, Synerise automatically reads and passes any values that are set depending on type, such as: time, date, position, progress, state, value, or if the element has been selected. | Action name | Description | Activity class | Label | |--------------------|-------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|-------------------------------------------------------------------------| | screen.view | This event is generated when any screen of a mobile app is displayed by a mobile app user. | `UIViewController` | View controllers name (for example, MyApp.ProductDetailsViewController) | | screen.interaction | This event is generated every time a mobile app user interacts with any element of the application UI. | `UIButton`
`UISwitch`
`UISegmentedControl`
`UISlider`
`UIStepper`
`UIDatePicker` | `viewText` or name of control type (if not able to read value) |
### Events tracked internally In addition to declarative event tracking and Auto-Tracking, many events are generated by the SDK and the Synerise infrastructure.
Read more about all [Synerise events](/docs/assets/events/event-reference/default-events)
#### Lifecycle events Some events are automatically generated by the SDK or backend as a result of the profile's activity. | Action name | Source | Description | |--------------------|--------------------|------------------| | client.applicationStarted | **SDK** | A user opened the mobile application. This event contains additional info such as operating system, device model, the sdk version etc. | | client.applicationCrashed | **SDK** | Report about a mobile application crash, with additional data for troubleshooting. | | click.errorReceiver | **SDK** | The event is called when the SDK cannot start an intent because there is no attached Activity (`ActivityNotFoundException`). | | session.start | **BACKEND** | A user opened the mobile application and a session was opened. The session ends when 30 minutes pass since the last activity. | | session.end | **BACKEND** | 30 minutes passed since the last activity and the session was closed. | In the following example of a`client.applicationStarted` event, the highlighted data is added automatically:
{
  "action": "client.applicationStarted",
  "eventUUID": "9f9f81ce-fb3d-432d-8f88-a4ce20ac3c0d",
  "label": "AppStarted",
  "params": {
    "deviceType": "SMARTPHONE", // SMARTPHONE or TABLET
    "deviceId": "B36535BD-7C80-4D90-A941-26CD4DB7FA7C",
    "osLanguage": "pl", // Language set in operating system
    "appVersionCode": "8", // Build number of the mobile app
    "systemPushConsent": "enabled", // System consent for push notifications
    "source": "MOBILE_APP",
    "networkType": "WIFI", // WIFI or CELL
    "cellCountry": "--",
    "deviceModel": "iPhone13,1", // Model of a device
    "os": "ios", // iOS or Android
    "applicationType": "UNKNOWN",
    "deviceRooted": "false",
    "applicationName": "SDK Sample App Swift",
    "appVersion": "4.16.0", // Version of the mobile app
    "cellCarrier": "--",
    "origin": "APP_STARTED",
    "deviceManufacturer": "Apple", // Manufacturer of a device
    "sdkVersion": "4.16.0", // SDK version in the mobile app
    "sdkPreviousVersion": "4.15.0", // SDK version previously installed in the mobile app
    "sdkPluginVersion": "1.2.0", // SDK plugin version in the mobile app (in hybrid apps, for example built with Flutter)
    "osVersion": "17.3.1", // OS version of a device
    "deviceId": "B36535BD-7C80-4D90-A941-26CD4DB7FA7C",
    "deviceResolution": "1080x2338", // Resolution of device screen
    (...)
  }
}
#### Profile events Some events are automatically generated as a result of an action or interaction with the profile such as registration, authorizations, and more.
Check details of [profile's events](/docs/assets/events/event-reference/profiles).
| Action name | Source | Description | |--------------------|--------------------|-----------------------------------------------------------------------------------------| | client.anonymousLogin | **BACKEND** | An anonymous profile generated a new authentication token. | | client.simpleAuthLogin | **BACKEND** | A user logged in with [Simple Profile Authentication](/developers/mobile-sdk/user-identification-and-authorization/simple-authentication) | | client.register | **BACKEND** | A profile was registered successfully. This event is only generated for Registration-as-a-Service. | | client.tryToLogInToInactiveAccount | **BACKEND** | A profile tried to log in to an inactive account. | | client.login | **BACKEND** | A user logged in mobile application. This event is only generated for OAuth and Synerise Authentication (aka RaaS). | | client.logout | **BACKEND** | A user logged out from the mobile application. By default, this event is generated only when you use Synerise Authentication (aka RaaS). | | client.merge | **BACKEND** | Two or more profiles were merged into one. | | profile.updated | **BACKEND** | A profile was updated. | #### Push Notifications events Some events are automatically generated as a result of an action or interaction of the profile with push notifications.
To ensure correct tracking of push notification events, you must [configure push notifications](/developers/mobile-sdk/configuring-push-notifications) first.
Check details of [push notification events](/docs/assets/events/event-reference/mobile-push).
| Action name | Source | Description | |--------------------|--------------------|-----------------------------------------------------------------------------------------| | push.view | **SDK** | A push notification was shown to the app user. | | push.notView | **SDK** | A push notification was sent, but the device did not display it due to the `areNotificationsEnabled` setting on the device. This event is only generated for Android 7.0 or later. | | push.click | **SDK** | A push notification was tapped. | | push.button.click | **SDK** | **DEPRECATED** A button in a push notification was tapped. | | push.openInApp | **SDK** | A push notification was tapped and the app was opened. This event is only generated for iOS. | | push.dismiss | **SDK** | A push notification was dismissed. The event requires configuring [Notification Service Extension](/developers/mobile-sdk/configuring-push-notifications/ios#synerise-notification-service-extension) for full support. | | push.imageTimeout | **SDK** | An image in a mobile push notification could not be loaded. | | push.controlGroup | **BACKEND** | A mobile push notification was not sent because the recipient belongs to the control group. | | push.send | **BACKEND** | A push notification was sent to a profile. | | push.notSent | **BACKEND** | A push notification failed to be created by the backend. Usually occurs when notification encryption is enabled in your business profile, but your application did not generate a key pair. | | push.capping | **BACKEND** | A push notification was not sent due to message limits set for this type of communication. | | push.skipped | **BACKEND** | A push notification was not sent because Silence Hours were active. If the process of sending multiple messages overlaps with Silence Hours, sending is stopped in progress. | | push.tokenUpdate | **BACKEND** | A Firebase registration token was updated in the Synerise system. | | push.tokenDelete | **BACKEND** | A Firebase registration token was deleted when a backend tried to send a push notification. Usually occurs when it is a problem with user's token. | | push.notRegistered | **BACKEND** | A push notification was not sent due to an invalid Firebase token. | | push.invalidRegistrationId | **BACKEND** | A push notification was not sent due to an incorrectly assigned registrationId in Firebase. | | push.mismatchSenderId | **BACKEND** | A push notification was not sent, because the Firebase project to which the profile was registered changed. | In these events campaign data is always tracked. See specified part of `push.view` event below:
{
  "action": "push.view",
  "eventUUID": "eca5662f-ecfd-418a-af5c-e65ba10ca252",
  "label": "Test Simple Push",
  "params": {
    "id": "ecf5678d-c137-44d1-964f-83bc8d15511e", // Campaign ID
    "variantId": 11598412, // Variant ID of the campaign
    "campaignTitle": "Test Simple Push", // Campaign title
    "campaignType": "Mobile push", // Campaign type
    (...)
  }
}
#### In-App Messages events Sort events are automatically generated as a result of an action or interaction with in-app messages by the user of the mobile app.
Read more about the details of [in-app messages events](/docs/assets/events/event-reference/inapp).
| Action name | Source | Description | |--------------------|--------------------|-----------------------------------------------------------------------------------------| | inApp.show | **SDK** | An in-app message was shown to the app user. | | inApp.capping | **SDK** | An in-app message was not displayed due to [capping](/docs/campaign/in-app-messages/create-inapp-message#capping) or [frequency limits](/docs/campaign/in-app-messages/create-inapp-message#frequency). | | inApp.click | **SDK** | The content of an in-app message was tapped. | | inApp.controlGroup | **SDK** | An in-app message was not displayed because the recipient belongs to the control group. | | inApp.discard | **SDK** | An in-app message was closed. | | inApp.hide | **SDK** | An in-app message was hidden. | | inApp.customHook | **SDK** | A custom action (implemented by your app developers and included in the in-app definition) from an in-app message was triggered. | | inApp.renderFail | **SDK** / **BACKEND** | An in-app message was not displayed due to an error. This may be caused, for example, by an error in the Jinjava syntax or a connection problem. | In these events campaign data is always tracked. See specified part of `inApp.show` event below:
{
  "action": "inApp.show",
  "eventUUID": "e982ed4d-9179-4bc3-9266-322ff4a8f2eb",
  "label": "In-app message was displayed in mobile app",
  "params": {
    "id": "83e13e0b-7930-4866-a2cf-088dcbe0b222", // Campaign ID
    "variantId": "c3bbfc16-a79e-474f-a255-ef7ee1333148", // Variant ID of the campaign
    (...)
  }
}
#### Other campaigns events Other events are which automatically generated as a result of an action related to campaigns. | Action name | Source | Description | |--------------------|--------------------|-----------------------------------------------------------------------------------------| | screen.content | **SDK** | A Screen View campaign was generated and fetched for the profile in the mobile app. It contains data with a sorted tree of the documents. | | client.activatePromotion | **BACKEND** | A promotion was activated by the profile. | | client.deactivatePromotion | **BACKEND** | A promotion was deactivated by the profile. | | recommendation.generated | **BACKEND** | A recommendation set was generated for a profile. | | recommendation.view | **SDK** | A recommendation frame was displayed to a user. The parameters may include a list of the items in the frame, depending on your implementation. Event from Content Widget. | | recommendation.seen | **SDK** | A recommendation frame was displayed to a user. The parameters may include a list of the items in the frame, depending on your implementation. Event from Content Widget. | | recommendation.click | **SDK** | A recommended item was clicked. Event from Content Widget. | | product.like | **SDK** | The Content Widget includes a "like" button that was tapped by the user. | | product.dislike | **SDK** | The Content Widget includes a "dislike" button that was tapped by the user. | ## Declarative tracking --- Declarative tracking is a feature of our SDK that allows you to declare additional actions for tracking. Product views, screen views, clicking a sign up button, contact with the call center, and more: you can implement anything and declarative tracking will help you to do that.
DO NOT send `transaction.charge` events as custom events.
Transactions must be tracked with these endpoints: - [`/v4/transactions`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) (single transaction) - [`/v4/transactions/batch`](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) (multiple transactions)
### Basic custom event In the most basic scenario, you can pass an event as in the examples below:
```Java Tracker.send(new CustomEvent("my.action", "label")); ```
```Swift let event: CustomEvent = CustomEvent(label: "label", action: "my.action") Tracker.send(event) ```
```Objective-C SNRCustomEvent *event = [[SNRCustomEvent alloc] initWithLabel:@"label" action:@"my.action"]; [SNRTracker send:event]; ```
```JavaScript let event = new CustomEvent("label", "my.action", parameters); Synerise.Tracker.send(event); ```
```Dart CustomEvent event = CustomEvent("label", "my.action", parameters); Synerise.tracker.send(event) ```
Such events are passed to Synerise as the `CustomEvent` type, since the `action` can be anything that you want.
- The action name must follow the `context.action` convention. For example: `screen.view`, `product.buy`, `social.share` - The action name must be up to 32 characters long and must match the following regular expression: ``` ^[a-zA-Z0-9\.\-_]+$ ```
### Custom events with more parameters If you want to send more complex events, you can include additional parameters:
```Java TrackerParams params = new TrackerParams.Builder() .add("name", "John") .add("surname", "Rise") .add("company", "Synerise") .add("age", 25) .add("isGreat", true) .add("lastOrder", 384.28) .add("count", 0x7fffffffffffffffL) .add("someObject", new MySerializableObject()) .build(); Tracker.send(new CustomEvent("my.action", "label", params)); ```
```Kotlin val params = TrackerParams.Builder() .add("name", "John") .add("surname", "Rise") .add("company", "Synerise") .add("age", 25) .add("isGreat", true) .add("lastOrder", 384.28) .add("count", 0x7fffffffffffffffL) .add("someObject", MySerializableObject()) .build() Tracker.send(CustomEvent("my.action", "label", params)) ```
```Swift let parameters: TrackerParams = TrackerParams.make { builder in builder.setString("John", forKey: "name") builder.setString("Rise", forKey: "surname") builder.setString("Synerise", forKey: "company") builder.setInt(57, forKey: "age") builder.setBool(true, forKey: "isGreat") builder.setDouble(384.28, forKey: "lastOrder") builder.setInt(10, forKey: "count") builder.setObject(SampleObject(), forKey: "someObject") } let event: CustomEvent = CustomEvent(label: "label", action: "my.action", params: parameters) Tracker.send(event) ```
```Objective-C SNRTrackerParams *parameters = [SNRTrackerParams makeWithBuilder:^(SNRTrackerParamsBuilder *builder) { [builder setString:@"John" forKey:@"name"]; [builder setString:@"Rise" forKey:@"surname"]; [builder setString:@"Synerise" forKey:@"company"]; [builder setInt:25 forKey:@"age"]; [builder setBool:YES forKey:@"isGreat"]; [builder setDouble:384.28 forKey:@"lastOrder"]; [builder setInt:10 forKey:@"count"]; [builder setObject:[SampleObject new] forKey:@"someObject"]; }]; SNRCustomEvent *event = [[SNRCustomEvent alloc] initWithLabel:@"label" action:@"my.action" andParams:parameters]; [SNRTracker send:event]; ```
```JavaScript let parameters = { "name": "John", "surname": "Rise", "company": "Synerise", "age": 25, "lastOrder": 380.50 }; let event = new CustomEvent("label", "my.action", parameters); Synerise.Tracker.send(event); ```
```Dart final parameters = { "name": "Rise", "surname": "Rise", "company": "Synerise", "age": 25, "lastOrder": 380.50 }; CustomEvent event = CustomEvent("label", "my.action", parameters); Synerise.tracker.send(event) ```
The following keys are reserved and you can't send them: **modifiedBy**, **apiKey**, **eventUUID**, **ip**, **time**, **businessProfileId**. If you add them to an event, they are ignored.
### Predefined events Synerise offers a set of predefined event types that require a minimum set of data for the backend. They can be sent by using Setters as in the following example. The example uses the [Product viewed](#product-viewed) event.
```java TrackerParams params = new TrackerParams.Builder() .add("campaignHash", "4321") .add("campaignId", "1234") .build(); ProductViewEvent event = new ProductViewEvent(("Smartphone X", "SM-01-S", "Smartphone X”, params); event.setCategory(“Smartphones”); event.setUrl(“myapp://products/CM01-R"); Tracker.send(event); ```
```kotlin val params = TrackerParams.Builder() .add("campaignHash", "4321") .add("campaignId", "1234") .build() val event = ProductViewEvent(("Smartphone X"), "SM-01-S", "Smartphone X", params) event.setCategory("Smartphones") event.setUrl("myapp://products/CM01-R") Tracker.send(event) ```
```Swift let parameters: TrackerParams = TrackerParams.make { builder in builder.setString("12345", forKey: "campaignId") builder.setString("campaign12345", forKey: "campaignHash") } let event: ProductViewEvent = ProductViewEvent(label: "Smartphone X", productName: "Smartphone X", productID:"SM-01-S", params: parameters) event.setCategory("Smartphones") event.setURL(URL(string: "myapp://products/SM-01-S") Tracker.send(event) ```
```Objective-C SNRTrackerParams *parameters = [SNRTrackerParams makeWithBuilder:^(SNRTrackerParamsBuilder *builder) { [builder setString:@"12345" forKey:@"campaignId"]; [builder setString:@"campaign12345" forKey:@"campaignHash"]; }]; SNRProductViewEvent *event = [[SNRProductViewEvent alloc] initWithLabel:@"Smartphone X" productName:@"Smartphone X" productId:@"SM-01-S" andParams:parameters]; [event setCategory:@"Smartphones"]; [event setURL:[NSURL URLWithString:@"myapp://products/SM-01-S"]]; [SNRTracker send:event]; ```
```JavaScript let parameters = { "campaignHash": "1234", "campaignId": "1234" }; let event = ProductViewEvent("Smartphone X", "Smartphone X", "SM-01-S", parameters); event.setCategory("Smartphones"); event.setURL("myapp://products/SM-01-S"); Synerise.Tracker.send(event); ```
```Dart Map parameters = { "campaignHash": "1234", "campaignId": "1234", }; var event = ProductViewEvent( "Smartphone X", "Smartphone X", "SM-01-S", parameters, ); event.setCategory("Smartphones"); event.setURL("myapp://products/SM-01-S"); Synerise.tracker.send(event) ```
| **Android** | **iOS** | **React Native** | **Flutter** | | --------------- | ----------------- | ----------------------- | ----------------------- | | [Tracker.send(event)](/developers/mobile-sdk/method-reference/android/tracking#send-event) method | [Tracker.send(_:)](/developers/mobile-sdk/method-reference/ios/tracking#send-event) method | [Synerise.Tracker.send(event)](/developers/mobile-sdk/method-reference/react-native/tracking#send-event) method | [Synerise.tracker.send(event)](/developers/mobile-sdk/method-reference/flutter/tracking#send-event) method | ## Predefined event list --- The list contains the list of predefined events which you can implement. ### Customer registered --- This event may be used if you do not use [Synerise registration/authentication](/developers/mobile-sdk/user-identification-and-authorization/overview) features and rely fully on your own mechanisms, but still want to gather events when a customer registers. **Action name of the generated event**: client.register **Example**:
```Java RegisteredEvent event = new RegisteredEvent("label") Tracker.send(event); ```
```Kotlin val event = RegisteredEvent("label") Tracker.send(event) ```
```Swift let event: RegisteredEvent = RegisteredEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRRegisteredEvent *event = [[SNRRegisteredEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { user: 'John', lastName: 'Doe', } let registeredEvent = new RegisteredEvent('Auth label', object) Synerise.Tracker.send(registeredEvent) ```
```Dart RegisteredEvent registeredEvent = RegisteredEvent('label', {}); Synerise.tracker.send(registeredEvent); ```
| OS | Event | Required fields | |--------------|----------------------------------------------------------------------------------------------------------------------|-----------------| | Android | [RegisteredEvent](/developers/mobile-sdk/class-reference/android/events#registeredevent) | Label | | iOS | [RegisteredEvent](/developers/mobile-sdk/class-reference/ios/events#registeredevent) | Label | | React Native | [RegisteredEvent](/developers/mobile-sdk/class-reference/react-native/events#registeredevent) | Label | | Flutter | [RegisteredEvent](/developers/mobile-sdk/class-reference/flutter/events#registeredevent) | Label | ### Customer logged in event --- This event may be used if you do not use [Synerise login/authentication](/developers/mobile-sdk/user-identification-and-authorization/overview) features and rely fully on your own mechanisms, but still want to gather events when a customer logs in. **Action name of the generated event**: client.login
Logged in event
Logged in event
**Example**:
```Java LoggedInEvent event = new LoggedInEvent("label") Tracker.send(event); ```
```Kotlin val event = LoggedInEvent("label") Tracker.send(event) ```
```Swift let event: LoggedInEvent = LoggedInEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRLoggedInEvent *event = [[SNRLoggedInEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { user: 'John', lastName: 'Doe', } let loggedInEvent = new LoggedInEvent('Auth label', object) Synerise.Tracker.send(loggedInEvent) ```
```Dart LoggedInEvent event = LoggedInEvent('label', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|-------------------------------------------------------------------------------------------------------------------|-----------------| | Android | [LoggedInEvent](/developers/mobile-sdk/class-reference/android/events#loggedinevent) | Label | | iOS | [LoggedInEvent](/developers/mobile-sdk/class-reference/ios/events#loggedinevent) | Label | | React Native | [LoggedInEvent](/developers/mobile-sdk/class-reference/react-native/events#loggedinevent) | Label | | Flutter | [LoggedInEvent](/developers/mobile-sdk/class-reference/flutter/events#loggedinevent) | Label | ### Customer logged out --- This event may be used if you do not use [Synerise login/authentication](/developers/mobile-sdk/user-identification-and-authorization/overview) features and rely fully on your own mechanisms, but still want to gather events when a customer logs out. **Action name of the generated event**: client.logout **Example**:
```Java LoggedOutEvent event = new LoggedOutEvent("label") Tracker.send(event); ```
```Kotlin val event = LoggedOutEvent("label") Tracker.send(event) ```
```Swift let event: LoggedOutEvent = LoggedOutEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRLoggedOutEvent *event = [[SNRLoggedOutEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { user: 'John', lastName: 'Doe', } let loggedOutEvent = new LoggedOutEvent('Auth label', object) Synerise.Tracker.send(loggedOutEvent) ```
```Dart LoggedOutEvent event = LoggedOutEvent('label', {}) Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|---------------------------------------------------------------------------------------------------------------------|-----------------| | Android | [LoggedOutEvent](/developers/mobile-sdk/class-reference/android/events#loggedoutevent) | Label | | iOS | [LoggedOutEvent](/developers/mobile-sdk/class-reference/ios/events#loggedoutevent) | Label | | React Native | [LoggedOutEvent](/developers/mobile-sdk/class-reference/react-native/events#loggedoutevent) | Label | | Flutter | [LoggedOutEvent](/developers/mobile-sdk/class-reference/flutter/events#loggedoutevent) | Label | ### Product viewed --- Use this event to track customer visits to a product in your mobile application. **Action name of the generated event**: product.view
Event sent when the mobile app user sees an item
Event sent when the mobile app user sees an item
**Example**:
```Java ProductViewEvent event = new ProductViewEvent("label", "productId", "productName"); Tracker.send(event); ```
```Kotlin val event = ProductViewEvent("label", "productId", "productName") Tracker.send(event) ```
```Swift let event: ProductViewedEvent = ProductViewedEvent(label: "LABEL", productName: "PRODUCT_NAME", productId: "12345", params: nil) event.setCategory("PRODUCT_CATEGORY") event.setURL(URL(string: "PRODUCT_URL")!) event.setIsRecommended(true) Tracker.send(event) ```
```Objective-C SNRProductViewedEvent *event = [[SNRProductViewedEvent alloc] initWithLabel:@"LABEL" productName:@"PRODUCT_NAME" productId:@"12345" andParams:nil]; [event setCategory:@"PRODUCT_CATEGORY"]; [event setURL:[NSURL URLWithString:@"PRODUCT_URL"]]; [event setIsRecommended:YES]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { campaign: 'Computer bargain', lastTo: 'December', } let productEventTest = new ProductViewEvent('product view label', '1234', 'Computer', object) Synerise.Tracker.send(productEventTest) ```
```Dart ProductViewedEvent event = ProductViewedEvent('label', 'productId', 'productName',{}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|-------------------------------------------------------------------------------------------------------------------------|------------------------| | Android | [ProductViewEvent](/developers/mobile-sdk/class-reference/android/events#productviewevent) | Label, ProductId, Name | | iOS | [ProductViewedEvent](/developers/mobile-sdk/class-reference/ios/events#productviewedevent) | Label, ProductId, Name | | React Native | [ProductViewedEvent](/developers/mobile-sdk/class-reference/react-native/events#productviewedevent) | Label, ProductId, Name | | Flutter | [ProductViewedEvent](/developers/mobile-sdk/class-reference/flutter/events#productviewedevent) | Label, ProductId, Name | ### Product added to favorites --- Use this event to track adding a product to favorites in your mobile application. **Action name of the generated event**: product.addToFavorite
Event sent when a mobile app user adds an item to favorites
Event sent when a mobile app user adds an item to favorites
**Example**:
```Java AddedToFavoritesEvent event = new AddedToFavoritesEvent("label"); Tracker.send(event); ```
```Kotlin val event = AddedToFavoritesEvent("label") Tracker.send(event) ```
```Swift let event: ProductAddedToFavoritesEvent = ProductAddedToFavoritesEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRProductAddedToFavoritesEvent *event = [[SNRProductAddedToFavoritesEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { product: 'computer', screenSize: 15, } let event = new AddedToFavouritesEvent('Hit Timer Event Label', object) Synerise.Tracker.send(event) ```
```Dart ProductAddedToFavoritesEvent event = ProductAddedToFavoritesEvent('label',{}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|---------------------------------------------------------------------------------------------------------------------------------|-----------------------------------| | Android | [AddedToFavoritesEvent](/developers/mobile-sdk/class-reference/android/events#addedtofavoritesevent) | Label | | iOS | [ProductAddedToFavoritesEvent](/developers/mobile-sdk/class-reference/ios/events#productremovedfromcartevent) | Label | | React Native | [ProductAddedToFavouritesEvent](/developers/mobile-sdk/class-reference/react-native/events#productaddedtofavoritesevent) | Label | | Flutter | [ProductAddedToFavouritesEvent](/developers/mobile-sdk/class-reference/flutter/events#productaddedtofavoritesevent) | Label | ### Product added to cart --- Use this event to track adding a product to a cart in your mobile application. **Action name of the generated event**: product.addToCart
Event sent when a user adds an item to cart
Event sent when a mobile app user adds an item to cart
**Example**:
```Java UnitPrice unitPrice = new UnitPrice(price, Currency.getInstance(Locale.US)); AddedToCartEvent event = new AddedToCartEvent("label", "sku", unitPrice, 1); Tracker.send(event); ```
```Kotlin val unitPrice = UnitPrice(price, Currency.getInstance(Locale.US)) val event = AddedToCartEvent("label", "sku", unitPrice, 1) Tracker.send(event) ```
```Swift let regularPrice: UnitPrice = UnitPrice(amount: 200) let discountedPrice: UnitPrice = UnitPrice(amount: 100) let finalPrice: UnitPrice = UnitPrice(amount: 100) let event: ProductAddedToCartEvent = ProductAddedToCartEvent(label: "LABEL", sku: "SKU12345", finalPrice: finalPrice, quantity: 1) event.setName("PRODUCT_NAME") event.setCategory("PRODUCT_CATEGORY") event.setCategories(["PRODUCT_CATEGORY_1", "PRODUCT_CATEGORY_2"]) event.setProducer("PRODUCT_PRODUCER") event.setOffline(false) event.setRegularPrice(regularPrice) event.setDiscountedPrice(discountedPrice) event.setURL(URL(string: "URL")!) Tracker.send(event) ```
```Objective-C SNRProductAddedToCartEvent *event = [[SNRProductAddedToCartEvent alloc] initWithLabel:@"LABEL" sku:@"SKU12345" finalPrice:finalPrice quantity:1]; [event setName:@"PRODUCT_NAME"]; [event setCategory:@"PRODUCT_CATEGORY"]; [event setCategories:@[@"PRODUCT_CATEGORY_1", @"PRODUCT_CATEGORY_2"]]; [event setProducer:@"PRODUCT_PRODUCER"]; [event setOffline:NO]; [event setRegularPrice:regularPrice]; [event setDiscountedPrice:discountedPrice]; [event setURL:[NSURL URLWithString:@"URL"]]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { campaign: 'Computer bargain', lastTo: 'December', } let price = new UnitPrice(10, 'PLN') let addedToCartEvent = new AddedToCartEvent('Cart Label', '12345', price, 15, object) Synerise.Tracker.send(addedToCartEvent) ```
```Dart UnitPrice unitPrice = UnitPrice(price,'PLN'); ProductAddedToCartEvent event = ProductAddedToCartEvent('label', 'sku', unitPrice, 1, {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|---------------------------------------------------------------------------------------------------------------------------------|-----------------------------------| | Android | [AddedToCartEvent](/developers/mobile-sdk/class-reference/android/events#addedtocartevent) | Label, Sku, FinalPrice, Quantity | | iOS | [ProductAddedToCartEvent](/developers/mobile-sdk/class-reference/ios/events#productaddedtocartevent) | Label, SKU, FinalPrice, Quantity | | React Native | [ProductAddedToCartEvent](/developers/mobile-sdk/class-reference/react-native/events#productaddedtocartevent) | Label, SKU, FinalPrice, Quantity | | Flutter | [ProductAddedToCartEvent](/developers/mobile-sdk/class-reference/flutter/events#productaddedtocartevent) | Label, SKU, FinalPrice, Quantity | ### Product removed from cart --- Use this event to track removing a product from a cart in your mobile application. **Action name of the generated event**: product.removeFromCart **Example**:
```Java UnitPrice unitPrice = new UnitPrice(price, Currency.getInstance(Locale.US)); RemovedFromCartEvent event = new RemovedFromCartEvent("label", "sku", unitPrice, 1); Tracker.send(event); ```
```Kotlin val unitPrice = UnitPrice(price, Currency.getInstance(Locale.US)) val event = RemovedFromCartEvent("label", "sku", unitPrice, 1) Tracker.send(event) ```
```Swift let regularPrice: UnitPrice = UnitPrice(amount: 200) let discountedPrice: UnitPrice = UnitPrice(amount: 100) let finalPrice: UnitPrice = UnitPrice(amount: 100) let event: ProductRemovedFromCartEvent = ProductRemovedFromCartEvent(label: "LABEL", sku: "SKU12345", finalPrice: finalPrice, quantity: 1) event.setName("PRODUCT_NAME") event.setCategory("PRODUCT_CATEGORY") event.setCategories(["PRODUCT_CATEGORY_1", "PRODUCT_CATEGORY_2"]) event.setProducer("PRODUCT_PRODUCER") event.setOffline(false) event.setRegularPrice(regularPrice) event.setDiscountedPrice(discountedPrice) event.setURL(URL(string: "URL")!) Tracker.send(event) ```
```Objective-C SNRProductRemovedFromCartEvent *event = [[SNRProductRemovedFromCartEvent alloc] initWithLabel:@"LABEL" sku:@"SKU12345" finalPrice:finalPrice quantity:1]; [event setName:@"PRODUCT_NAME"]; [event setCategory:@"PRODUCT_CATEGORY"]; [event setCategories:@[@"PRODUCT_CATEGORY_1", @"PRODUCT_CATEGORY_2"]]; [event setProducer:@"PRODUCT_PRODUCER"]; [event setOffline:NO]; [event setRegularPrice:regularPrice]; [event setDiscountedPrice:discountedPrice]; [event setURL:[NSURL URLWithString:@"URL"]]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { campaign: 'Computer bargain', lastTo: 'December', } let price = new UnitPrice(10, 'PLN') let removedFromCartEvent = new RemovedFromCartEvent('Cart Label', '12345', price, 15, object) Synerise.Tracker.send(removedFromCartEvent) ```
```Dart UnitPrice unitPrice = UnitPrice(price, 'PLN'); ProductRemovedFromCartEvent event = ProductRemovedFromCartEvent('label', 'sku', unitPrice, 1, {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|---------------------------------------------------------------------------------------------------------------------------------|-----------------------------------| | Android | [RemovedFromCartEvent](/developers/mobile-sdk/class-reference/android/events#removedfromcartevent) | Label, Sku, FinalPrice, Quantity | | iOS | [ProductRemovedFromCartEvent](/developers/mobile-sdk/class-reference/ios/events#productremovedfromcartevent) | Label, SKU, FinalPrice, Quantity | | React Native | [ProductRemovedFromCartEvent](/developers/mobile-sdk/class-reference/react-native/events#productremovedfromcartevent) | Label, SKU, FinalPrice, Quantity | | Flutter | [ProductRemovedFromCartEvent](/developers/mobile-sdk/class-reference/flutter/events#productremovedfromcartevent) | Label, SKU, FinalPrice, Quantity | ### Recommendation viewed Use this event to track when a recommendation is displayed to a customer. **Action name of the generated event**: recommendation.view **For iOS and Android only**: If you use the [Widget](/developers/mobile-sdk/displaying-recommendations/content-widget/android) to present recommendations, this event is tracked automatically. **Example**:
```Java List items = Arrays.asList("PRODUCT_ID_1", "PRODUCT_ID_2!"); RecommendationViewEvent event = new RecommendationViewEvent("LABEL", items, "12345", "1234", "corr", params) Tracker.send(event) ```
```Kotlin val items = listOf("PRODUCT_ID_1", "PRODUCT_ID_2") val event = RecommendationViewEvent("LABEL", items, "12345", "1234", "corr", params) Tracker.send(event) ```
```Swift let event = RecommendationViewEvent(label: "LABEL", campaignID: "1234", campaignHash: "1234", correlationId: "corr", params: nil) event.setItems([ "PRODUCT_ID_1", "PRODUCT_ID_2" ]) Tracker.send(event) ```
```Objective-C RecommendationViewEvent *event = [[RecommendationViewEvent alloc] initWithLabel:@"LABEL" campaignID:(NSString *)campaignID campaignHash:(NSString *)campaignHash correlationId:(NSString *)correlationId andParams:(nullable SNRTrackerParams *)params]; [event setItems:@[ @"PRODUCT_ID_1", @"PRODUCT_ID_2" ]]; [SNRTracker send:event]; ```
```Dart List items = ['PRODUCT_ID_1', 'PRODUCT_ID_2!']; RecommendationViewEvent event = RecommendationViewEvent('LABEL', '12345', items, '213', '234', 'corr', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|---------------------------------------------------------------------------------------------------------------------------------------| --- | | Android | [RecommendationViewEvent](/developers/mobile-sdk/class-reference/android/events#recommendationviewevent) | Label, items OR ProductId and Name, CampaignId, CampaignHash | | iOS | [RecommendationViewEvent](/developers/mobile-sdk/class-reference/ios/events#recommendationviewevent) | Label, items, Name, CampaignId, CampaignHash | | Flutter | [RecommendationViewEvent](/developers/mobile-sdk/class-reference/flutter/events#recommendationviewevent) | Label, items, Name, CampaignId, CampaignHash | ### ~~Recommendation seen~~ ---
This is a legacy event. You should use [recommendation.view](#recommendation-viewed) instead.
Use this event to track recommendation display to a customer. **Action name of the generated event**: recommendation.seen **For iOS and Android only**: If you use the [Widget](/developers/mobile-sdk/displaying-recommendations/content-widget/android) to present recommendations, this event is tracked automatically. **Example**:
```Java RecommendationSeenEvent event = new RecommendationSeenEvent("label", "productId", "productName", "campaignId", "campaignHash"); Tracker.send(event); ```
```Kotlin val event = RecommendationSeenEvent("label", "productId", "productName", "campaignId", "campaignHash") Tracker.send(event) ```
```Swift let event: RecommendationSeenEvent = RecommendationSeenEvent(label: "LABEL", productName: "PRODUCT_NAME", productId: "12345", campaignID: "12345", campaignHash: "CAMPAIGN_HASH", params: nil) event.setCategory("PRODUCT_CATEGORY") event.setURL(URL(string: "PRODUCT_URL")!) Tracker.send(event) ```
```Objective-C SNRRecommendationSeenEvent *event = [[SNRRecommendationSeenEvent alloc] initWithLabel:@"LABEL" productName:@"PRODUCT_NAME" productId:@"12345" campaignID:@"12345" campaignHash:@"CAMPAIGN_HASH" andParams:nil]; [event setCategory:@"PRODUCT_CATEGORY"]; [event setURL:[NSURL URLWithString:@"PRODUCT_URL"]]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { product: 'computer', screenSize: 15, } let eventSeen = new RecommendationSeenEvent('Recommendation.ts Seen label', '12351', 'Nike Boots', '12345', 'test', object) Synerise.Tracker.send(eventSeen) ```
```Dart RecommendationSeenEvent event = RecommendationSeenEvent('label', 'productId', 'productName', 'campaignId', 'campaignHash',{}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|---------------------------------------------------------------------------------------------------------------------------------------| --- | | Android | [RecommendationSeenEvent](/developers/mobile-sdk/class-reference/android/events#recommendationseenevent) | Label, ProductId,Name, CampaignId, CampaignHash | | iOS | [RecommendationSeenEvent](/developers/mobile-sdk/class-reference/ios/events#recommendationseenevent) | Label, ProductId, Name, CampaignId, CampaignHash | | React Native | [RecommendationSeenEvent](/developers/mobile-sdk/class-reference/react-native/events#recommendationseenevent) | Label, ProductId, Name, CampaignId, CampaignHash | | Flutter | [RecommendationSeenEvent](/developers/mobile-sdk/class-reference/flutter/events#recommendationseenevent) | Label, ProductId, Name, CampaignId, CampaignHash | ### Recommendation clicked --- Use this event to track recommendation clicks. **Action name of the generated event**: recommendation.click **For iOS and Android only**: If you use the [Widget](/developers/mobile-sdk/displaying-recommendations/content-widget/android) to present recommendations, this event is tracked automatically. **Example**:
```Java RecommendationClickEvent event = new RecommendationClickEvent("label", "productId", "productName", "campaignId", "campaignHash"); Tracker.send(event); ```
```Kotlin val event = RecommendationClickEvent("label", "productId", "productName", "campaignId", "campaignHash") Tracker.send(event) ```
```Swift let event: RecommendationClickEvent = RecommendationClickEvent(label: "LABEL", productName: "PRODUCT_NAME", productId: "12345", campaignID: "12345", campaignHash: "CAMPAIGN_HASH", params: nil) event.setCategory("PRODUCT_CATEGORY") event.setURL(URL(string: "PRODUCT_URL")!) Tracker.send(event) ```
```Objective-C SNRRecommendationClickEvent *event = [[SNRRecommendationClickEvent alloc] initWithLabel:@"LABEL" productName:@"PRODUCT_NAME" productId:@"12345" campaignID:@"12345" campaignHash:@"CAMPAIGN_HASH" andParams:nil]; [event setCategory:@"PRODUCT_CATEGORY"]; [event setURL:[NSURL URLWithString:@"PRODUCT_URL"]]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { product: 'computer', screenSize: 15, } let event = new RecommendationClickEvent('Recommendation.ts Click label', '12351', 'Boots', '12345', 'test') Synerise.Tracker.send(event) ```
```Dart RecommendationClickEvent event = RecommendationClickEvent('label', 'productId', 'productName', 'campaignId', 'campaignHash', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|---------------------------------------------------------------------------------------------------------------------------------------| --- | | Android | [RecommendationClickEvent](/developers/mobile-sdk/class-reference/android/events#recommendationclickevent) | Label, ProductId,Name, CampaignId, CampaignHash | | iOS | [RecommendationClickEvent](/developers/mobile-sdk/class-reference/ios/events#recommendationclickevent) | Label, ProductId, Name, CampaignId, CampaignHash | | React Native | [RecommendationClickEvent](/developers/mobile-sdk/class-reference/react-native/events#recommendationclickevent) | Label, ProductId, Name, CampaignId, CampaignHash | | Flutter | [RecommendationClickEvent](/developers/mobile-sdk/class-reference/flutter/events#recommendationclickevent) | Label, ProductId, Name, CampaignId, CampaignHash | ### Customer appeared in location --- Use this event to track a customer's presence at a location by passing geographic coordinates. 1. Send a [silent push](/developers/mobile-sdk/campaigns/silent-push) with the Synerise command `GET_LOCATION`. 2. SDK retrieves the location. 3. Use the data from the `GET_LOCATION` response to send the `AppearedInLocation` event. **Action name of the generated event**: client.location
Appeared in location event sent after sending silent notification
The "appeared in location" event is sent after a silent push
**Example**:
```Java AppearedInLocationEvent event = new AppearedInLocationEvent("label", 48.1599, 11.5761); Tracker.send(event); ```
```Kotlin val event = AppearedInLocationEvent("label", 48.1599, 11.5761) Tracker.send(event) ```
```Swift let latitude: CLLocationDegrees = CLLocationDegrees(52.237049) let longitude: CLLocationDegrees = CLLocationDegrees(21.017532) let location: CLLocation = CLLocation(latitude: latitude, longitude: longitude) let event: AppearedInLocationEvent = AppearedInLocationEvent(label: "LABEL", location: location) Tracker.send(event) ```
```Objective-C CLLocationDegrees latitude = 52.237049; CLLocationDegrees longitude = 21.017532; CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude]; SNRAppearedInLocationEvent *event = [[SNRAppearedInLocationEvent alloc] initWithLabel:@"LABEL" andLocation:location]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { number: 5, } let event = new AppearedInLocationEvent('Hit Timer Event Label', 10, 20, object) Synerise.Tracker.send(event) ```
```Dart AppearedInLocationEvent event = AppearedInLocationEvent('label', 48.1599, 11.5761, {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|----------------------------------------------------------------------------------------------------------------- |----------------------------| | Android | [AppearedInLocationEvent](/developers/mobile-sdk/class-reference/android/events#appearedinlocationevent) | Label, Latitude, Longitude | | iOS | [AppearedInLocationEvent](/developers/mobile-sdk/class-reference/ios/events#appearedinlocationevent) | Label, Latitude, Longitude | | React Native | [AppearedInLocationEvent](/developers/mobile-sdk/class-reference/react-native/events#appearedinlocationevent) | Label, Latitude, Longitude | | Flutter | [AppearedInLocationEvent](/developers/mobile-sdk/class-reference/flutter/events#appearedinlocationevent) | Label, Latitude, Longitude | ### Customer activity timer --- Use this event to measure the duration of any customer activity - send Hit timer when a customer starts an activity and send it again with a different time signature when the customer finishes. After that, you can use the [Decision Hub](/docs/analytics) to measure, for example, average activity time. You can add a custom parameter to the timer events so you can recognize them. **Action name of the generated event**: client.hitTimer **Example**:
```Java HitTimerEvent event = new HitTimerEvent("label"); Tracker.send(event); ```
```Kotlin val event = HitTimerEvent("label") Tracker.send(event) ```
```Swift let event: HitTimerEvent = HitTimerEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRHitTimerEvent *event = [[SNRHitTimerEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript let sendHitTimerEvent = function() { var object: Object = { timer: 'anti-clockwise', number: 5, } let event = new HitTimerEvent('Hit Timer Event Label', object) Synerise.Tracker.send(event) ```
```Dart HitTimerEvent event = HitTimerEvent('label',{}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|-------------------------------------------------------------------------------------------------------------------|-----------------| | Android | [HitTimerEvent](/developers/mobile-sdk/class-reference/android/events#hittimerevent) | Label | | iOS | [HitTimerEvent](/developers/mobile-sdk/class-reference/ios/events#hittimerevent) | Label | | React Native | [HitTimerEvent](/developers/mobile-sdk/class-reference/react-native/events#hittimerevent) | Label | | Flutter | [HitTimerEvent](/developers/mobile-sdk/class-reference/flutter/events#hittimerevent) | Label | ### Customer searched --- Use this event to track search queries - every time a customer types a query in the search box in your mobile application, this event will be generated. **Action name of the generated event**: client.search **Example**:
```Java SearchedEvent event = new SearchedEvent("label"); Tracker.send(event); ```
```Kotlin val event = SearchedEvent("label") Tracker.send(event) ```
```Swift let event: SearchedEvent = SearchedEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRSearchedEvent *event = [[SNRSearchedEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { timer: 'anti-clockwise', number: 5, } let event = new HitTimerEvent('Hit Timer Event Label', object) Synerise.Tracker.send(event) ```
```Dart SearchedEvent event = SearchedEvent('label', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|-------------------------------------------------------------------------------------------------------------------|-----------------| | Android | [SearchedEvent](/developers/mobile-sdk/class-reference/android/events#searchedevent) | Label | | iOS | [SearchedEvent](/developers/mobile-sdk/class-reference/ios/events#searchedevent) | Label | | React Native | [SearchedEvent](/developers/mobile-sdk/class-reference/react-native/events#searchedevent) | Label | | Flutter | [SearchedEvent](/developers/mobile-sdk/class-reference/flutter/events#searchedevent) | Label | ### Customer shared --- Use this event to track customer sharing something from your application. **Action name of the generated event**: client.shared **Example**:
```Java SharedEvent event = new SharedEvent("label"); Tracker.send(event); ```
```Kotlin val event = SharedEvent("label") Tracker.send(event) ```
```Swift let event: SharedEvent = SharedEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRSharedEvent *event = [[SNRSharedEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript var object: Object = { sharedEvents: '5', field: 'test', } let event = new SharedEvent('Shared Event Label', object) Synerise.Tracker.send(event) ```
```Dart SharedEvent event = new SharedEvent('label',{}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|--------------------------------------------------------------------------------------------------------------|-----------------| | Android | [SharedEvent](/developers/mobile-sdk/class-reference/android/events#sharedevent) | Label | | iOS | [SharedEvent](/developers/mobile-sdk/class-reference/ios/events#sharedevent) | Label | | React Native | [SharedEvent](/developers/mobile-sdk/class-reference/react-native/events#sharedevent) | Label | | Flutter | [SharedEvent](/developers/mobile-sdk/class-reference/flutter/events#sharedevent) | Label | ### Customer visited a screen --- This event is used when a customer visits a particular screen in your application. **Action name of the generated event**: screen.view
Event sent when a user visits a screen
Event sent when a mobile app user visits a screen
**Example**:
```Java VisitedScreenEvent event = new VisitedScreenEvent("label"); Tracker.send(event); ```
```Kotlin val event = VisitedScreenEvent("label") Tracker.send(event) ```
```Swift let event: VisitedScreenEvent = VisitedScreenEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRVisitedScreenEvent *event = [[SNRVisitedScreenEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```JavaScript let sendVisitedScreenEvent = function() { var object: Object = { screen: '1', age: '25', } let event = new VisitedScreenEvent('Visited Screen label', object) Synerise.Tracker.send(event) ```
```Dart VisitedScreenEvent event = VisitedScreenEvent('label', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|----------------------------------------------------------------------------------------------------------------------|-----------------| | Android | [VisitedScreenEvent](/developers/mobile-sdk/class-reference/android/events#visitedscreenevent) | Label | | iOS | [VisitedScreenEvent](/developers/mobile-sdk/class-reference/ios/events#visitedscreenevent) | Label | | React Native | [VisitedScreenEvent](/developers/mobile-sdk/class-reference/react-native/events#visitedscreenevent) | Label | | Flutter | [VisitedScreenEvent](/developers/mobile-sdk/class-reference/flutter/events#visitedscreenevent) | Label | ### Crash Event --- This event is used when the application crashes. The event is sent automatically by **Synerise SDK** when you enable [crash handling](/developers/mobile-sdk/miscellaneous#crash-handling) while configuring the SDK. You can send it by yourself when you handle an uncaught exception. **Action name of the generated event**: client.applicationCrashed **Example**:
```Swift let event: CrashEvent = CrashEvent(label: "LABEL") event.setExceptionName("EXCEPTION_NAME") event.setExceptionReason("EXCEPTION_REASON") event.setExceptionStacktrace("EXCEPTION_STACKTRACE") Tracker.send(event) ```
```Objective-C SNRCrashEvent *event = [[SNRCrashEvent alloc] initWithLabel:@"LABEL"]; [event setExceptionName:@"EXCEPTION_NAME"]; [event setExceptionReason:@"EXCEPTION_REASON"]; [event setExceptionStacktrace:@"EXCEPTION_STACKTRACE"]; [SNRTracker send:event]; ```
| OS | Event | Required fields | |--------------|------------------------------------------------------------------------------------------------------------|-----------------| | Android | [CrashEvent](/developers/mobile-sdk/class-reference/android/events#crashevent) | Label | | iOS | [CrashEvent](/developers/mobile-sdk/class-reference/ios/events#crashevent) | Label | | React Native | n/a | Label | | Flutter | n/a | Label | ### Push viewed --- Use this event to track viewing a push notification.
Push events are tracked automatically for Android and React Native (if the notifications have been configured for React Native according to [iOS](/developers/mobile-sdk/configuring-push-notifications/react-native#setting-up-ios) or [Android](/developers/mobile-sdk/configuring-push-notifications/react-native#setting-up-android) ).
**Action name of the generated event**: push.view
```Swift let event: PushViewedEvent = PushViewedEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRPushViewedEvent *event = [[SNRPushViewedEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```Dart PushViewedEvent event = PushViewedEvent('label', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|------------------------------------------------------------------------------------------------------------|-----------------| | Android | [PushViewedEvent](/developers/mobile-sdk/class-reference/android/events#viewedpushevent) | Label | | iOS | [PushViewedEvent](/developers/mobile-sdk/class-reference/ios/events/#pushviewedevent ) | Label | | React Native | [PushViewedEvent](/developers/mobile-sdk/class-reference/react-native/events#pushviewedevent) | Label | | Flutter | [PushViewedEvent](/developers/mobile-sdk/class-reference/flutter/events#pushviewedevent) | Label | ### Push clicked --- Use this event to track tapping a push notification.
Push events are tracked automatically for Android and React Native (if the notifications have been configured for React Native according to [iOS](/developers/mobile-sdk/configuring-push-notifications/react-native#setting-up-ios) or [Android](/developers/mobile-sdk/configuring-push-notifications/react-native#setting-up-android) ).
**Action name of the generated event**: push.click
```Swift let event: PushClickedEvent = PushClickedEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRPushClickedEvent *event = [[SNRPushClickedEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```Dart PushClickedEvent event = PushClickedEvent('label', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|------------------------------------------------------------------------------------------------------------|-----------------| | Android | [ClickedPushEvent](/developers/mobile-sdk/class-reference/android/events#clickedpushevent) | Label | | iOS | [PushClickedEvent](/developers/mobile-sdk/class-reference/ios/events#pushclickedevent) | Label | | React Native | [ClickedPushEvent](/developers/mobile-sdk/class-reference/react-native/events#pushclickedevent) | Label | | Flutter | [PushClickedEvent](/developers/mobile-sdk/class-reference/flutter/events#pushclickedevent) | Label | ### Push cancelled --- Use this event to track dismissing push notifications.
Push events are tracked automatically for Android and React Native (if the notifications have been configured for React Native according to [iOS](/developers/mobile-sdk/configuring-push-notifications/react-native#setting-up-ios) or [Android](/developers/mobile-sdk/configuring-push-notifications/react-native#setting-up-android) ).
**Action name of the generated event**: push.dismiss
```Swift let event: PushCancelledEvent = PushCancelledEvent(label: "LABEL") Tracker.send(event) ```
```Objective-C SNRPushCancelledEvent *event = [[SNRPushCancelledEvent alloc] initWithLabel:@"LABEL"]; [SNRTracker send:event]; ```
```Dart PushCancelledEvent event = PushCancelledEvent('label', {}); Synerise.tracker.send(event); ```
| OS | Event | Required fields | |--------------|------------------------------------------------------------------------------------------------------------|-----------------| | Android | [CancelledPushEvent](/developers/mobile-sdk/class-reference/android/events#cancelledpushevent) | Label | | iOS | [PushCancelledEvent](/developers/mobile-sdk/class-reference/ios/events#pushclickedevent) | Label | | React Native | [PushCancelledEvent](/developers/mobile-sdk/class-reference/react-native/events#pushcancelledevent) | Label | | Flutter | [PushCancelledEvent](/developers/mobile-sdk/class-reference/flutter/events#pushcancelledevent) | Label | ### Recommendation API filters You can manipulate item filters when making the request. ## Filter types
For a detailed description of filter types, see [the User Guide](/docs/ai-hub/recommendations-v2/recommendation-filters#filter-types).
### IQL filters An IQL filter is a string built using the [Items Query Language](/developers/iql). It allows you to combine filters and apply logic such as IF statements to build criteria that an item must meet to be included in the recommendation response. Elastic IQL filters let you supplement the recommendation result with items which don't meet the filter criteria in case the criteria are too restrictive.
- The "equals" operator is `==`. A single `=` is not an operator in IQL. - In the IQL string, the spaces before and after the `AND/OR` operators are required. - When adding filters to POST requests, you must escape any `"` in the filter string in the request body, for example: ``` "additionalFilters": "brand!=\"foo\" AND brand!=\"bar baz\"", ```
When you add filters to a campaign in the Synerise Web Application, you can [use the API to fetch the campaign's settings, including filters](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#operation/GetRecommendationCampaignV2). You can use this to learn IQL by seeing how filters created with the GUI are saved into IQL strings. To see the filters, check the `slots[].filterRules` object in the response.
### Distinct filters Distinct filters regulate how many items with certain properties can be recommended at the same time. - In campaign result requests, the filters are set by the campaign and can't be changed when making the request. - In model requests, you can add a distinct filter when making the request. ## Manipulating filters in campaign results In campaign requests, you can use the `additionalFilters` and `additionalElasticFilters` parameters to modify or replace the filters from the campaign settings. When you do that, you must the use `filtersJoiner` and `elasticFiltersJoiner` parameters to set the logic of combining the filters: - `AND` means that an item must match both the filter you send and the one from the campaign. - `OR` means that an item must match the filter you send, the filter from the campaign, or both. - `REPLACE` means that an item must match the filter you send and the filter from the campaign is ignored. Distinct filters are defined in the campaign settings and can't be changed when making a request. **Examples**:
In this example, the item must meet at least both of the following: - the conditions of elastic filter from the campaign - elastic filter: price must be more than 50 Usage example: a cart recommendation which shows items with a price that will increase the cart's value to the threshold of free shipping.
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns?token=...' \
--header 'Content-Type: application/json' \
--data '{
    "clientUUID": "cf9e9b57-7776-51bc-b7bc-75cc75abdf59",
    "campaignId": "DkhvrZoTKthD",
    "additionalElasticFilters": "price.value>50",
    "elasticFiltersJoiner": "AND"
}'
In this example, the item must meet at least one of the following: - the conditions of elastic filter from the campaign - elastic filter: price must be between 50 and 100
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns?token=...' \
  --header 'Content-Type: application/json' \
  --data '{
      "clientUUID": "cf9e9b57-7776-51bc-b7bc-75cc75abdf59",
      "campaignId": "DkhvrZoTKthD",
      "additionalElasticFilters": "price.value<100 AND price.value>50",
      "elasticFiltersJoiner": "OR"
  }'
In this example, the filter from the campaign is replaced. The new filter is that the item's brand can't be "foo" or "bar baz".
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns/DkhvrZoTKthD?&additionalFilters=brand!%3D%22foob%22%20AND%20brand!%3D%22bar%20baz%22&filtersJoiner=REPLACE&token=...&clientUUID=...'
In this example, the item must meet both of the following: - the conditions of filter from the campaign - color is `red`
curl --location 'https://api.synerise.com/recommendations/v2/recommend/campaigns?token=...' \
  --header 'Content-Type: application/json' \
  --data '{
      "clientUUID": "cf9e9b57-7776-51bc-b7bc-75cc75abdf59",
      "campaignId": "DkhvrZoTKthD",
      "additionalFilters": "color==\"red\"",
      "filtersJoiner": "AND"
  }'
## Requests to a model In requests to a model, you can add the following parameters: - `filters` is an [IQL filter](/developers/iql) - `elastic:filters` is an elastic [IQL filter](/developers/iql) - `distinctFilter` is an object:
"distinctFilter": {
  "elastic": boolean, // when `true`, if there are not enough items which meet the criteria,
                      // other items can be added to meet the minimum number of items in the slot
  "filters": // an array of filters
      [
          {
              "field": "color", // attribute name
              "maxNumItems": n, // max number of items with the same attribute value
              "levelRangeModifier": n // only used when field is 'category'.
                                      // Removes the last n category levels
          }
      ]
  }
The available filter types depend on the recommendation type. For details, refer to each endpoint's [reference documentation](https://developers.synerise.com/AIRecommendations/AIRecommendations.html#tag/Recommendations).
**Example**: A request to the "Personalized" model with a filter that uses an attribute from the profile which made the request:
curl --location 'https://api.synerise.com/recommendations/v2/recommend/items/users/8ae22439-f72b-4fe7-98e5-da3217215c54?filters=colors%3D%3Dclient.attributes.favoriteColor&token=98A5FC55-0000-0000-0000-98339BDECAE6'
curl --location 'https://api.synerise.com/recommendations/v2/recommend/items/users/8ae22439-f72b-4fe7-98e5-da3217215c54?token=98A5FC55-0000-0000-0000-98339BDECAE6' \
--header 'Content-Type: application/json' \
--data '{
    "clientUuid": "8ae22439-f72b-4fe7-98e5-da3217215c54",
    "slots": [
        {
            "filters": "colors==client.attributes.favoriteColor"
        }
    ]
}'
### Mobile SDK This section explains how to implement and use Synerise SDK in your mobile applications (Android, iOS, React Native). The best way to start is to read the [Overview](/developers/mobile-sdk/overview) article. It contains all information about the possibilities Mobile SDK offers. After reading the Overview, we recommend familiarizing with the instructions and performing the actions described in them in the presented order: - [Installation and configuration](/developers/mobile-sdk/installation-and-configuration) - [Configuring push notifications](/developers/mobile-sdk/configuring-push-notifications) - [Settings](/developers/mobile-sdk/settings) - [Profile identification, authorization and management](/developers/mobile-sdk/user-identification-and-authorization) - [Event tracking](/developers/mobile-sdk/event-tracking) - [Campaigns](/developers/mobile-sdk/campaigns) - [Loyalty](/developers/mobile-sdk/loyalty) After that, you can read and configure the other modules in any order. ### Functions Functions allow you to perform some additional operations when building the IQL query string. You can use functions inside functions, for example: ``` effectivePrice.value <= MULTIPLY(MIN(context.effectivePrice.value), 1.2) ``` In the above example: 1. `(MIN(context.effectivePrice.value)` gets the lowest value of an attribute from the context items. 2. `MULTIPLY(...), 1.2` multiplies that lowest value by `1.2`. 3. The resulting filter matches items whose `effectivePrice.value` is at least 20% higher than in the cheapest context item. ## CATEGORY {#category-function} The `CATEGORY` function allows you to: - access categories from the context - access context attributes that are formatted as categories, but not named `category` (for example, a custom `favoriteCategory` attribute in a profile) - manipulate category levels The function takes two arguments: - the source of the category value - how many category levels you want to drop or include (`0` does not drop any levels). Positive numbers **drop** levels from the bottom, negative numbers **include** from the top. **Example 1**: Accessing category from the item context and dropping one level from the bottom (right): ``` category == CATEGORY(context.category, 1) ``` If the context category is `X > Y > Z` the result of the function is the following filter: ``` category == "X > Y" ``` **Example 2**: Accessing category from the item context including two levels from the top (left): ``` category == CATEGORY(context.category, -1) ``` If the context category is `X > Y > Z` the result of the function is the following filter: ``` category == "X" ``` **Example 3**: Adding an [OR statement](/developers/iql/logic#or) and the `additionalCategories` attribute, no levels dropped: ``` category == CATEGORY(context.category, 0) OR category == CATEGORY(context.additionalCategories, 0) ``` **Example 4**: Accessing a category saved as a custom profile attribute `"favoriteCategory": "foo > bar"`: ``` category == CATEGORY(client.attributes.favoriteCategory, 0) ``` The resulting filter is: ``` category == "foo > bar" ``` ## Numeric functions You can perform mathematical operations on item context and profile context attributes. ### MIN Returns the lowest value from an array. ``` attributeName >= MIN([]) ``` **Example**: In the following example, the context is a few items with a `size.width` attribute: ``` size.width >= MIN(context.size.width) ``` The resulting filter is: ``` size.width >= MIN([10.0,14.0,20.0]) ``` which calculates into: ``` size.width >= 10.0 ``` ### MAX Returns the highest value from an array. ``` attributeName >= MAX([]) ``` **Example**: In the following example, the context is a few items with a `size.width` attribute: ``` size.width >= MAX(context.size.width) ``` The resulting filter is: ``` size.width >= MAX([10.0,14.0,20.0]) ``` which calculates into: ``` size.width >= 20.0 ``` ### AVG Returns the average value of an array. ``` attributeName >= AVG([]) ``` **Example**: In the following example, the context is 3 items with a `size.width` attribute: ``` size.width >= AVG(context.size.width) ``` The resulting filter is: ``` size.width >= AVG([10.0,14.0,20.0]) ``` which calculates into: ``` size.width >= 14.666666666666666 ``` ### SUM Returns the sum of all elements in an array. All elements must be numbers. ``` attributeName == SUM([]) ``` In the following example, the context is 3 items with a `regularPrice` attribute. ``` price > SUM(context.regularPrice) ``` The resulting filter is: ``` price > SUM([10.0,15.65,14.30]) ``` which calculates into: ``` price > 39.95 ``` ### ADD Adds one value to one other value. If you want to add more values at once, use [`SUM`](#sum). The first argument is a context attribute or a number, the second attribute is a number. ``` attributeName == ADD(value,number) ``` **Example 1**: In the following example, the context is one item with `"size": 10`: ``` size > ADD(context.size,5) ``` The resulting filter is: ``` size > ADD(10.0,5.0) ``` which evaluates to: ``` size > 15 ``` ### MULTIPLY Multiplies values. The first argument is a context attribute or a number, the second attribute is a number. ``` attributeName == MULTIPLY(value,number) ``` **Example**: In the following example, the context is one item with `"price.value": 5`: ``` price.value > MULTIPLY(context.price.value,0.7) ``` The resulting filter is: ``` price.value > MULTIPLY(5.0,0.7) ``` which evaluates to: ``` price.value > 3.5 ``` ### Check if value is null The `IS DEFINED` operator allows you to check if an attribute exists and has a non-null value. For example, the following filter matches items in which the `winterPromotion` has a non-null value: ``` winterPromotion IS DEFINED ``` You can also check contexts: ``` IF(context.thisAttributeDoesNotExist IS DEFINED, discount > 0, discount == 0) ``` ## TOP/BOTTOM values The `TOP_K` and `BOTTOM_K` functions let you retrieve a number of items with the top/bottom values of an attribute. You can add a filter to the items. **Syntax**: ``` TOP_K(value, attribute, filter) BOTTOM_K(value, attribute, filter) ``` where: - `value` is the number of items to retrieve - `attribute` is the tested attribute - `filter` is a filter string **Example 1:** Retrieve 10 items with the lowest prices: ``` BOTTOM_K(10, price.value , ALL) ``` **Example 2:** Retrieve 10 red items with the highest prices: ``` TOP_K(10, price.value , color == red) ``` **Example 3:** Retrieve 10 available items with the highest [value of a metric](/developers/iql/filters#metrics): ``` TOP_K(10, extra.metrics.9 , availability == true) ``` ## Time functions These functions let you use dates and times in a filter. ### TIMESTAMP Converts a date-time string or a timestamp (string) into a timestamp (integer). **Syntax**: ``` TIMESTAMP(string) ``` where `string` can be: - an ISO 8601 date-time string, for example `2024-01-01T10:00:00Z` If the string doesn't declare a timezone, the timezone of the workspace is applied. `Z` declares UTC as the timezone. - a timestamp in seconds as a string, for example `1727337789` The result is a timestamp as an integer, in seconds. ### NOW Gets current time as a timestamp (integer) in seconds. **Syntax**: ``` NOW() ``` The function doesn't have any arguments. ### DATE_ADD Adds or subtracts from a date-time (string). **Syntax**: ``` DATE_ADD(unit, number, time) ``` where: - `unit` is one of: `minutes`, `hours`, `days`, `months`, `years` This argument is NOT case-sensitive. `months` takes into account the different number of days each month and `years` handles leap years. - `number` is the value to add. Negative values result in subtraction. - `time` is an ISO 8601 date-time string, a timestamp in seconds (as string or integer), or the `NOW()` function. If date-time doesn't declare a timezone, the timezone of the workspace is applied. `Z` declares UTC as the timezone. **Examples**: - Add 31 days to a fixed date: ``` DATE_ADD("days", 31, "2024-01-01T10:00:00Z") ``` ``` DATE_ADD("days", 31, "1704099600") ``` ``` DATE_ADD("days", 31, 1704099600) ``` - Subtract 3 months from current time: ``` DATE_ADD("MONTHS", -3, NOW()) ``` ## ALL/NONE This special function lets include or exclude all items from the results. - `ALL` - take all items - `NONE` - take no items This is especially useful in the [IF statement](/developers/iql/logic#if). ### Transactions The mobile SDK doesn't provide tracking of transactions. To do so, use the following endpoints: - [Create a transaction](https://developers.synerise.com/DataManagement/DataManagement.html#operation/CreateATransaction) - [Batch add or update transactions](https://developers.synerise.com/DataManagement/DataManagement.html#operation/BatchAddOrUpdateTransactions) ### In-app message ## Overview --- In-app message is a banner that can be displayed when your app is running. It may have various layout variants, because it is fully customizable by HTML. The campaign is triggered and displayed depending on the configuration settings. Read more about creating in-app messages [here](/docs/campaign/in-app-messages/create-inapp-message).
Due to operating system differences and web engines, in-app message appearance may differ between systems or not be as expected. You should test your in-app messages.
In in-app messages, you can use: - the **safe area** mode on iOS from the `5.1.0` version, - the **display cutouts** mode on Android from the `6.1.0` version.
## Requirements --- - Recommended Mobile SDK version: - Android - 5.3.0 or newer - iOS - 4.12.0 or newer - React Native - 0.12.0 or newer - Flutter - 0.5.0 or newer - If your in-app content (such as JavaScript, CSS, images, or fonts) is being loaded from your own server via HTTP and you have configured **CORS policies**, you need to set the **contentBaseUrl** to your server's address. For example, if you're loading resources from `https://www.synerise.com/example/font.woff`, you should configure **contentBaseUrl** to `https://www.synerise.com` (check this option in the [Settings](/developers/mobile-sdk/settings#content-base-url-for-in-app-message)). - Enable the `IN_APP_DEFINITIONS_COMMUNICATION_READ` (**Experience Hub**) permission in the Profile (formerly Client) [API key](/docs/settings/tool/api) used by the mobile application so the mobile application can fetch in-app messages.
The API key permission matrix with the in-app permission
The API key permission matrix with the in-app permission
## Good practices --- ### Campaign planning recommendations Using a large number of in-app messages in your application can impact rendering time, message delivery, and battery usage. To maintain optimal application performance when using in-app campaigns: - Avoid assigning more than 10 in-app messages to the same trigger event. - Avoid having more than 20 in-app messages active at the same time in your application. - Review and archive in-app campaigns that you no longer need. ### Template construction When creating or editing in-app message content: - Place the the `SRInApp.close()` (or `SRInApp.hide()`) method at the beginning of the JS script. - Use try/catch to handle possible fatal errors in the JS script. - Handle situations where Jinjava inserts return empty data. - When adding external links to your message: - Only link to sites you trust. - Don't link to large images that may negatively affect performance. - Don't link to resources whose CSS/HTML may be blocked. If you have resources loaded from your own URLs, set `Synerise.settings.inAppMessaging.contentBaseUrl` and use relative paths in HTML/CSS. ## Configuration --- In-app message campaigns are served by the Synerise backend. Check possible available configuration options in the [Settings](/developers/mobile-sdk/settings#in-app-messaging). ## JavaScript methods in in-app messages --- See ["Using in-app template builder" in the User Guide](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#javascript-methods-in-in-app-messages). ## Events generated by in-app messaging --- For information about events generated by in-app messaging, see the [event reference](/docs/assets/events/event-reference/inapp).
You can disable sending the `inApp.capping` event in the SDK Settings - [Enable/disable sending in-app capping event](/developers/mobile-sdk/settings#enabledisable-sending-inappcapping-event).
## Setting up a global control group for in-app message --- For information about global control groups in in-app messages, see the [global control group](/docs/settings/configuration/global-control-group) article. ## Handling actions from in-app messages --- Handling main actions from campaigns depends on the campaign type and operating system and it is described [here](/developers/mobile-sdk/campaigns/action-handling). ## Controlling behavior and actions --- You may control an incoming in-app message and decide whether to show it (the display of in-app message can be triggered by occurrence of specific events). By default, the SDK allows in-app message display. The user interface allows selecting up to 3 trigger events, however, in Android, only for `5.8.1` SDK version (released on 28.08.2023) or higher all triggers are considered altogether. For older SDK versions in Android, only the last event from the trigger list will be considered. These limitations don't apply in iOS. Also, you can be notified (in the form of events) about the campaign actions in the following cases: - When the in-app message is presented. - When the in-app message disappeared. - When additional context is needed to render the campaign. - When the customer invoked an action. You can handle the message using: - [OnInAppListener](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-in-app-listener) methods for Android. - [InjectorInAppMessageDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#injector-in-app-message-delegate) methods for iOS. - [InjectorInAppMessageListener](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#injector-in-app-message-listener) methods for React Native. - [InjectorInAppMessageListener](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#injector-in-app-message-listener) methods for Flutter. See the following code samples:
```Java public static OnInAppListener NULL = new OnInAppListener() { // This method is called after an in-app message is loaded and Synerise SDK asks for permission to show it. @Override public boolean shouldShow(InAppMessageData inAppMessageData) { return true; } // This method is called after an in-app message appears. @Override public void onShown(InAppMessageData inAppMessageData) { //... } // This method is called after an in-app message disappears. @Override public void onDismissed(InAppMessageData inAppMessageData) { //... } // This method is called when a individual context for an in-app message is needed. @Override public HashMap onContextFromAppRequired(InAppMessageData inAppMessageData) { return new HashMap<>(); } // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. @Override public void onHandledOpenUrl(InAppMessageData inAppMessageData) { //... } // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. @Override public void onHandledOpenDeepLink(InAppMessageData inAppMessageData) { //... } // This method is called when the // SRInApp.handleCustomAction(name, params) method is used in an in-app message. @Override public void onCustomAction(String identifier, HashMap params, InAppMessageData inAppMessageData) { //... } }; ```
```Kotlin var inAppCallbacks: OnInAppListener = object : OnInAppListener() { // This method is called after an in-app message is loaded and Synerise SDK asks for permission to show it. override fun shouldShow(inAppMessageData: InAppMessageData): Boolean { return true } // This method is called after an in-app message appears. override fun onShown(inAppMessageData: InAppMessageData) { //... } // This method is called after an in-app message disappears. override fun onDismissed(inAppMessageData: InAppMessageData) { //... } // This method is called when a individual context for an in-app message is needed. override fun onContextFromAppRequired(inAppMessageData: InAppMessageData): HashMap { return HashMap() } // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. override fun onHandledOpenUrl(inAppMessageData: InAppMessageData) { //... } // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. override fun onHandledOpenDeepLink(inAppMessageData: InAppMessageData) { //... } // This method is called when the // SRInApp.handleCustomAction(name, params) method is used in an in-app message. override fun onCustomAction(identifier: String?, params: HashMap?, inAppMessageData: InAppMessageData?) { //... } } ```
```Swift // MARK: - InjectorInAppMessageDelegate // This method is called after an in-app message is loaded and Synerise SDK asks for permission to show it. func snr_shouldInAppMessageAppear(data: InAppMessageData) -> Bool { return true } // This method is called after an in-app message appears. func snr_inAppMessageDidAppear(data: InAppMessageData) { //... } // This method is called after an in-app message disappears. func snr_inAppMessageDidDisappear(data: InAppMessageData) { //... } // This method is called when an in-app message changes size. func snr_inAppMessageDidChangeSize(rect: CGRect) { //... } // This method is called when a individual context for an in-app message is needed. func snr_inAppMessageContextIsNeeded(data: InAppMessageData) -> [AnyHashable: Any]? { return [] } // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. func snr_inAppMessageHandledAction(data: InAppMessageData, url: URL) { //... } // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. func snr_inAppMessageHandledAction(data: InAppMessageData, deeplink: String) { //... } // This method is called when the // SRInApp.handleCustomAction(name, params) method is used in an in-app message. func snr_inAppMessageHandledCustomAction(data: InAppMessageData, name: String, parameters: [AnyHashable: Any]) { //... } ```
```Objective-C #pragma mark - SNRInjectorInAppMessageDelegate // This method is called after an in-app message is loaded and Synerise SDK asks for permission to show it. - (BOOL)SNR_shouldInAppMessageAppear:(SNRInAppMessageData *)data { //... } // This method is called after an in-app message appears. - (void)SNR_inAppMessageDidAppear:(SNRInAppMessageData *)data { //... } // This method is called after an in-app message disappears. - (void)SNR_inAppMessageDidDisappear:(SNRInAppMessageData *)data { //... } // This method is called when an in-app message changes size. - (void)SNR_inAppMessageDidChangeSize:(CGRect)rect { //... } // This method is called when a individual context for an in-app message is needed. - (nullable NSDictionary *)SNR_inAppMessageContextIsNeeded:(SNRInAppMessageData *)data { //... } // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. - (void)SNR_inAppMessageHandledURLAction:(SNRInAppMessageData *)data url:(NSURL *)url { //... } // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. - (void)SNR_inAppMessageHandledDeeplinkAction:(SNRInAppMessageData *)data deeplink:(NSString *)deeplink { //... } // This method is called when the // SRInApp.handleCustomAction(name, params) method is used in an in-app message. - (void)SNR_inAppMessageHandledCustomAction:(SNRInAppMessageData *)data name:(NSString *)name parameters:(NSDictionary *)parameters { //... } ```
```JavaScript Synerise.onReady(function() { Synerise.Injector.setInAppMessageListener({ // This method is called after an in-app message is loaded and Synerise SDK asks for permission to show it. shouldPresent: function(data) { return true; }, // This method is called after an in-app message appears. onPresent: function(data) { //... }, // This method is called after an in-app message disappears. onHide: function(data) { //... }, // This method is called when a individual context for an in-app message is needed. contextIsNeeded: function(data) { return {} }, // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. onOpenUrl: function(data, url) { //... }, // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. onDeepLink: function(data, deepLink) { //... }, // This method is called when Synerise handles custom action from in-app messages. onCustomAction: function(data, name, parameters) { //... } }); }) ```
```Dart Synerise.injector.inAppMessageListener((listener) { // This method is called after an in-app message appears. listener.onPresent = (data) { //... }; // This method is called after an in-app message disappears. listener.onHide = (data) { //... }; // This method is called when the SRInApp.openUrl(url) method is used in an in-app message. listener.onOpenUrl = (data, url) { //... }; // This method is called when the SRInApp.openDeeplink(url) method is used in an in-app message. listener.onDeepLink = (data, deepLink) { //... }; // This method is called when Synerise handles custom action from in-app messages. listener.onCustomAction(data, name, parameters) { //... }; }); ```
## Closing a message In-app messages can be closed with a [JS method included in their content](/docs/campaign/in-app-messages/creating-inapp-templates/creating-inapp-template#close-a-message), but you can also use a mobile SDK method. This can be used to close top or bottom bar in-app from somewhere else on the screen. Using this method generates an `inApp.discard` event. See the method reference: - [Android](/developers/mobile-sdk/method-reference/android/campaigns#close-in-app-message) - [Flutter](/developers/mobile-sdk/method-reference/flutter/campaigns#close-in-app-message) - [iOS](/developers/mobile-sdk/method-reference/ios/campaigns#close-in-app-message) - [React Native](/developers/mobile-sdk/method-reference/react-native/campaigns#close-in-app-message) ## Example --- This is an in-app message campaign example with full screen presentation.
In-app message campaign example
In-app message campaign (Android)
In-app message campaign example
In-app message campaign (iOS)
### Content Widget ### ContentWidget Class responsible for creating the content widget. **Declared In:** `com.synerise.sdk.content.widgets.ContentWidget` **Declaration:**
```Java public class ContentWidget ```
```Kotlin class ContentWidget ```
**Properties:** There are no properties. **Initializers:** There is a constructor.
public ContentWidget(ContentWidgetOptions contentWidgetOptions, ContentWidgetAppearance contentWidgetAppearance)
**Methods:** Setter for widget state.
public void setOnContentWidgetListener(OnContentWidgetListener listener)
--- This method is responsible for returning widgetView.
public View getView()
--- This method reloads data.
public void load()
--- --- --- ### ContentWidgetAppearance Class responsible for configuring the content widget UI. **Declared In:** `com.synerise.sdk.content.widgets.model.ContentWidgetAppearance` **Declaration:**
```Java public class ContentWidgetAppearance ```
```Kotlin class ContentWidgetAppearance ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **layout** | [ContentWidgetBaseLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetbaselayout) | no | - | Content widget layout | | **itemLayout** | [ContentWidgetBaseItemLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetbaseitemlayout) | no | - | Single item layout | **Initializers:** There is a constructor.
public ContentWidgetAppearance(ContentWidgetBaseLayout layout, ContentWidgetBaseItemLayout itemLayout)
**Methods:** There are no methods. --- --- --- ### ContentWidgetOptions Class responsible for configuration of the content widget data. **Declared In:** `com.synerise.sdk.content.widgets.model.ContentWidgetOptions` `com.synerise.sdk.content.widgets.model.ContentWidgetRecommendationsOptions` **Declaration:**
```Java public class ContentWidgetRecommendationsOptions ```
```Kotlin class ContentWidgetRecommendationsOptions ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **activity** | Activity | no | - | Activity | | **slug** | String | no | - | Slug of the document | | **attributes** | HashMap | no | - | Attribute value | | **ContentWidgetOptionsAttributeKeyProductId** | String | no | - | Final flag to add to attributes | | **mapper** | [OnRecommendationModelMapper](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetrecommendationdatamodel) | no | - | Mapper responsible for mapping RecommendationResponse| | **recommendationEventType** | RecommendationEventType | no | - | 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.
| **Initializers:** There is a constructor.
public ContentWidgetRecommendationsOptions(@NonNull Activity activity, @NonNull String slug, OnRecommendationModelMapper mapper)
**Methods:** There are no methods. --- --- --- ### ContentWidgetBaseLayout Class responsible for widget layout configuration. **Declared In:** `com.synerise.sdk.content.widgets.layout.ContentWidgetBaseLayout` **Declaration:**
```Java public abstract class ContentWidgetBaseLayout ```
```Kotlin abstract class ContentWidgetBaseLayout ```
**Properties:** There are no properties. **Initializers:** There are no constructors. #### Inheriting classes [ContentWidgetGridLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetgridlayout) [ContentWidgetHorizontalSliderLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetsliderlayout) **Methods:** This method defines the value of the cardview size. Any unit is acceptable, but remember to use the same unit across the whole widget.
public void setCardViewSize(int width, int height)
--- This method retrieves the preferred width of a gridView.
public float getPreferredWidth()
--- Setter for preferredWidth of a gridView.
public void setPreferredWidth(float width)
--- --- --- ### ContentWidgetSliderLayout Class responsible for slider layout configuration. **Declared In:** `com.synerise.sdk.content.widgets.layout.ContentWidgetHorizontalSliderLayout` **Declaration:**
```Java public class ContentWidgetHorizontalSliderLayout extends ContentWidgetBaseLayout ```
```Kotlin class ContentWidgetHorizontalSliderLayout : ContentWidgetBaseLayout ```
**Properties:** There are no properties. **Initializers:** There is only a default constructor. **Methods:** This method defines the cardview size. Any unit is acceptable, but remember to use the same unit across the whole widget.
public void setCardViewSize(int width, int height)
--- This method retrieves the preferred width of a gridView.
public float getPreferredWidth()
--- Setter for the preferredWidth of a gridView.
public void setPreferredWidth(float width)
--- --- --- ### ContentWidgetGridLayout Class responsible for grid layout configuration. **Declared In:** `com.synerise.sdk.content.widgets.layout.ContentWidgetGridLayout` **Declaration:**
```Java public class ContentWidgetGridLayout extends ContentWidgetBaseLayout ```
```Kotlin class ContentWidgetGridLayout : ContentWidgetBaseLayout ```
**Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **itemsPerRow** | int | no | 1 | Number of items per row | | **cardViewVerticalSpacing** | int | no | 0 | Card view vertical spacing | | **includeEdgeSpacing** | Boolean | no | false | Defines if edge spacing is included | **Initializers:** Constructor with the preferred width of a grid layout.
public ContentWidgetGridLayout(float prefferedWidth)
**Methods:** This method defines the cardview size. Any unit is acceptable, but remember to use the same unit across the whole widget.
public void setCardViewSize(int width, int height)
--- This method retrieves the preferred width of a gridView.
public float getPreferredWidth()
--- Setter for the preferredWidth of a gridView.
public void setPreferredWidth(float width)
--- --- --- ### ContentWidgetBaseItemLayout Class responsible for card layout configuration. **Declared In:** `com.synerise.sdk.content.widgets.layout.ContentWidgetBaseItemLayout` **Declaration:**
```Java public abstract class ContentWidgetBaseItemLayout ```
```Kotlin class abstract ContentWidgetBaseItemLayout ```
#### Inheriting classes [ContentWidgetBasicProductItemLayout](/developers/mobile-sdk/class-reference/android/content-widget#contentwidgetbasicproductitemlayout) **Properties:** | Property | Type | Optional | Default | Description | | --- | --- | --- | --- | --- | | **cardViewCornerRadius** | float | no | 0 | Card view corner radius | | **cardViewElevation** | float | no | 0 | Card view elevation | **Initializers:** There is only a default constructor. **Methods:** There are no methods. --- --- ### ContentWidgetBasicProductItemLayout Class responsible for the configuration of item layout. **Declared In:** `com.synerise.sdk.content.widgets.layout.ContentWidgetBasicProductItemLayout` **Declaration:**
```Java public class ContentWidgetBasicProductItemLayout extends ContentWidgetBaseItemLayout ```
```Kotlin class ContentWidgetBasicProductItemLayout : ContentWidgetBaseItemLayout ```
**Properties:** | 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 | | itemTitleMaxLines | int | 1 | Maximum displayed lines of the title text | | itemSubTitleStyle | Typeface | - | Typeface of the product subtitle | | itemTitleSize | int | 12 | Size of the title | | itemSubTitleColor | int | #000 | Color of the subtitle text | | itemSubTitleMarginLeft | int | 0 | Left margin of the subtitle text | | itemSubTitleMarginRight | int | 0 | Right margin of the subtitle text | | itemSubTitleMarginBottom | int | 0 | Bottom margin of the subtitle text | | itemSubTitleMarginTop | int | 0 | Top margin of the subtitle text | | isItemSubTitleVisible | Boolean | false | Flag indicating visibility of subtitle | | itemSubTitleGravity | int | Gravity.LEFT | Flag indicating gravity of subtitle | | itemSubTitleMaxLines | int | 1 | Maximum displayed lines of the subtitle text | | itemProductIdentifier | Typeface | - | Typeface of the product identifier | | itemIdentifierSize | int | 12 | Size of the identifier | | itemIdentifierColor | int | #000 | Color of the identifier text | | itemIdentifierMarginLeft | int | 0 | Left margin of the identifier text | | itemIdentifierMarginRight | int | 0 | Right margin of the identifier text | | itemIdentifierMarginBottom | int | 0 | Bottom margin of the identifier text | | itemIdentifierMarginTop | int | 0 | Top margin of the identifier text | | isItemIdentifierVisible | Boolean | false | Flag indicating visibility of identifier | | itemIdentifierGravity | int | Gravity.LEFT | Flag indicating gravity of identifier | | itemIdentifierMaxLines | int | 1 | Maximum displayed lines of the identifier text | | itemLoyaltyPointsStyle | Typeface | - | Typeface of the loyalty points | | itemLoyaltyPointsSize | int | 12 | Size of the loyalty points | | itemLoyaltyPointsColor | int | #000 | Color of the loyalty points text | | itemLoyaltyPointsMarginLeft | int | 0 | Left margin of the loyalty points text | | itemLoyaltyPointsMarginRight | int | 0 | Right margin of the loyalty points text | | itemLoyaltyPointsMarginBottom | int | 0 | Bottom margin of the loyalty points text | | itemLoyaltyPointsMarginTop | int | 0 | Top margin of the loyalty points text | | isItemLoyaltyPointsVisible | Boolean | false | Flag indicating visibility of loyalty points | | itemLoyaltyPointsHorizontalPosition | `HorizontalPosition` | HorizontalPosition.LEFT | Flag indicating position of loyaltyPoints | | itemLoyaltyPointsLabel | String | "Loyalty points" | Label for loyalty points field | | itemLoyaltyPointsLabelStyle | Typeface | - | Typeface of the loyalty points label | | itemLoyaltyPointsLabelSize | int | 12 | Size of the loyalty points label | | itemLoyaltyPointsLabelColor | int | #000 | Color of the loyalty points label text | | itemLoyaltyPointsLabelMarginLeft | int | 0 | Left margin of the loyalty points label text | | itemLoyaltyPointsLabelMarginRight | int | 0 | Right margin of the loyalty points label text | | itemLoyaltyPointsLabelMarginBottom | int | 0 | Bottom margin of the loyalty points label text | | itemLoyaltyPointsLabelMarginTop | int | 0 | Top margin of the loyalty points label 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 | | itemPriceCurrencyHorizontalPosition | HorizontalPosition | HorizontalPosition.RIGHT | Flag indicating position of currency | | itemPriceHorizontalPosition | HorizontalPosition | 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 | **Initializers:** There are no initializers. **Methods:** Setter for margins in ItemTitle.
public void setItemTitleMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemPrice.
public void setItemPriceMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemSalePrice.
public void setItemSalePriceMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemLabel.
public void setItemLabelMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemDiscountLabel.
public void setItemDiscountLabelMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemSubtitle.
public void setItemSubTitleMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemIdentifier.
public void setItemIdentifierMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemLoyaltyPoints.
public void setItemLoyaltyPointsMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for margins in ItemLoyaltyPointsLabel.
public void setItemLoyaltyPointsLabelMargins(int marginLeft, int marginRight, int marginTop, int marginBottom)
--- Setter for itemAction.
public void setItemAction(ImageButtonCustomAction itemImageButton)
--- Setter for the badge.
public void setBadge(ContentWidgetBadge badge)
--- --- ### ContentWidgetRecommendationDataModel Model for recommendations inside a content widget **Declared In:** `com.synerise.sdk.content.widgets.dataModel.ContentWidgetRecommendationDataModel` **Declaration:**
```Java public class ContentWidgetRecommendationDataModel ```
```Kotlin class ContentWidgetRecommendationDataModel ```
**Properties:** There are no properties. **Initializers:** Constructor:
public ContentWidgetRecommendationDataModel(String name, String image, String price, String salePrice, String priceCurrency)
It's recommended to send the value of the `priceCurrency` in ISO format.
**Methods:** This method retrieves an item name.
public String getName()
--- This method retrieves the URL of the item's image.
public String getImage()
--- This method retrieves the item's price.
public String getPrice()
--- This method retrieves the item's sale price.
public String getSalePrice()
--- This method retrieves the currency of the price.
public String getPriceCurrency()
--- This method retrieves the value of the badge model parameter.
public ContentWidgetBadgeDataModel getBadgeDataModel()
--- This method retrieves the value of the label parameter.
public String getLabel()
--- This method defines the value of the badge model parameter.
public void setBadgeDataModel(ContentWidgetBadgeDataModel badge)
--- This method defines the value of the label parameter.
public void setLabel(String label)
--- --- --- ### ContentWidgetBadgeDataModel Model for badges inside content widgets. **Declared In:** `com.synerise.sdk.content.widgets.dataModel.ContentWidgetBadgeDataModel` **Declaration:**
```Java public class ContentWidgetBadgeDataModel ```
```Kotlin class ContentWidgetBadgeDataModel ```
**Properties:** There are no properties. **Initializers:** Constructor:
public ContentWidgetBadgeDataModel(String text, int color, int textColor)
**Methods:** This method retrieves the value of the badge text.
public String getText()
--- This method retrieves the badge color.
public int getColor()
--- This method retrieves the badge text color.
public int getTextColor()
--- --- --- ### ContentWidgetRecommendationDataModel Model for recommendations inside a content widget **Declared In:** `com.synerise.sdk.content.widgets.dataModel.ContentWidgetRecommendationDataModel` **Declaration:**
```Java public class ContentWidgetRecommendationDataModel ```
```Kotlin class ContentWidgetRecommendationDataModel ```
**Properties:** There are no properties. **Initializers:** Constructor:
public ContentWidgetRecommendationDataModel(String name, String image, String price, String salePrice, String priceCurrency)
It's recommended to send the value of the `priceCurrency` in ISO format.
**Methods:** This method retrieves an item name.
public String getName()
--- This method retrieves the URL of the item's image.
public String getImage()
--- This method retrieves the item's price.
public String getPrice()
--- This method retrieves the item's sale price.
public String getSalePrice()
--- This method retrieves the currency of the price.
public String getPriceCurrency()
--- This method retrieves the value of the badge model parameter.
public ContentWidgetBadgeDataModel getBadgeDataModel()
--- This method retrieves the value of the label parameter.
public String getLabel()
--- This method defines the value of the badge model parameter.
public void setBadgeDataModel(ContentWidgetBadgeDataModel badge)
--- This method defines the value of the label parameter.
public void setLabel(String label)
--- ### Content Widget ### ContentWidget Content Widget is a feature in our Software Development Kit that allows you to embed an easily customizable view with various types of content in your application. **Declared In:** Headers/SNRContentWidget.h **Related To:** [ContentWidgetOptions](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetoptions) [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) [ContentWidgetDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#content-widget-delegate) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class ContentWidget: NSObject ```
```Objective-C @interface SNRContentWidget : NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **options** | [ContentWidgetOptions](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetoptions) | no | Business configuration of the widget | | **appearance** | [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) | no | UI configuration of the widget | | **delegate** | [ContentWidgetDelegate](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#content-widget-delegate) | no | Delegate of the widget | **Initializers:**
```Swift init(options: ContentWidgetOptions, appearance: ContentWidgetAppearance) ```
```Objective-C - (instancetype)initWithOptions:(nonnull SNRContentWidgetOptions *)options andAppearance:(nonnull SNRContentWidgetAppearance *)appearance ```
**Methods:** Starts operation of fetching data and creates view structure of widget.
```Swift func load() ```
```Objective-C - (void)load ```
--- Checks whether widget is loaded with success.
```Swift func isLoaded() -> Bool ```
```Objective-C - (BOOL)isLoaded ```
--- Gets root view of whole widget view structure.
```Swift func getView() -> UIView ```
```Objective-C - (UIView *)getView ```
--- --- ### ContentWidgetAppearance The **ContentWidgetAppearance** class is responsible for defining the appearance of the widget. **Declared In:** Headers/SNRContentWidgetAppearance.h **Related To:** [SNRContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) [SNRContentWidgetLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetlayout) [SNRContentWidgetHorizontalSliderLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgethorizontalsliderlayout) [SNRContentWidgetGridLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetgridlayout) [SNRContentWidgetItemLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetitemlayout) [SNRContentWidgetBasicProductItemLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetbasicproductitemlayout) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class ContentWidgetAppearance: NSObject ```
```Objective-C @interface SNRContentWidgetAppearance : NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **layout** | [ContentWidgetLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetlayout) | no | UI configuration of the widget's layout | | **itemLayout** | [ContentWidgetItemLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetitemlayout) | no | UI configuration a single widget item | **Initializers:**
```Swift init(widgetLayout: ContentWidgetLayout, itemLayout: ContentWidgetItemLayout) ```
```Objective-C - (instancetype)initWithLayout:(nonnull SNRContentWidgetLayout *)layout andItemLayout:(nonnull SNRContentWidgetItemLayout *)itemLayout ```
--- --- ### ContentWidgetOptions **Declared In:** Headers/SNRContentWidgetOptions.h **Related To:** [SNRContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class ContentWidgetOptions: NSObject ```
```Objective-C @interface SNRContentWidgetOptions : NSObject ```
--- --- ### ContentWidgetRecommendationsOptions The **ContentWidgetRecommendationsOptions** class is responsible for defining the business logic options of the widget. **Declared In:** Headers/SNRContentWidgetOptions.h **Related To:** [SNRContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class ContentWidgetRecommendationsOptions: NSObject ```
```Objective-C @interface SNRContentWidgetRecommendationsOptions : NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **slug** | String | no | Slug of a document | | **productID** | String | yes | Product identifier for generating data | | **mapping** | ((ContentWidgetRecommendationModel) -> (ContentWidgetRecommendationDataModel)) | no | Mapping block responsible for mapping data from the feed to a ContentWidgetRecommendationDataModel | | **recommendationEventType** | ContentWidgetRecommendationEventType | - | Recommendation event type.
  • **.view** sends all products in one event. We highly recommend using this type of event in content widget.
  • **.seen** sends each event as a separate event.
| **Initializers:**
```Swift init() ```
```Objective-C - (instancetype)init ```
--- --- ### ContentWidgetLayout Main widget layout abstract class for inheriting classes. **Declared In:** Headers/SNRContentWidgetLayout.h **Related To:** [SNRContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class ContentWidgetLayout: NSObject ```
```Objective-C @interface SNRContentWidgetLayout : NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **backgroundColor** | UIColor | yes | Background color of a widget | | **insets** | UIEdgeInsets | yes | Inner widget margins in pt | | **itemSize** | Size | yes | Size of a single item in pt | | **numberOfItems** | Int | yes | It returns the number of items after the widget is loaded |
**numberOfItems** property is read-only.
--- --- ### ContentWidgetHorizontalSliderLayout This layout is intended to present recommendations in a fixed-hight horizontal scrollable slider. **Declared In:** Headers/SNRContentWidgetHorizontalSliderLayout.h **Related To:** [SNRContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) **Inherits From:** [ContentWidgetLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetlayout) **Declaration:**
```Swift class ContentWidgetHorizontalSliderLayout: ContentWidgetLayout ```
```Objective-C @interface SNRContentWidgetHorizontalSliderLayout : SNRContentWidgetLayout ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **itemSpacing** | Float | yes | Horizontal spacing between items in pt | --- --- ### ContentWidgetGridLayout 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. **Declared In:** Headers/SNRContentWidgetGridLayout.h **Related To:** [SNRContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) **Inherits From:** [ContentWidgetLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetlayout) **Declaration:**
```Swift class ContentWidgetGridLayout: ContentWidgetLayout ```
```Objective-C @interface SNRContentWidgetGridLayout : SNRContentWidgetLayout ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **itemHorizontalSpacing** | Float | yes | Horizontal spacing between items in pt | | **itemVerticalSpacing** | Float | yes | Vertical spacing between items in pt | --- --- ### ContentWidgetItemLayout Main widget layout item abstract class for inheriting classes. **Declared In:** Headers/SNRContentWidgetItemLayout.h **Related To:** [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class ContentWidgetItemLayout: NSObject ```
```Objective-C @interface SNRContentWidgetItemLayout : NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **backgroundColor** | UIColor | no | Background color of an item | | **cornerRadius** | Float | no | Radius of the item corners | | **borderWidth** | Float | no | Width of the item’s border | | **borderColor** | UIColor | no | Color of the item’s border | | **shadowColor** | UIColor | no | Color of the item’s shadow | --- --- ### ContentWidgetBasicProductItemLayout This is the basic layout for items. It contains: the image, the title, and the price from the uploaded data. **Declared In:** Headers/SNRContentWidgetBasicProductItemLayout.h **Related To:** [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) **Inherits From:** [ContentWidgetItemLayout](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetitemlayout) **Declaration:**
```Swift class ContentWidgetBasicProductItemLayout: ContentWidgetItemLayout ```
```Objective-C @interface SNRContentWidgetBasicProductItemLayout : SNRContentWidgetItemLayout ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **imageWidthRatio** | Float | no | Image width. A ratio of 1.0 means that the image width equals to 100% of the entire height of the item | | **imageHeightRatio** | Float | no | Image height. A ratio of 0.3 means that image height equals to 30% of the entire height of the item | | **imageBackground** | UIColor | no | Background color of the image | | **titleInsets** | UIEdgeInsets | no | Inner margins of the title label | | **titleFont** | UIFont | no | Font of the item title label | | **titleFontColor** | UIColor | no | Color of the title label | | **titleAlignment** | NSTextAlignment | no | Alignment of the title label | | **priceInsets** | UIEdgeInsets | no | Inner margins of the price label | | **priceFont** | UIFont | no | Font of the price label | | **priceFontColor** | UIColor | no | Color of the price label | | **priceAlignment** | NSTextAlignment | no | Alignment of the price label | | **priceGroupSeparator** | String | no | Separator of price group | | **priceDecimalSeparator** | String | no | Separator of price decimal | | **isSalePriceVisible** | Bool | no | Flag determining whether to show the sale price label or not | | **salePriceOrientation** | UILayoutConstraintAxis | no | Orientation of the sale price label | | **salePriceMargin** | Float | no | Margin between the price label and the sale price label | | **regularPriceFont** | UIFont | no | Font of the regular price label | | **regularPriceFontColor** | UIColor | no | Color of the regular price label | | **salePriceFont** | UIFont | no | Font of the sale price label | | **salePriceFontColor** | UIColor | no | Color of the sale price label | | **actionButton** | ContentWidgetImageButtonCustomAction | no | Optional button for your own custom action | | **actionButtonPosition** | CGPoint | no | Position of the action button | --- --- ### ContentWidgetBaseCustomAction Main widget custom action abstract class for inheriting classes. **Declared In:** Headers/SNRContentWidgetItemLayout.h **Related To:** [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) **Inherits From:** [NSObject](https://developer.apple.com/documentation/objectivec/nsobject) **Declaration:**
```Swift class ContentWidgetBaseCustomAction: NSObject ```
```Objective-C @interface SNRContentWidgetBaseCustomAction : NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **predefinedActionType** | ContentWidgetBaseCustomActionPredefiniedActionType | no | It determines which event is on click | --- --- ### ContentWidgetImageButtonCustomAction **ContentWidgetImageButtonCustomAction** is used to add an image button to your widget (only if the item layout allows). You can add a button with a single state or make it selectable. **Declared In:** Headers/SNRContentWidgetImageButtonCustomAction.h **Related To:** [ContentWidget](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidget) [ContentWidgetAppearance](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetappearance) **Inherits From:** [ContentWidgetBaseCustomAction](/developers/mobile-sdk/class-reference/ios/content-widget#contentwidgetbasecustomaction) **Declaration:**
```Swift class ContentWidgetImageButtonCustomAction: NSObject ```
```Objective-C @interface SNRContentWidgetImageButtonCustomAction : NSObject ```
**Properties:** | Property | Type | Optional | Description | | --- | --- | --- | --- | | **size** | Size | yes | Button size | | **backgroundColor** | UIColor | yes | Background color of the button | | **tintColor** | UIColor | yes | Fill color of the button’s image, if an asset supports it | | **image** | UIImage | yes | Button image | | **isSelectable** | Bool | yes | Flag determining whether the button is selectable | | **selectedImage** | UIImage | yes | Image of the button when the button is selected | | **isSelected** | ContentWidgetImageButtonCustomActionIsSelectedBlock | yes | Block/closure to be executed when the widget needs to determine the state of a button in the cell | | **onReceiveClick** | ContentWidgetImageButtonCustomActionReceiveClickBlock | yes | Block/closure to be executed when the button is clicked | --- --- ### ContentWidgetBaseCustomActionPredefiniedActionType **Declared In:** Headers/SNRContentWidgetBaseCustomAction.h **Declaration:**
```Swift enum ContentWidgetBaseCustomActionPredefiniedActionType: Int { none, sendLikeEvent } ```
```Objective-C typedef NS_ENUM(NSUInteger, SNRContentWidgetBaseCustomActionPredefiniedActionType) { SNRContentWidgetBaseCustomActionPredefiniedActionTypeNone = 0, SNRContentWidgetBaseCustomActionPredefiniedActionTypeSendLikeEvent } ```
### Loyalty Loyalty in mobile SDK covers two features: - [Promotions](/developers/mobile-sdk/loyalty#promotions) - In Synerise, Promotions lets you: - introduce a system of awarding and spending loyalty points so your profiles can use them and purchase your products. - use promotions as a distribution channel for discounted products.
Read more about [implementing promotions in your store](/docs/ai-hub/promotions/introduction-to-promotions).
- [Vouchers](/developers/mobile-sdk/loyalty#vouchers) - In Synerise, you can create a pool of discount codes which you can distribute through the mobile application.
Read more about [voucher pools](/docs/assets/code-pools).
## Promotions --- ### Overview {id=promotions-overview} Promotions let you fetch special offers for your profiles.
Documentation on how to prepare promotions is available [here](/docs/ai-hub/promotions/creating-promotions).
**Class reference** for promotions: [Android](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotions), [iOS](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotions), [React Native](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotions), [Flutter](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotions). **Method reference** for promotions: [Android](/developers/mobile-sdk/method-reference/android/promotions), [iOS](/developers/mobile-sdk/method-reference/ios/promotions), [React Native](/developers/mobile-sdk/method-reference/react-native/promotions), [Flutter](/developers/mobile-sdk/method-reference/flutter/promotions). ### Basic implementation {id=promotions-basic-implementation} The example below is the basic implementation and retrieves all promotions for a profile, without any parameters to filter them.
```java IDataApiCall apiCall = Promotions.getPromotions(); apiCall.execute(onSuccess, showAlertError); ```
```kotlin val apiCall = Promotions.getPromotions() apiCall.execute(onSuccess, showAlertError) ```
```swift Promotions.getPromotions(success: { (promotionResponse) in //success }) { (error) in //failure } ```
```objective-c [SNRPromotions getPromotionsWithSuccess:^(SNRPromotionResponse *promotionResponse) { //success } failure:^(NSError *error) { //failure }]; ```
```javascript Synerise.Promotions.getAllPromotions( function(promotionResponse) { //success }, function(error) { //failure } ) ```
```dart PromotionResponse promotionResponse = await Synerise.promotions.getAllPromotions().catchError((error) { //failure }); ```
### Advanced implementation {id=promotions-advanced-implementation} If you want to have full possibilities of configuring the query for promotions, getting items using the `PromotionsApiQuery` is the best way to achieve it. The table explains the filtering options available when fetching promotions.
| Property | Type | Default | Description | | --- | --- | --- | --- | | statuses | [`List`](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotionstatus) | [] | List of statuses for query | | types | [`List`](/developers/mobile-sdk/class-reference/android/promotions-and-vouchers#promotiontype) | [] | List of types for query | | sortParameters | `LinkedHashMap` | [] | Specifies [sorting rules](#promotion-sorting-options) for items in the response | | limit | `Int` | 100 | Limit of items per page in the response | | page | `Int` | 1 | Page number | | includeMeta | `Boolean` | false | Specifies if metadata should be included in the response |
| Property | Type | Default | Description | | --- | --- | --- | --- | | statuses | [`[PromotionStatus]`](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotionstatus) | [] | List of statuses for query | | types | [`[PromotionType]`](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotiontype) | [] | List of types for query | | sorting | `[[SNRPromotionSortingKey: SNRApiQuerySortingOrderString]]` | [] | Specifies [sorting rules](#promotion-sorting-options) for items in the response | | limit | `Int` | 100 | Limit of items per page in the response | | page | `Int` | 1 | Page number | | includeMeta | `Bool` | false | Specifies if meta data should be included in the response |
| Property | Type | Default | Description | | --- | --- | --- | --- | | statuses | [`Array`](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionstatus) | [] | List of statuses for query | | types | [`Array`](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotiontype) | [] | List of types for query | | sorting | `Array` | [] | Specifies [sorting rules](#promotion-sorting-options) for items in the response | | limit | `number` | 100 | Limit of items per page in the response | | page | `number` | 1 | Page number | | includeMeta | `boolean` | false | Specifies if meta data should be included in the response |
| Property | Type | Default | Description | | --- | --- | --- | --- | | statuses | [`List`](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionstatus) | [] | List of statuses for query | | types | [`List`](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotiontype) | [] | List of types for query | | sorting | `List` | [] | Specifies [sorting rules](#promotion-sorting-options) for items in the response | | limit | `int` | 100 | Limit of items per page in the response | | page | `int` | 1 | Page number | | includeMeta | `bool` | false | Specifies if meta data should be included in the response |
The example below is the advanced implementation and fetches promotions using `PromotionsApiQuery` object.
```java List statuses = new ArrayList<>(); if (activeBox.isChecked()) statuses.add(PromotionStatus.ACTIVE); if (assignedBox.isChecked()) statuses.add(PromotionStatus.ASSIGNED); if (redeemedBox.isChecked()) statuses.add(PromotionStatus.REDEEMED); List types = new ArrayList<>(); if (generalBox.isChecked()) types.add(PromotionType.GENERAL); if (customBox.isChecked()) types.add(PromotionType.CUSTOM); if (membersOnlyBox.isChecked()) types.add(PromotionType.MEMBERS_ONLY); PromotionsApiQuery query = new PromotionsApiQuery(); query.limit = 100; query.statuses = statuses; query.types = types; query.page = page; query.includeMeta = includeButton.isChecked(); LinkedHashMap sortParams = new LinkedHashMap<>(); sortParams.put(PromotionSortingKey.TYPE, ApiQuerySortingOrder.ASCENDING); sortParams.put(PromotionSortingKey.CREATED_AT, ApiQuerySortingOrder.ASCENDING); sortParams.put(PromotionSortingKey.EXPIRE_AT, ApiQuerySortingOrder.DESCENDING); query.setSortParameters(sortParams); IDataApiCall apiCall = Promotions.getPromotions(query); apiCall.execute(onSuccess, new DataActionListener() { @Override public void onDataAction(ApiError apiError) { // error handling } }); ```
```kotlin val statuses = ArrayList() if (activeBox.isChecked()) statuses.add(PromotionStatus.ACTIVE) if (assignedBox.isChecked()) statuses.add(PromotionStatus.ASSIGNED) if (redeemedBox.isChecked()) statuses.add(PromotionStatus.REDEEMED) val types = ArrayList() if (generalBox.isChecked()) types.add(PromotionType.GENERAL) if (customBox.isChecked()) types.add(PromotionType.CUSTOM) if (membersOnlyBox.isChecked()) types.add(PromotionType.MEMBERS_ONLY) val query = PromotionsApiQuery() query.limit = 100 query.statuses = statuses query.types = types query.page = page query.includeMeta = includeButton.isChecked() val sortParams = LinkedHashMap() sortParams.put(PromotionSortingKey.TYPE, ApiQuerySortingOrder.ASCENDING) sortParams.put(PromotionSortingKey.CREATED_AT, ApiQuerySortingOrder.ASCENDING) sortParams.put(PromotionSortingKey.EXPIRE_AT, ApiQuerySortingOrder.DESCENDING) query.setSortParameters(sortParams) val apiCall = Promotions.getPromotions(query) apiCall.execute(onSuccess, object:DataActionListener() { fun onDataAction(apiError:ApiError) { // error handling } }) ```
```swift let apiQuery = PromotionsApiQuery() apiQuery.types = [SNR_PROMOTION_TYPE_GENERAL] apiQuery.statuses = [SNR_PROMOTION_STATUS_ACTIVE, SNR_PROMOTION_STATUS_ASSIGNED] apiQuery.types = [SNR_PROMOTION_TYPE_GENERAL] apiQuery.sorting = [ [SNR_PROMOTION_SORTING_KEY_PRIORITY: SNR_API_QUERY_SORTING_ASC] ] apiQuery.limit = 50 apiQuery.page = 1 apiQuery.includeMeta = true Promotions.getPromotions(apiQuery: apiQuery, success: { (promotionResponse) in //success }, failure: { (error) in //failure }) ```
```objective-c SNRPromotionsApiQuery *apiQuery = [SNRPromotionsApiQuery new]; apiQuery.types = @[SNR_PROMOTION_TYPE_GENERAL]; apiQuery.statuses = @[SNR_PROMOTION_STATUS_ACTIVE, SNR_PROMOTION_STATUS_ASSIGNED]; apiQuery.types = @[SNR_PROMOTION_TYPE_GENERAL]; apiQuery.sorting = @[ @{ SNR_PROMOTION_SORTING_KEY_PRIORITY: SNR_API_QUERY_SORTING_ASC } ]; apiQuery.limit = 50; apiQuery.page = 1; apiQuery.includeMeta = YES; [SNRPromotions getPromotionsWithApiQuery:apiQuery success:^(SNRPromotionResponse *promotionResponse) { //success } failure:^(NSError *error) { //failure }]; ```
```javascript let apiQuery = new PromotionsApiQuery() apiQuery.statuses = [ PromotionStatus.Active ]; apiQuery.types = [ PromotionType.General ] apiQuery.sorting = [{ property: PromotionSortingKey.CreatedAt, order: ApiQuerySortingOrder.Ascending }] apiQuery.limit = 120 apiQuery.page = 2 apiQuery.includeMeta = true Synerise.Promotions.getPromotions(apiQuery, function(promotionResponse) { //success }, function(error) { //failure } ) ```
```dart List promotionsStatusList = [PromotionStatus.active]; List promotionTypeList = [PromotionType.general]; List apiQuerySortingList = [ApiQuerySorting(property: "", order: ApiQuerySortingOrder.ascending)]; PromotionsApiQuery promotionsApiQuery = PromotionsApiQuery( statuses: promotionsStatusList, types: promotionTypeList, sorting: apiQuerySortingList, limit: 10, page: 10, includeMeta: true ); PromotionResponse promotionResponse = await Synerise.promotions.getPromotions(promotionsApiQuery).catchError((error) { //failure }); ```
### Promotion type The promotion type options correspond to the [promotion type options available in the Synerise application](/docs/ai-hub/promotions/creating-promotions-for-entire-basket#type--limits) in the creating promotion form. - **GENERAL** - promotions are available to all profiles. - **MEMBERS_ONLY** - promotions are available to profiles who joined a loyalty program. - **HANDBILL** - promotions which can only be selected by the [AI promotion engine for a customer](/docs/ai-hub/personalized-promotions). - **CUSTOM** - custom promotions are a category that has custom configuration, tailored for chosen profiles. Constants in the SDK correlated with promotion types: | Android | iOS | React Native | Flutter | | --- | --- | --- | --- | | `PromotionType.GENERAL` | `SNR_PROMOTION_TYPE_GENERAL` | `PromotionType.General` | `PromotionType.general` | | `PromotionType.MEMBERS_ONLY` | `SNR_PROMOTION_TYPE_MEMBERS_ONLY` | `PromotionType.MembersOnly` | `PromotionType.membersOnly` | | `PromotionType.CUSTOM` | `SNR_PROMOTION_TYPE_CUSTOM` | `PromotionType.Custom` | `PromotionType.custom` | | `PromotionType.HANDBILL` | `SNR_PROMOTION_TYPE_HANDBILL` | `PromotionType.Handbill` | `PromotionType.handbill` | ### Promotion status - **ACTIVE** - promotion is activated by the profile. - **ASSIGNED** - promotion is assigned to a profile and visible to them. - **REDEEMED** - promotion is redeemed and finished for the profile. Constants in the SDK correlated with promotion statuses: | Android | iOS | React Native | Flutter | | --- | --- | --- | --- | | `PromotionStatus.ACTIVE` | `SNR_PROMOTION_STATUS_ACTIVE` | `PromotionStatus.Active` | `PromotionStatus.active` | | `PromotionStatus.ASSIGNED` | `SNR_PROMOTION_STATUS_ASSIGNED` | `PromotionStatus.Assigned` | `PromotionStatus.assigned` | | `PromotionStatus.REDEEMED` | `SNR_PROMOTION_STATUS_REDEEMED` | `PromotionStatus.Redeemed` | `PromotionStatus.redeemed` | ### Promotion sorting options You can set an array of sorting options. Each sorting option is a key-value pair. The key is the sorting key constant and the value is the sorting order. Promotion-related sorting constants: - **EXPIRE_AT** - time when the promotion expires. - **CREATED_AT** - time when the promotion was created. - **LASTING_AT** - time when the promotion stops being active for the profile. - **REQUIRE_REDEEMED_POINTS** - how many loyalty points are needed to redeem the promotion. - **UPDATED_AT** - time when the promotion was last updated. - **TYPE** - type of the promotion. - **PRIORITY** - priority of the promotion. Constants in the SDK correlated with promotion sorting options: | Android | iOS | React Native | Flutter | | --- | --- | --- | --- | | `PromotionSortingKey.EXPIRE_AT` | `SNR_PROMOTION_SORTING_KEY_EXPIRE_AT` | `PromotionSortingKey.ExpireAt` | `PromotionSortingKey.expireAt` | | `PromotionSortingKey.CREATED_AT` | `SNR_PROMOTION_SORTING_KEY_CREATED_AT` | `PromotionSortingKey.CreatedAt` | `PromotionSortingKey.createdAt` | | `PromotionSortingKey.LASTING_AT` | `SNR_PROMOTION_SORTING_KEY_LASTING_AT` | `PromotionSortingKey.LastingAt` | `PromotionSortingKey.lastingAt` | | `PromotionSortingKey.REQUIRE_REDEEMED_POINTS` | `SNR_PROMOTION_SORTING_KEY_REQUIRE_REDEEMED_POINTS` | `PromotionSortingKey.requireRedeemPoints` | `PromotionSortingKey.ExpireAt` | | `PromotionSortingKey.UPDATED_AT` | `SNR_PROMOTION_SORTING_KEY_UPDATED_AT` | `PromotionSortingKey.UpdatedAt` | `PromotionSortingKey.updatedAt` | | `PromotionSortingKey.TYPE` | `SNR_PROMOTION_SORTING_KEY_TYPE` | `PromotionSortingKey.Type` | `PromotionSortingKey.type` | | `PromotionSortingKey.PRIORITY` | `SNR_PROMOTION_SORTING_KEY_PRIORITY` | `PromotionSortingKey.Priority` | `PromotionSortingKey.priority` | You can sort each of the above ascending or descending by using the values: - **ASCENDING** - **DESCENDING** Constants in the SDK correlated with sorting order values: | Android | iOS | React Native | Flutter | | --- | --- | --- | --- | | `ApiQuerySortingOrder.ASCENDING` | `SNR_API_QUERY_SORTING_ASC` | `ApiQuerySortingOrder.Ascending` | `ApiQuerySortingOrder.ascending` | | `ApiQuerySortingOrder.DESCENDING` | `SNR_API_QUERY_SORTING_DESC` | `ApiQuerySortingOrder.Descending` | `ApiQuerySortingOrder.descending` | You can add a number of key-value pairs for sorting. ### Working with single promotions --- In addition to getting all promotions or a filtered list, you can get a single promotion. You can get a single promotion by: - UUID of the promotion - Code of the promotion These are the basic identity properties for a promotion. They are useful and thanks to them, you can **activate** and **deactivate** a single promotion too. The following methods are available: | Android | iOS | React Native | | --- | --- | --- | | [Get promotion identified by UUID](/developers/mobile-sdk/method-reference/android/promotions#get-promotion-by-uuid) | [Get promotion identified by UUID](/developers/mobile-sdk/method-reference/ios/promotions#get-promotion-by-uuid) | [Get promotion identified by UUID](/developers/mobile-sdk/method-reference/react-native/promotions#get-promotion-by-uuid) | | [Get promotion identified by code](/developers/mobile-sdk/method-reference/android/promotions#get-promotion-by-code) | [Get promotion identified by code](/developers/mobile-sdk/method-reference/ios/promotions#get-promotion-by-code) | [Get promotion identified by code](/developers/mobile-sdk/method-reference/react-native/promotions#get-promotion-by-code) | | [Activate promotion identified by UUID](/developers/mobile-sdk/method-reference/android/promotions#activate-promotion-by-uuid) | [Activates promotion identified by UUID](/developers/mobile-sdk/method-reference/ios/promotions#activate-promotion-by-uuid) | [Activates promotion identified by UUID](/developers/mobile-sdk/method-reference/react-native/promotions#activate-promotion-by-uuid) | | [Activate promotion identified by code](/developers/mobile-sdk/method-reference/android/promotions#activate-promotion-by-code) | [Activate promotion identified by code](/developers/mobile-sdk/method-reference/ios/promotions#activate-promotion-by-code) | [Activate promotion identified by code](/developers/mobile-sdk/method-reference/react-native/promotions#activate-promotion-by-code) | | [Activate promotions](/developers/mobile-sdk/method-reference/android/promotions#activate-promotions-in-a-batch) | [Activate promotions](/developers/mobile-sdk/method-reference/ios/promotions#activate-promotions-in-a-batch) | [Activate promotions](/developers/mobile-sdk/method-reference/react-native/promotions#activate-promotions-in-a-batch) | | [De-activate promotion identified by UUID](/developers/mobile-sdk/method-reference/android/promotions#deactivate-promotion-by-uuid) | [De-activate promotion identified by UUID](/developers/mobile-sdk/method-reference/ios/promotions#deactivate-promotion-by-uuid) | [De-activate promotion identified by UUID](/developers/mobile-sdk/method-reference/react-native/promotions#deactivate-promotion-by-uuid) | | [De-activate promotion identified by code](/developers/mobile-sdk/method-reference/android/promotions#deactivate-promotion-by-code) | [De-activate promotion identified by code](/developers/mobile-sdk/method-reference/ios/promotions#deactivate-promotion-by-code) |[De-activate promotion identified by code](/developers/mobile-sdk/method-reference/react-native/promotions#deactivate-promotion-by-code) | | [De-activate promotions](/developers/mobile-sdk/method-reference/android/promotions#deactivate-promotions-in-a-batch) | [De-activate promotions](/developers/mobile-sdk/method-reference/ios/promotions#deactivate-promotions-in-a-batch) | [De-activate promotions](/developers/mobile-sdk/method-reference/react-native/promotions#deactivate-promotions-in-a-batch) | ## Vouchers --- ### Overview {id=vouchers-overview} In Synerise, you can create a voucher pool to distribute discount codes to your profiles for the campaign purposes. The codes in a voucher pool get two forms: - a text string - a barcode
Before using it in your mobile app, [create a voucher pool in Synerise](/docs/assets/code-pools).
**Class reference** for vouchers: [Android](/developers/mobile-sdk/class-reference/android/modules#promotions), [iOS](/developers/mobile-sdk/class-reference/ios/modules#promotions), [React Native](/developers/mobile-sdk/class-reference/ios/modules#promotions), [Flutter](/developers/mobile-sdk/class-reference/flutter/modules#promotions). **Method reference** for vouchers: [Android](/developers/mobile-sdk/method-reference/android/promotions#vouchers), [iOS](/developers/mobile-sdk/method-reference/ios/promotions#vouchers), [React Native](/developers/mobile-sdk/method-reference/react-native/promotions#vouchers), [Flutter](/developers/mobile-sdk/method-reference/flutter/promotions#vouchers). ### Voucher status - **UNASSIGNED** - voucher is unassigned to any profile. - **ASSIGNED** - voucher is assigned to a profile and visible to them. - **REDEEMED** - voucher is redeemed and finished for the profile. - **CANCELED** - voucher is canceled for the profile. ### Working with vouchers The following methods are available: | Android | iOS | React Native | | --- | --- | --- | | [Get voucher code only once or assign a voucher with provided pool UUID for the profile](/developers/mobile-sdk/method-reference/android/promotions#get-or-assign-voucher-from-pool)| [Get voucher code only once or assign a voucher with provided pool UUID for the profile](/developers/mobile-sdk/method-reference/ios/promotions#get-or-assign-voucher-from-pool) |[Get voucher code only once or assign a voucher with provided pool UUID for the client](/developers/mobile-sdk/method-reference/react-native/promotions#get-or-assign-voucher-from-pool) | | [Assign voucher with provided pool UUID for the profile](/developers/mobile-sdk/method-reference/android/promotions#assign-voucher-code-from-pool) | [Assign voucher with provided pool UUID for the profile](/developers/mobile-sdk/method-reference/ios/promotions#assign-voucher-code-from-pool) | [Assign voucher with provided pool UUID for the profile](/developers/mobile-sdk/method-reference/react-native/promotions#assign-voucher-code-from-pool) | | [Get profile's voucher codes](/developers/mobile-sdk/method-reference/android/promotions#get-voucher-codes-assigned-to-customer) | [Get profile's voucher codes](/developers/mobile-sdk/method-reference/ios/promotions#get-voucher-codes-assigned-to-customer) | [Get profile's voucher codes](/developers/mobile-sdk/method-reference/react-native/promotions#get-voucher-codes-assigned-to-customer) | ### Promotions and Vouchers --- ## Promotions --- ### Get all promotions of a customer --- This method retrieves all available promotions that are defined for a customer.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public getAllPromotions(onSuccess: (promotionResponse: PromotionResponse) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.getAllPromotions(function(promotionResponse) { //success }, function(error) { //failure }); ```
### Get promotions with query parameters --- This method retrieves promotions that match the parameters defined in an API query.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Related To:** [PromotionsApiQuery](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionsapiquery) **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public getPromotions(apiQuery: PromotionsApiQuery, onSuccess: (promotionResponse: PromotionResponse) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiQuery** | [PromotionsApiQuery](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionsapiquery) | yes | - | [PromotionsApiQuery](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionsapiquery) object responsible for storing all query parameters | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript let apiQuery = new PromotionsApiQuery(); apiQuery.statuses = [ PromotionStatus.Active ]; apiQuery.types = [ PromotionType.General ] apiQuery.sorting = [ { property: PromotionSortingKey.CreatedAt, order: ApiQuerySortingOrder.Ascending } ]; apiQuery.limit = 120; apiQuery.page = 2; apiQuery.includeMeta = true; Synerise.Promotions.getPromotions(apiQuery, function(promotionResponse) { //success }, function(error) { //failure }); ```
### Get promotion by UUID --- This method retrieves the promotion with the specified UUID.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public getPromotionByUUID(uuid: string, onSuccess: (promotion: Promotion) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | string | yes | - | UUID of the promotion | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.getPromotionByUUID("UUID", function(promotion) { //success }, function(error) { //failure }); ```
### Get promotion by code --- This method retrieves the promotion with the specified code.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public getPromotionByCode(code: string, onSuccess: (promotion: Promotion) => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | string | yes | - | Code of the promotion | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.getPromotionByCode("CODE", function(promotion) { //success }, function(error) { //failure }); ```
### Activate promotion by UUID --- This method activates the promotion with the specified UUID.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public deactivatePromotionByUUID(uuid: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | string | yes | - | UUID of the promotion | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.activatePromotionByUUID("UUID", function() { //success }, function(error) { //failure }); ```
### Activate promotion by code --- This method activates the promotion with the specified code.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public activatePromotionByCode(code: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | string | yes | - | Code of the promotion | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.activatePromotionByCode("CODE", function() { //success }, function(error) { //failure }); ```
### Activate promotions in a batch --- This method activates promotions with a code or with UUID in a batch.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Related To:** [PromotionIdentifier](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionidentifier) **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public activatePromotionsBatch(promotionsIdentifiers: Array<PromotionIdentifier>, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **promotionsIdentifiers** | Array<[PromotionIdentifier](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionidentifier)> | yes | - | List of promotion identifiers | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.activatePromotionsBatch(promotionsIdentifiers, function() { //success }, function(error) { //failure }); ```
### Deactivate promotion by UUID --- This method deactivates the promotion with the specified UUID.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public deactivatePromotionByUUID(uuid: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | string | yes | - | UUID of the promotion | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.deactivatePromotionByUUID("UUID", function() { //success }, function(error) { //failure }); ```
### Deactivate promotion by code --- This method deactivates the promotion with the specified code.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public deactivatePromotionByCode(code: string, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | string | yes | - | Code of the promotion | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.deactivatePromotionByCode("CODE", function() { //success }, function(error) { //failure }); ```
### Deactivate promotions in a batch --- This method deactivates promotions with a code or with UUID in a batch.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Related To:** [PromotionIdentifier](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionidentifier) **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
public deactivatePromotionsBatch(promotionsIdentifiers: Array<PromotionIdentifier>, onSuccess: () => void, onError: (error: Error) => void)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **promotionsIdentifiers** | Array<[PromotionIdentifier](/developers/mobile-sdk/class-reference/react-native/promotions-and-vouchers#promotionidentifier)> | yes | - | List of promotion identifiers | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.deactivatePromotionsBatch(promotionsIdentifiers, function() { //success }, function(error) { //failure }); ```
## Vouchers --- ### Get or assign voucher from pool --- This method retrieves an assigned voucher code or assigns a voucher from a pool identified by UUID to the customer. Once a voucher is assigned using this method, **the same** voucher is returned for the profile every time the method is called. When the voucher is assigned for the first time, a [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
The API key must have the `VOUCHERS_ITEM_ASSIGN_CREATE` and `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUuid** | string | yes | - | Unique identifier of a code pool | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.getOrAssignVoucher(poolUuid, function(voucherResponse) { // success }, function(error) { // failure }) ```
### Assign voucher code from pool --- This method assigns a voucher from a pool identified by UUID to the profile. Every request returns a **different code** until the pool is empty. A [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
Returns the HTTP 416 status code when the pool is empty.
The API key must have the `VOUCHERS_ITEM_ASSIGN_CREATE` and `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUuid** | string | yes | - | Unique identifier of a code pool | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.assignVoucherCode(poolUuid, function(voucherResponse) { // success }, function(error) { // failure }) ```
### Get voucher codes assigned to customer --- This method retrieves voucher codes for a customer.
The API key must have the `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** lib/main/modules/PromotionsModule.js **Class:** [PromotionsModule](/developers/mobile-sdk/class-reference/react-native/modules#promotions) **Declaration:**
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function | no | - | Function to be executed when the operation is completed successfully | | **onError** | Function | no | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```JavaScript Synerise.Promotions.getAssignedVoucherCodes(function(voucherCodesResponse) { // success }, function(error) { // failure }) ```
### Campaigns ## Set In-App listener --- Sets inAppListener to injector. **Method name:** Injector.setOnInAppListener(OnInAppListener listener) **Declaration:**
```java public static void setOnInAppListener(OnInAppListener listener) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **listener** | OnInAppListener | yes | - | Listener | **Return Value:** No value returned. **Example:**
```java Injector.setOnInAppListener(listener); ```
```kotlin Injector.setOnInAppListener(listener) ```
## Remove In-App listener --- Removes inAppListener from injector. **Method name:** Injector.removeInAppListener() **Declaration:**
```java public static void removeInAppListener() ```
**Parameters:** No parameters. **Return Value:** No value returned. **Example:**
```java Injector.removeInAppListener(); ```
```kotlin Injector.removeInAppListener() ```
## Close in-app message --- 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. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | ----------------------------------------------- | ----------- | --------------- | -------------------- | --------------- | | Introduced in: | 5.7.0 | 6.7.0 | 1.5.0 | 2.5.0 | **Method name:** Injector.closeInAppMessage(campaignHash) **Declaration:**
public static void closeInAppMessage(String campaignHash)
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | ---------------- | ------ | --------- | ------- | ---------------------------------------- | | **campaignHash** | string | yes | - | Unique identifier of the in-app campaign | **Return value:** No value returned. **Example**:
```java Injector.closeInAppMessage(campaignHash); ```
```kotlin Injector.closeInAppMessage(campaignHash) ```
## Register for push notifications --- This method passes the Firebase Token to Synerise for notifications.
- You should call this method every time the user changes the system or application consent for notifications. - The API key must have the `API_PERSONAL_DEVICE_CLIENT_UPDATE` permission from the **Client** group. - If the registration fails, the SDK requests a token update again by a listener/delegate method ([Android](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener), [iOS](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed), [React Native](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener), [Flutter](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener)).
**Method name:** Client.registerForPush(firebaseId, mobilePushAgreement) **Declaration:**
```Java public static IApiCall registerForPush(@NonNull String firebaseId, boolean mobilePushAgreement) ```
```Kotlin fun registerForPush(@NonNull firebaseId:String, mobilePushAgreement:boolean):IApiCall ```
This method has a built-in cache mechanism. If you try to post the same data within 24 hours, the call to the backend isn't made.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **firebaseId** | String | yes | - | FirebaseInstanceId | | **mobilePushAgreement** | boolean | yes | - | Agreement (consent) for mobile push campaigns | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java 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 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) }) ```
## Register for push notifications without agreement --- This method passes the Firebase Token to Synerise for notifications and doesn't update the agreement of the profile. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Introduced in: | 4.14.0 | 5.7.1 | 0.15.0 | 1.1.0 |
The API key must have the `API_PERSONAL_DEVICE_CLIENT_UPDATE` permission from the **Client** group.
If the registration fails, the SDK requests a token update again by a listener/delegate method ([Android](/developers/mobile-sdk/listeners-and-delegates/android-listeners#on-register-for-push-listener), [iOS](/developers/mobile-sdk/listeners-and-delegates/ios-delegates#synerise-delegate-register-for-push-notifications-is-needed), [React Native](/developers/mobile-sdk/listeners-and-delegates/react-native-listeners#notifications-listener), [Flutter](/developers/mobile-sdk/listeners-and-delegates/flutter-listeners#notifications-listener)).
**Method name:** Client.registerForPush(firebaseId) **Declaration:**
```Java public static IApiCall registerForPush(@NonNull String firebaseId) ```
```Kotlin fun registerForPush(@NonNull firebaseId:String):IApiCall ```
This method has a built-in cache mechanism. If you try to post the same data within 24 hours, the call to the backend isn't made.
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **firebaseId** | String | yes | - | FirebaseInstanceId | **Return Value:** [IApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#iapicall) object to execute the request. **Example:**
```Java IApiCall call = Client.registerForPush(refreshedToken); call.execute(() -> Log.d(TAG, "Register for Push succeed: " + refreshedToken), apiError -> Log.w(TAG, "Register for push failed: " + refreshedToken)); ```
```Kotlin val call = Client.registerForPush(refreshedToken) call.execute({ Log.d(TAG, "Register for Push succeed: " + refreshedToken) }, { apiError-> Log.w(TAG, "Register for push failed: " + refreshedToken) }) ```
## Check if push notification is from Synerise --- This method verifies if a notification was sent by Synerise. **Method name:** Injector.isSynerisePush(pushPayload); **Declaration:**
```java public static boolean isSynerisePush(Map pushPayload) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pushPayload** | Map | yes | - | Key-Value map of data. The "issuer" key must be set to "Synerise". | **Return Value:** Boolean indicating if the incoming push contains an "issuer" key with the "Synerise" value. **Example:**
```java boolean isSynerisePush = Injector.isSynerisePush(data); ```
```kotlin var isSynerisePush = Injector.isSynerisePush(data) ```
## 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 Simple Push campaign **Method name:** Injector.isSyneriseSimplePush(pushPayload); **Declaration:**
```java public static boolean isSyneriseSimplePush(Map pushPayload) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pushPayload** | Map | yes | - | Key-Value map of data. The "issuer" key must be set to "Synerise". | **Return Value:** Boolean indicating if the incoming push contains a "content-type" key with the "simple-push" value. **Example:**
```java boolean isSyneriseSimplePush = Injector.isSyneriseSimplePush(data); ```
```kotlin var isSyneriseSimplePush = Injector.isSyneriseSimplePush(data) ```
## 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 Command. **Method name:** Injector.isSilentCommand(pushPayload); **Declaration:**
```java public static boolean isSilentCommand(Map pushPayload) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pushPayload** | Map | yes | - | Key-Value map of data. The "issuer" key must be set to "Synerise". | **Return Value:** Boolean indicating if the incoming push contains a "content-type" key with the "silent-command" value. **Example:**
```java boolean isSilentCommand = Injector.isSilentCommand(data); ```
```kotlin var isSilentCommand = Injector.isSilentCommand(data) ```
## Get a Silent Command --- Method that converts push payload into a SilentCommand object. **Method name:** Injector.getSilentCommand(payload); **Declaration:**
```java public static SilentCommand getSilentCommand(Map payload) throws ValidationException ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **payload** | Map | yes | - | payload received from push | **Return Value:** [SilentCommand](/developers/mobile-sdk/class-reference/android/campaigns#silentcommand) object, may be null if the payload is not a `SilentCommand` payload. **Example:**
```java SilentCommand silentCommand = Injector.getSilentCommand(payload); ```
```kotlin var silentCommand = Injector.getSilentCommand(payload) ```
## 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 Silent SDK Command. **Method name:** Injector.isSilentCommandSdk(pushPayload); **Declaration:**
```java public static boolean isSilentCommandSdk(Map pushPayload) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pushPayload** | Map | yes | - | Key-Value map of data. The "issuer" key must be set to "Synerise". | **Return Value:** Boolean indicating if the incoming push contains a "content-type" key with the "silent-sdk-command" value. **Example:**
```java boolean isSilentCommandSdk = Injector.isSilentCommandSdk(data); ```
```kotlin var isSilentCommandSdk = Injector.isSilentCommandSdk(data) ```
## Check if push notification is encrypted --- This method verifies if a notification is encrypted. **Method name:** Injector.isPushEncrypted(pushPayload); **Declaration:**
```java public static boolean isPushEncrypted(Map pushPayload) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pushPayload** | Map | yes | - | Key-Value map of data | **Return Value:** Boolean indicating if the incoming push is encrypted by Synerise. **Example:**
```java boolean isPushEncrypted = Injector.isPushEncrypted(data); ```
```kotlin var isPushEncrypted = Injector.isPushEncrypted(data) ```
## Decrypt push notification --- This method decrypts the notification payload.
If the notification is not encrypted, the method returns the raw payload.
If a notification is not decrypted successfully, the method returns nil.
**Method name:** Injector.decryptPushPayload(pushPayload); **Declaration:**
```java public static Map decryptPushPayload(Map pushPayload) throws DecryptionException ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pushPayload** | Map | yes | - | Key-Value map of data | **Return Value:** Key-Value map of data with the decrypted push. **Example:**
```java Injector.decryptPushPayload(data); ```
```kotlin Injector.decryptPushPayload(data) ```
## Handle Synerise push notification --- This method handles a notification payload and starts activity.
It is recommended to call this method from your `FirebaseMessagingService` subclass within the `onMessageReceived(RemoteMessage)` method.
**Method name:** Injector.handlePushPayload(pushPayload); **Declaration:**
```java public static boolean handlePushPayload(Bundle bundle) public static boolean handlePushPayload(Map pushPayload) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **bundle** | Bundle | yes | - | Bundle of data. Key "issuer" must be set to "Synerise". | | **pushPayload** | Map | yes | - | Key-Value map of data. The "issuer" key must be set to "Synerise". | **Return Value:** Boolean indicating if the incoming push contains an "issuer" key with the value "Synerise". **Example:**
```java boolean isSynerisePush = Injector.handlePushPayload(getIntent().getExtras()); ```
```kotlin var isSynerisePush = Injector.handlePushPayload(getIntent().getExtras()) ```
## Get pushes --- This method fetches Push Notifications set for mobile campaigns. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | n/a | n/a |
The API key must have the `CAMPAIGN_BACKEND_COLLECTOR_READ` permission from the **Collector** group.
**Method name:** Injector.getPushes(); **Declaration:**
```java public static IDataApiCall> getPushes() ```
**Parameters:** No parameters. **Return Value:** [IDataApiCall](/developers/mobile-sdk/method-reference/android/public-interfaces#idataapicall)> with a parameterized list of SynerisePushResponse to execute a request. **Example:**
```java IDataApiCall> apiCall = Injector.getPushes(); apiCall.execute(this::success, this::showAlertError); ```
```kotlin val apiCall = Injector.getPushes() apiCall.execute(({ this.success() }), ({ this.showAlertError() })) ```
## Removed methods ### Check if push notification is a Banner Campaign {#check-if-push-notification-is-a-banner-campaign} --- This method verifies if a notification’s sender is Synerise and if the notification is a Banner campaign. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | n/a | **Method name:** Injector.isSyneriseBanner(pushPayload); **Declaration:**
```java public static boolean isSyneriseBanner(Map pushPayload) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **pushPayload** | Map | yes | - | Key-Value map of data. The "issuer" key must be set to "Synerise". | **Return Value:** Boolean indicating if the incoming push contains a "content-type" key with the "template-banner" value. **Example:**
```java boolean isSyneriseBanner = Injector.isSyneriseBanner(data); ```
```kotlin var isSyneriseBanner = Injector.isSyneriseBanner(data) ```
### Fetch Banners {#fetch-banners} --- This method fetches banners set for mobile campaigns and caches the valid ones. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | n/a | **Method name:** Injector.fetchBanners(successListener, errorListener); **Declaration:**
```java public static void fetchBanners() public static void fetchBanners(@NonNull final DataActionListener> successListener, @NonNull final DataActionListener errorListener) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **successListener** | DataActionListener> | yes | - | Success data callback with valid banners. | | **errorListener** | DataActionListener<[ApiError](/developers/mobile-sdk/class-reference/android/miscellaneous#apierror)> | yes | - | Error callback with an ApiError instance. | **Return Value:** No value is returned. **Example:**
```java Injector.fetchBanners(); ```
```kotlin Injector.fetchBanners(); ```
### Get Banners {#get-banners} --- This method provides valid banners directly from SDK cache. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | n/a | **Method name:** Injector.getBanners(); **Declaration:**
```java public static List getBanners() ```
**Parameters:** No parameters. **Return Value:** List<[TemplateBanner](/developers/mobile-sdk/class-reference/android/campaigns#templatebanner)> of cached banners. **Example:**
```java List bannerList = Injector.getBanners(); ```
```kotlin var bannerList = Injector.getBanners() ```
### Show Banner {#show-banner} --- This method shows a banner immediately. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 4.6.0 | 4.7.0 | 0.12.0 | - | **Method name:** Injector.showBanner(banner, markPresented); **Declaration:**
```java public static void showBanner(TemplateBanner banner, boolean markPresented) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **banner** | [TemplateBanner](/developers/mobile-sdk/class-reference/android/campaigns#templatebanner) | yes | - | Banner to display | | **markPresented** | boolean | yes | - | Flag indicating if the banner should be marked as presented and not be presented the next time | **Return Value:** No value returned. **Example:**
```java Injector.showBanner(banner, markPresented); ```
```kotlin Injector.showBanner(banner, markPresented) ```
### Get Walkthrough {#get-walkthrough} --- This method fetches a walkthrough. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 |
The API key must have the `CAMPAIGN_BACKEND_CAMPAIGN_READ` permission from the **Campaign** group.
To receive callbacks properly, this method should be called after `Injector.setOnWalkthroughListener(OnWalkthroughListener)`.
**Method name:** Injector.getWalkthrough(); **Declaration:**
```java public static void getWalkthrough() ```
**Parameters:** No parameters. **Return Value:** No return value. **Example:**
```java Injector.getWalkthrough(); ```
```kotlin Injector.getWalkthrough() ```
### Show Walkthrough {#show-walkthrough} --- This method shows a walkthrough when it is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Method name:** Injector.showWalkthrough(); **Declaration:**
```java public static boolean showWalkthrough() ```
**Parameters:** No parameters. **Return Value:** Boolean value is returned. `true` if the loaded or cached Walkthrough was presented, `false` otherwise. **Example:**
```java Injector.showWalkthrough(); ```
```kotlin Injector.showWalkthrough() ```
### Check if Walkthrough is loaded {#check-if-walkthrough-is-loaded} --- This method checks if a walkthrough is loaded. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Method name:** Injector.isWalkthroughLoaded(); **Declaration:**
```java public static boolean isWalkthroughLoaded() ```
**Parameters:** No parameters. **Return Value:** Boolean value is returned. `true` if Walkthrough is already loaded, `false` otherwise. **Example:**
```java Boolean isWalkthroughLoaded = Injector.isWalkthroughLoaded(); ```
```kotlin var isWalkthroughLoaded = Injector.isWalkthroughLoaded() ```
### Check if loaded Walkthrough is unique {#check-if-loaded-walkthrough-is-unique} --- This method checks if the walkthrough is unique compared to the previous one. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | 5.0.0 | 6.0.0 | 1.0.0 | 2.0.0 | **Method name:** Injector.isLoadedWalkthroughUnique(); **Declaration:**
```java public static boolean isLoadedWalkthroughUnique() ```
**Parameters:** No parameters. **Return Value:** Returns `true` if the loaded Walkthrough is loaded and different than previously presented, `false` otherwise. **Example:**
```java Boolean isWalkthroughLoadedUnique = Injector.isLoadedWalkthroughUnique(); ```
```kotlin var isWalkthroughLoadedUnique = Injector.isLoadedWalkthroughUnique() ```
### Set Banner listener {#set-banner-listener} --- Set your own banner listener to receive optional callbacks. Instantiate `OnBannerListener` and override the desired callbacks. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | n/a | 6.0.0 | n/a | n/a | **Method name:** Injector.setOnBannerListener(banner, markPresented); **Declaration:**
```java public static void setOnBannerListener(OnBannerListener listener) ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **listener** | OnBannerListener | yes | - | Listener | **Return Value:** No value returned. **Example:**
```java Injector.setOnBannerListener(listener); ```
```kotlin Injector.setOnBannerListener(listener) ```
### Remove Banner listener {#remove-banner-listener} --- Remove banner listener to stop receiving callbacks. It is recommended to call this method when your Activity is stopped. | | **iOS SDK** | **Android SDK** | **React Native SDK** | **Flutter SDK** | | --- | --- | --- | --- | --- | | Removed in: | n/a | 6.0.0 | n/a | n/a | **Method name:** Injector.removeBannerListener(); **Declaration:**
```java public static void removeBannerListener() ```
**Parameters:** No parameters. **Return Value:** No value returned. **Example:**
```java Injector.removeBannerListener(); ```
```kotlin Injector.removeBannerListener() ```
### Promotions and Vouchers --- ## Promotions --- ### Get all promotions of a customer --- This method retrieves all available promotions that are defined for a customer.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> getAllPromotions(
      {required void Function(PromotionResponse promotionResponse) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function([PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse) promotionResponse) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.getAllPromotions(onSuccess: (PromotionResponse promotionResponse) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<PromotionResponse> getAllPromotions() async
**Return Value:** [PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse) **Example:**
await Synerise.promotions.getAllPromotions().catchError((error) {
      //onError handling
    });
### Get promotions with query parameters --- This method retrieves promotions that match the parameters defined in an API query.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [PromotionsApiQuery](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionsapiquery) [PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> getPromotions(PromotionsApiQuery apiQuery,
      {required void Function(PromotionResponse promotionResponse) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiQuery** | [PromotionsApiQuery](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionsapiquery) | yes | - | Object that stores all query parameters | | **onSuccess** | Function([PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse) promotionResponse) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.getPromotions(promotionsApiQuery, onSuccess: (PromotionResponse promotionResponse) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<PromotionResponse> getPromotions(PromotionsApiQuery apiQuery) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiQuery** | [PromotionsApiQuery](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionsapiquery) | yes | - | Object that stores all query parameters | **Return Value:** [PromotionResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionresponse) **Example:**
await Synerise.promotions.getPromotions(promotionsApiQuery).catchError((error) {
      //onError handling
    });
### Get promotion by UUID --- This method retrieves the promotion with the specified UUID.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> getPromotionByUUID(String uuid,
      {required void Function(Promotion promotion) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | | **onSuccess** | Function([Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) promotion) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.getPromotionByUUID(uuid, onSuccess: (Promotion promotion) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<Promotion> getPromotionByUUID(String uuid) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | **Return Value:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Example:**
await Synerise.promotions.getPromotionByUUID(uuid).catchError((error) {
      //onError handling
    });
### Get promotion by code --- This method retrieves the promotion with the specified code.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> getPromotionByCode(String code,
      {required void Function(Promotion promotion) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | | **onSuccess** | Function([Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) promotion) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.getPromotionByCode(code, onSuccess: (Promotion promotion) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<Promotion> getPromotionByCode(String code) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | **Return Value:** [Promotion](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotion) **Example:**
await Synerise.promotions.getPromotionByCode(code).catchError((error) {
      //onError handling
    });
### Activate promotion by UUID --- This method activates the promotion with the specified UUID.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> activatePromotionByUUID(String uuid,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.activatePromotionByUUID(uuid, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> activatePromotionByUUID(String uuid) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.activatePromotionByUUID(uuid).catchError((error) {
      //onError handling
    });
### Activate promotion by code --- This method activates the promotion with the specified code.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> activatePromotionByCode(String code,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.activatePromotionByCode(code, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> activatePromotionByCode(String code) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.activatePromotionByCode(code).catchError((error) {
      //onError handling
    });
### Activate promotions in a batch --- This method activates promotions with a code or with UUID in a batch.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [PromotionIdentifier](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionidentifier) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> activatePromotionsBatch(List<PromotionIdentifier> promotionsToActivate,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **promotionsToActivate** | List<[PromotionIdentifier](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionidentifier)> | yes | - | List of promotion identifiers | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.activatePromotionsBatch(promotionIdentifierList, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> activatePromotionsBatch(List<PromotionIdentifier> promotionsToActivate) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **promotionsToActivate** | List<[PromotionIdentifier](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionidentifier)> | yes | - | List of promotion identifiers | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.activatePromotionsBatch(promotionIdentifierList).catchError((error) {
      //onError handling
    });
### Deactivate promotion by UUID --- This method deactivates the promotion with the specified UUID.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> deactivatePromotionByUUID(String uuid,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.deactivatePromotionByUUID(uuid, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> deactivatePromotionByUUID(String uuid) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.deactivatePromotionByUUID(uuid).catchError((error) {
      //onError handling
    });
### Deactivate promotion by code --- This method deactivates the promotion with the specified code.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> deactivatePromotionByCode(String code,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.deactivatePromotionByCode(code, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> deactivatePromotionByCode(String code) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.deactivatePromotionByCode(code).catchError((error) {
      //onError handling
    });
### Deactivate promotions in a batch --- This method deactivates promotions with a code or with UUID in a batch.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [PromotionIdentifier](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionidentifier) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> deactivatePromotionsBatch(List<PromotionIdentifier> promotionsToDeactivate,
      {required void Function() onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **promotionsIdentifiers** | List<[PromotionIdentifier](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionidentifier)> | yes | - | List of promotion identifiers | | **onSuccess** | Function() | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.deactivatePromotionsBatch(promotionIdentifierList, onSuccess: () {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<void> deactivatePromotionsBatch(List<PromotionIdentifier> promotionsToDeactivate) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **promotionsIdentifiers** | List<[PromotionIdentifier](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#promotionidentifier)> | yes | - | List of promotion identifiers | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.deactivatePromotionsBatch(promotionIdentifierList).catchError((error) {
      //onError handling
    });
## Vouchers --- ### Get or assign voucher from pool --- This method retrieves an assigned voucher code or assigns a voucher from a pool identified by UUID to the customer. Once a voucher is assigned using this method, **the same** voucher is returned for the profile every time the method is called. When the voucher is assigned for the first time, a [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
The API key must have the `VOUCHERS_ITEM_ASSIGN_CREATE` and `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> getOrAssignVoucher(String poolUuid,
      {required void Function(AssignVoucherResponse assignVoucherResponse) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUuid** | String | yes | - | Unique identifier of a code pool | | **onSuccess** | Function([AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) assignVoucherResponse) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.getOrAssignVoucher(poolUuid, onSuccess: (AssignVoucherResponse assignVoucherResponse) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<AssignVoucherResponse> getOrAssignVoucher(String poolUuid) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUuid** | String | yes | - | Unique identifier of a code pool | **Return Value:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) **Example:**
await Synerise.promotions.getOrAssignVoucher(poolUuid).catchError((error) {
      //onError handling
    });
### Assign voucher code from pool --- This method assigns a voucher from a pool identified by UUID to the profile. Every request returns a **different code** until the pool is empty. A [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
Returns the HTTP 416 status code when the pool is empty.
The API key must have the `VOUCHERS_ITEM_ASSIGN_CREATE` and `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> assignVoucherCode(String poolUuid,
      {required void Function(AssignVoucherResponse response) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUuid** | String | yes | - | Unique identifier of a code pool | | **onSuccess** | Function([AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) assignVoucherResponse) | yes | - | Function to be executed when the operation is completed successfully, returning the [AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.assignVoucherCode(poolUuid, onSuccess: (AssignVoucherResponse assignVoucherResponse) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<AssignVoucherResponse> assignVoucherCode(String poolUuid) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUuid** | String | yes | - | Unique identifier of a code pool | **Return Value:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#assignvoucherresponse) **Example:**
await Synerise.promotions.assignVoucherCode(poolUuid).catchError((error) {
      //onError handling
    });
### Get voucher codes assigned to customer --- This method retrieves voucher codes for a customer.
The API key must have the `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** lib/modules/promotions/promotions_impl.dart **Related To:** [VoucherCodesResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#vouchercodesresponse) **Class:** [PromotionsImpl](/developers/mobile-sdk/class-reference/flutter/modules#promotions)
**Declaration:**
Future<void> getAssignedVoucherCodes(
      {required void Function(VoucherCodesResponse voucherCodesResponse) onSuccess,
      required void Function(SyneriseError error) onError}) async
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **onSuccess** | Function([VoucherCodesResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#vouchercodesresponse) voucherCodesResponse) | yes | - | Function to be executed when the operation is completed successfully | | **onError** | Function([SyneriseError](/developers/mobile-sdk/class-reference/flutter/miscellaneous#syneriseerror) error) | yes | - | Function to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
await Synerise.promotions.getAssignedVoucherCodes(onSuccess: (VoucherCodesResponse voucherCodesResponse) {
      //onSuccess handling
    }, onError: (SyneriseError error) {
      //onError handling
    });
**Declaration:**
Future<VoucherCodesResponse> getAssignedVoucherCodes() async
**Return Value:** [VoucherCodesResponse](/developers/mobile-sdk/class-reference/flutter/promotions-and-vouchers#vouchercodesresponse) **Example:**
await Synerise.promotions.getAssignedVoucherCodes().catchError((error) {
      //onError handling
    });
### Promotions and Vouchers ## Promotions --- ### Get all promotions of a customer --- This method retrieves all available promotions that are defined for a customer.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func getPromotions(success: ((PromotionResponse) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getPromotionsWithSuccess:(nonnull void (^)(SNRPromotionResponse *promotionResponse))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **success** | (([PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift Promotions.getPromotions(success: { (promotionResponse) in // success print(promotionResponse.items) }, failure: { (error) in // failure }) ```
```Objective-C [SNRPromotions getPromotionsWithSuccess:^(SNRPromotionResponse *promotionResponse) { / success } failure:^(SNRApiError *error) { // failure }]; ```
### Get promotions with query parameters --- This method retrieves promotions that match the parameters defined in an API query.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [PromotionsApiQuery](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionsapiquery) [PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func getPromotions(apiQuery: PromotionsApiQuery, success: ((PromotionResponse) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getPromotionsWithApiQuery:(nonnull SNRPromotionsApiQuery *)apiQuery success:(nonnull void (^)(SNRPromotionResponse *promotionResponse))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **apiQuery** | [PromotionsApiQuery](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionsapiquery) | no | - | Object that stores all query parameters | | **success** | (([PromotionResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionresponse)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let apiQuery = PromotionsApiQuery() apiQuery.types = [SNR_PROMOTION_TYPE_GENERAL] apiQuery.statuses = [SNR_PROMOTION_STATUS_ACTIVE, SNR_PROMOTION_STATUS_ASSIGNED] apiQuery.types = [SNR_PROMOTION_TYPE_GENERAL] apiQuery.sorting = [ [SNR_PROMOTION_SORTING_KEY_EXPIRE_AT: SNR_API_QUERY_SORTING_ASC], [SNR_PROMOTION_SORTING_KEY_TYPE: SNR_API_QUERY_SORTING_DESC] ] apiQuery.limit = 50 apiQuery.page = 1 apiQuery.includeMeta = true Promotions.getPromotions(apiQuery: apiQuery, success: { (promotionResponse) in // success }, failure: { (error) in // failure }) ```
```Objective-C SNRPromotionsApiQuery *apiQuery = [SNRPromotionsApiQuery new]; apiQuery.types = @[SNR_PROMOTION_TYPE_GENERAL]; apiQuery.statuses = @[SNR_PROMOTION_STATUS_ACTIVE, SNR_PROMOTION_STATUS_ASSIGNED]; apiQuery.types = @[SNR_PROMOTION_TYPE_GENERAL]; apiQuery.sorting = @[ @{SNR_PROMOTION_SORTING_KEY_EXPIRE_AT: SNR_API_QUERY_SORTING_ASC}, @{SNR_PROMOTION_SORTING_KEY_TYPE: SNR_API_QUERY_SORTING_DESC} ]; apiQuery.limit = 50; apiQuery.page = 1; apiQuery.includeMeta = YES; [SNRPromotions getPromotionsWithApiQuery:apiQuery success:^(SNRPromotionResponse *promotionResponse) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Get promotion by UUID --- This method retrieves the promotion with the specified UUID.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func getPromotion(uuid: String, success: ((Promotion) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getPromotionByUuid:(nonnull NSString *)uuid success:(nonnull void (^)(SNRPromotion *promotion))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | | **success** | (([Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let UUID: String = "UUID" Promotions.getPromotion(uuid: UUID, success: { (promotion) in // success print(promotion.code) print(promotion.discountValue) }, failure: { (error) in // failure }) ```
```Objective-C NSString *UUID = @"UUID"; [SNRPromotions getPromotionByUuid:UUID success:^(SNRPromotion *promotion) { // success } failure:^(SNRApiError *error) { // failure }] ```
### Get promotion by code --- This method retrieves the promotion with the specified code.
The API key must have the `PROMOTIONS_DETAILS_FOR_CLIENT_READ` permission from the **Client** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func getPromotion(code: String, success: ((PromotionResponse) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getPromotionByCode:(nonnull NSString *)code success:(nonnull void (^)(SNRPromotion *promotion))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | true | - | Code of the promotion | | **success** | (([Promotion](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotion)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let code: String = "CODE" Promotions.getPromotion(code: code, success: { (promotion) in // success print(promotion.code) print(promotion.discountValue) }, failure: { (error) in // failure }) ```
```Objective-C NSString *code = @"CODE"; [SNRPromotions getPromotionByCode:code success:^(SNRPromotion *promotion) { // success } failure:^(SNRApiError *error) { // failure }] ```
### Activate promotion by UUID --- This method activates the promotion with the specified UUID.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** Headers/SNRPromotions.h **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func activatePromotion(uuid: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)activatePromotionByUuid:(NSString *)uuid success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let UUID: String = "UUID" Promotions.activatePromotion(uuid: UUID, success: { (isSuccess) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *UUID = @"UUID"; [SNRPromotions activatePromotionByUuid:UUID success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }] ```
### Activate promotion by code --- This method activates the promotion with the specified code.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** Headers/SNRPromotions.h **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func activatePromotion(code: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)activatePromotionByCode:(NSString *)code success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let code: String = "CODE" Promotions.activatePromotion(code: code, success: { (isSuccess) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *code = @"CODE"; [SNRPromotions activatePromotionByCode:code success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }] ```
### Activate promotions in a batch --- This method activates promotions with a code or with UUID in a batch.
The API key must have the `PROMOTIONS_ACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [PromotionIdentifier](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionidentifier) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func activatePromotions(identifiers: [PromotionIdentifier], success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)activatePromotionsWithIdentifiers:(nonnull NSArray *)identifiers success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identifiers** | [[PromotionIdentifier]](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotionidentifier) | yes | - | List of identifiers of the promotions that you want to activate | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let UUIDs = "UUID_1, UUID2, UUID_3" let UUIDsArray = UUIDs.components(separatedBy: ",").filter { !$0.isEmpty } var promotionIdentifiers: [PromotionIdentifier] = [PromotionIdentifier]() UUIDsArray.forEach { uuid in let promotionIdentifier = PromotionIdentifier(uuid: uuid) promotionIdentifiers.append(promotionIdentifier) } Promotions.activatePromotions(identifiers: promotionIdentifiers, success: { (success) in // success }, failure: { (error) in // failure }) ```
### Deactivate promotion by UUID --- This method deactivates the promotion with the specified UUID.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** Headers/SNRPromotions.h **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func deactivatePromotion(uuid: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)deactivatePromotionByUuid:(nonnull NSString *)uuid success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **uuid** | String | yes | - | UUID of the promotion | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let UUID: String = "UUID" Promotions.deactivatePromotion(uuid: UUID, success: { (isSuccess) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *UUID = @"UUID"; [SNRPromotions deactivatePromotionByUuid:UUID success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }] ```
### Deactivate promotion by code --- This method deactivates the promotion with the specified code.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** Headers/SNRPromotions.h **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func deactivatePromotion(code: String, success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)deactivatePromotionByCode:(nonnull NSString *)code success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **code** | String | yes | - | Code of the promotion | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let code: String = "CODE" Promotions.deactivatePromotion(code: code, success: { (isSuccess) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *code = @"CODE"; [SNRPromotions deactivatePromotionByCode:code success:^(BOOL isSuccess) { // success } failure:^(SNRApiError *error) { // failure }] ```
### Deactivate promotions in a batch --- This method deactivates promotions with a code or with UUID in a batch.
The API key must have the `PROMOTIONS_DEACTIVATE_PROMOTIONS_UPDATE` permission from the **Promotions** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [PromotionIdentifier](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#promotionidentifier) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func deactivatePromotions(identifiers: [PromotionIdentifier], success: ((Bool) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)deactivatePromotionsWithIdentifiers:(nonnull NSArray *)identifiers success:(nonnull void (^)(BOOL isSuccess))success failure:(nonnull void (^)(SNRApiError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **identifiers** | [[PromotionIdentifier]](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers/#promotionidentifier) | yes | - | List of identifiers of the promotions that you want to de-activate | | **success** | ((Bool) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let UUIDs = "UUID_1, UUID2, UUID_3" let UUIDsArray = UUIDs.components(separatedBy: ",").filter { !$0.isEmpty } var promotionIdentifiers: [PromotionIdentifier] = [PromotionIdentifier]() UUIDsArray.forEach { uuid in let promotionIdentifier = PromotionIdentifier(uuid: uuid) promotionIdentifiers.append(promotionIdentifier) } Promotions.deactivatePromotions(identifiers: promotionIdentifiers, success: { (success) in // success }, failure: { (error) in // failure }) ```
## Vouchers --- ### Get or assign voucher from pool --- This method retrieves an assigned voucher code or assigns a voucher from a pool identified by UUID to the customer. Once a voucher is assigned using this method, **the same** voucher is returned for the profile every time the method is called. When the voucher is assigned for the first time, a [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
The API key must have the `VOUCHERS_ITEM_ASSIGN_CREATE` and `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherresponse) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func getOrAssignVoucher(poolUUID: String, success: ((AssignVoucherResponse) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getOrAssignVoucherWithPoolUUID:(nonnull NSString *)poolUUID success:(nonnull void (^)(SNRAssignVoucherResponse *assignVoucherResponse))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUUID** | String | no | - | Unique identifier of a code pool | | **success** | (([AssignVoucherResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherresponse)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let poolUUID: String = "POOL_UUID" Promotions.getOrAssignVoucher(poolUUID: poolUUID, success: { (assignVoucherResponse) in // success failure: { (error) in // failure }) ```
```Objective-C NSString *poolUUID = @"POOL_UUID"; [SNRPromotions getOrAssignVoucherWithPoolUUID:poolUUID success:^(SNRAssignVoucherResponse *assignVoucherResponse) { // success } failure:^(NSError * _Nonnull error) { // failure }]; ```
### Assign voucher code from pool --- This method assigns a voucher from a pool identified by UUID to the profile. Every request returns a **different code** until the pool is empty. A [voucherCode.assigned](/docs/assets/events/event-reference/loyalty#vouchercodeassigned) event is produced.
Returns the HTTP 416 status code when the pool is empty.
The API key must have the `VOUCHERS_ITEM_ASSIGN_CREATE` and `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [AssignVoucherResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherresponse) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func assignVoucherCode(poolUUID: String, success: ((AssignVoucherResponse) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)assignVoucherCodeWithPoolUUID:(nonnull NSString *)poolUUID success:(nonnull void (^)(SNRAssignVoucherResponse *assignVoucherResponse))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **poolUUID** | String | yes | - | Unique identifier of a code pool | | **success** | (([AssignVoucherResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#assignvoucherresponse)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift let poolUUID: String = "POOL_UUID" Promotions.assignVoucherCode(poolUUID: poolUUID, success: { (assignVoucherResponse) in // success }, failure: { (error) in // failure }) ```
```Objective-C NSString *poolUUID = @"POOL_UUID"; [SNRPromotions assignVoucherCodeWithPoolUUID:poolUUID success:^(SNRAssignVoucherResponse *assignVoucherResponse) { // success } failure:^(SNRApiError *error) { // failure }]; ```
### Get voucher codes assigned to customer --- This method retrieves voucher codes for a customer.
The API key must have the `VOUCHERS_ITEM_ASSIGN_READ` permission from the **Assign** group.
**Declared In:** Headers/SNRPromotions.h **Related To:** [VoucherCodesResponse](/developers/mobile-sdk/class-reference/ios/promotions-and-vouchers#vouchercodesresponse) **Class:** [Promotions](/developers/mobile-sdk/class-reference/ios/modules#promotions) **Declaration:**
```Swift static func getAssignedVoucherCodes(success: ((VoucherCodesResponse) -> Void), failure: ((ApiError) -> Void)) -> Void ```
```Objective-C + (void)getAssignedVoucherCodesWithSuccess:(nonnull void (^)(SNRVoucherCodesResponse *voucherCodesResponse))success failure:(nonnull void (^)(NSError *error))failure ```
**Parameters:** | Parameter | Type | Mandatory | Default | Description | | --- | --- | --- | --- | --- | | **success** | ((VoucherCodesResponse) -> Void) | yes | - | Closure/Block to be executed when the operation is completed successfully | | **failure** | (([ApiError](/developers/mobile-sdk/class-reference/ios/miscellaneous#snrapierror)) -> Void) | yes | - | Closure/Block to be executed when the operation is completed with an error | **Return Value:** No value is returned. **Example:**
```Swift Promotions.getAssignedVoucherCodes(success: { (voucherCodesResponse) in // success }, failure: { (error) in // failure }) ```
```Objective-C [SNRPromotions getAssignedVoucherCodesWithSuccess:^(SNRVoucherCodesResponse *voucherCodesResponse) { // success } failure:^(NSError * _Nonnull error) { // failure }]; ```
### Campaigns In this section, you will learn how to implement and handle Synerise campaigns in your mobile application. ### Jinjava filters Jinjava filters let you perform operations on values, such as rounding or formatting. If a filter has more than one parameter, the parameters are listed in the order they need to be provided.
If you use Visual Studio Code as your editor, you can use code snippets to speed up working with inserts. You can find the snippets in our Github repository: [https://github.com/Synerise/jinja-code-snippet](https://github.com/Synerise/jinja-code-snippet)
## abs Returns the absolute value of the argument. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to calculate the absolute value from | **Example:**
{% set my_number = -53 %}
{{ my_number|abs }} {#  returns 53  #}
## add Adds a number to the existing value. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to which the variable/number in the parameters will be added | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | A number/variable | **Example:**
{% set my_num = 40 %}
{{ my_num|add(13) }} {#  returns 53  #}
## attr Renders the attribute of a dictionary. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | The dictionary that contains an attribute | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The name of the attribute to render | **Example:** The filter example below is equivalent to rendering a variable that exists within a dictionary, such as content.absolute_url.
{% set content = {'absolute_url': 'https://example.com'} %}
{{ content|attr('absolute_url') }}
Output:
https://example.com
## base64 encode/decode You can encode/decode values with base64.
{% set foo = "example@synerise.com"|base64Encode %}

{{ foo }}
{#  returns ZXhhbXBsZUBzeW5lcmlzZS5jb20=  #}

{% set baz = foo|base64Decode %}

{{ baz }}
{#  returns "example@synerise.com"  #}
## batch A filter that divides items in a list into groups. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | list | yes | A sequence or dict to apply the filter to | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number of items to contain in each group | | string | no | The value used to fill in the positions of missing items | **Example:**
{% set items=[1, 2, 3, 4, 5] %}
<table>
    {%- for row in items|batch(3, 'xxx') -%}
    <tr>
        {%- for column in row -%}
        <td>{{ column }}</td>
        {%- endfor -%}
    </tr>
    {%- endfor -%}
</table>
Output code:
<table>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
    </tr>
    <tr>
        <td>4</td>
        <td>5</td>
        <td>xxx</td>
    </tr>
</table>
## bool Converts a value into a boolean using strict conversion rules. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | any | yes | The value to convert into a boolean |
The `|bool` filter uses **stricter rules** than implicit boolean conversion, which is used in comparisons (`==`, `!=`), `{% if %}` conditions, and the `is truthy` test. The two approaches can return different results for the same input value — see the [example below](#bool-conversion-example).
**`|bool` conversion rules:** | Input type | Returns `true` | Returns `false` | | :--- | :--- | :--- | | Boolean | `true` | `false` | | Integer | `1` | All other integers, including `0` | | Float | Never | Always, including `1.0` | | String | `"true"` or `"1"` | All other strings | | null | Never | Always | **Implicit conversion rules** (used in `==`, `!=`, `{% if %}`, `is truthy`): | Input type | Returns `true` | Returns `false` | | :--- | :--- | :--- | | Boolean | `true` | `false` | | Number | Any non-zero number | `0` | | String | Any non-empty string, except `"false"` | `""` (empty string) or `"false"` | | null | Never | Always | | Collection (list, map) | Non-empty | Empty | | Any other type | Always | Never | #### Bool conversion example This example converts a string to a boolean using the `|bool` filter:
{%- if "true"|bool == true -%}
    hello world
{%- endif -%}
The following example shows how `|bool` and implicit conversion can produce different results for the same input:
{% set x = true %}
{% set y = 'string' %}

{% if x == y %}
  == {# implicit conversion: non-empty string → true, so true == true #}
{% else %}
  !=
{% endif %}

{% if x == y|bool %}
  ==
{% else %}
  != {# |bool: 'string' is neither 'true' nor '1' → false, so true != false #}
{% endif %}
For strict type-and-value equality without any boolean conversion, use the [`sameas` test](/developers/inserts/exptest#issameas). Unlike `|bool`, `sameas` checks that two values are identical objects without type coercion. For example, `"1" is sameas "true"` returns `false`, because `"1"` and `"true"` are different strings.
## capitalize Capitalizes a value. The first character will be uppercase, all others lowercase. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string where the first character will be capitalized | **Example:**
{% set sentence = "the first letter of a sentence should always be capitalized." %}

{{ sentence|capitalize }}
## center Uses whitespace to center the value in a field of a given width. This filter will only work in tags where whitespace is retained, such as `
`.

**Input:**

| Type | Required | Description |
| :--- | :--- | :--- |
| value | yes | The value to center |

**Parameters:**

| Type | Required | Description |
| :--- | :--- | :--- |
| number | yes | The width of the field where the value will be centered |

**Example:**


<pre>
    {% set var = "string to center" %}

    {{ var|center(80) }}
</pre>
## count Returns the number of items in a sequence or mapping. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | The sequence/mapping to count | **Example:**
{% set services = ['Web design', 'SEO', 'Inbound Marketing', 'PPC'] %}

{{ services|count }}
## cut Removes a string from the value of another string. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The original string | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The sub-string to remove from the original string | **Example:**
{% set my_string = "Hello world." %}

{{ my_string|cut(' world') }}
## datetimeformat Formats a datetime object and returns a string. The datetime object can be generated with: - [`iso8601_to_time`](#iso8601_to_time) - [`timestamp_to_time`](#timestamp_to_time) - [`strtotime`](#strtotime)
To get the current UTC time, you can use the `{{ iso_date }}` and `{{ timestamp }}` variables. These variables are initialized automatically; you don't need to declare them first.
**Input:** | Type | Required | Description | | :--- | :--- | :--- | | datetime object | yes | The datetime object to format. | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The format of the date determined by the [directives](#datetimeformat-directives) added in this parameter. | | string | no | Time zone (offset) of the output date. | **Examples:**
{% set iso_string = "2023-01-19T09:15:40+03:00" %}
{{ iso_string|iso8601_to_time|datetimeformat('%a, %B %d; %H:%M','-01:00') }}

{# outputs "Thu, January 19; 05:15" #}
{{ 1721894790|timestamp_to_time|datetimeformat('%b %d, %Y; %H:%M') }}

{# outputs "Jul 25, 2024; 08:06" #}
### datetimeformat directives The table lists the formatting directives you can use in the Synerise Jinjava implementation. For the purpose of the "Example" column, the time is `2023-01-08T14:15:40.350+00:00`. | Directive | Description | Example | | --------- | ---------------------------------------------- | -------------------------- | | `%a` | Weekday, abbreviated | `Sun` | | `%A` | Weekday, full | `Sunday` | | `%w` | Weekday as number (Sunday is 1, Saturday is 7) | `1` | | `%d` | Day of the month, zero-padded | `08` | | `%b` | Month, abbreviated | `Jan` | | `%B` | Month, full | `January` | | `%m` | Month as number, zero-padded | `01` | | `%y` | Year, without century, zero-padded | `23` | | `%Y` | Year, with century | `2023` | | `%H` | Hour in 24-hour format, zero-padded | `14` | | `%I` | Hour in 12-hour format, zero-padded | `02` | | `%p` | AM/PM information | `PM` | | `%M` | Minutes, zero-padded | `15` | | `%S` | Seconds, zero-padded | `40` | | `%f` | Microseconds, zero-padded | `3500` | | `%z` | UTC offset | `+0000` | | `%Z` | Timezone name (as GMT or GMT±....) | `GMT` | | `%j` | Day of the year, zero-padded | `008` | | `%U` | Week number, Sunday as first day | `02` | | `%c` | Date and time | `Sun Jan 08 14:15:40 2023` | | `%x` | Date | `01/08/23` | | `%X` | Time | `14:15:40` | | `%%` | The `%` character, literal | `%` | ## default If the value is null, it returns the passed default value, otherwise the value of the variable. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | The variable to check | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | The value to return when the variable is not defined | | boolean | no | Set to `true` to use with variables which evaluate to false | **Example:**
// returns 'my_variable is not defined':

{% set my_variable = null %}
{{ my_variable|default('my_variable is not defined') }}

// returns 'Example string':

{% set my_variable2 = "Example string" %}
{{ my_variable2|default('my_variable is not defined') }}
If you want to use default with variables that evaluate to false you have to set the second parameter to true.
{{ ''|default('the string was empty', true) }}
## dictsort Sorts a dict and returns key-value pairs. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | dict | yes | The dict to sort | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | boolean | no | Defines if sorting is case-sensitive. Defaults to `false`. | | string | no | Allowed values: `key`,`value`. Defines sorting by key or by value. Defaults to `key`. | **Example:** Sort the dict by value, case insensitive.
{%- set contact = {
    'name': 'Alice',
    'email': 'alice@example.com',
    'phone': '123456789'
} -%}
{%- for item in contact|dictsort(false, 'value') -%}
    {{item}} </br>
{%- endfor -%}
Output:
email=alice@example.com
name=Alice
phone=123456789
## divide Divides the current value by a divisor. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to be divided | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The divisor | **Example:**
{% set my_number = 106 %}

{{ my_number|divide(2) }}
## divisible Evaluates to `true` if the value is divisible by the divisor provided in the parameter. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to be divided | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The divisor | **Example:** This example is an alternative to using the is [divisibleby expression test](/developers/inserts/exptest#isdivisibleby).
{% set num = 10 %}

{%- if num|divisible(2) -%}
    The number is divisible by 2
{%- endif -%}
## escape Converts the characters `&, <, >, ‘,`, and `”` in a string to HTML-safe sequences. Use this filter if you need to display text that might contain such characters in HTML. Marks the return value as a markup string. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to escape | **Example:**
{% set escape_string = "<div>This markup is printed as text</div>" %}

{{ escape_string|escape }}
## escape_jinjava Converts the characters `{` and `}` in strings to Jinjava-safe sequences. Use this filter if you need to display text that might contain such characters in Jinjava. Marks the return value as a markup string. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to escape | **Example:**
{% set escape_string = "{{This markup is printed as text}}" %}

{{ escape_string|escape_jinjava }}
## escapejs Escapes strings so that they can be safely inserted into a JavaScript variable declaration. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to escape | **Example:**
{% set escape_string = "This string can safely be inserted into JavaScript" %}

{{ escape_string|escapejs }}
## escapejson Escapes strings so that they can be used as JSON values. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to escape | **Example:**
{% set escape_string = "String that contains JavaScript" %}

{{ escape_string|escapejson }}
## filesizeformat Formats raw file size in bytes into a human-readable format (for example, "13 kB", "4.1 MB", "102 bytes", and so on). **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The file size to format | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | boolean | no | Defines if binary prefixes (Mebi, Gibi) should be used. Defaults to `false`. | **Example:**
{% set bytes = 100000 %}

{{ bytes|filesizeformat }}
## first Returns the first item of a sequence. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to process | **Example:**
{% set my_sequence = ['Item 1', 'Item 2', 'Item 3'] %}

{{ my_sequence|first }}
## float Converts the value into a floating point number. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | The value to convert into a float | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | float | no | The value to return if conversion fails. Defaults to `0.0`. | **Example:** This example converts a text field string value to a float.
{% set my_text = "25.3" %}

{{ my_text|float }}
## forceescape Enforces HTML escaping.
This may double-escape variables.
**Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The value to escape | **Example:**
{% set escape_string = "<div>This markup is printed as text</div>" %}

{{ escape_string|forceescape }}
## format Applies Python string formatting to an object. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | String value to reformat | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string arguments | yes | Values to insert into the string | **Example:** `%s` can be replaced with other variables or values, for example `%d`.
{{ "Hi %s %s"|format("Hello", "World!") }}
## fromjson Deserializes data from a string. The string must be a serialized object. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The JSON string to deserialize | **Example:**
{%- set y = '{"dataX":"b"}' -%}
{%- set deserialized = y|fromjson -%}
{{ deserialized }}
Output:
{dataX=b}
### Using fromjson with arrays To use `fromjson` with arrays, the array must be transformed into an object and then serialized with [tojson](#tojson). Such a situation may occur when arrays are the result of macros or other inserts. In the following example, the array is created for demonstration purposes:
// Set the array:
{% set array = [{"a":9,"b":10},{"a":12,"b":15}] %}
// Put the array in an object:
{% set obj = { data:array } %}
// Serialize the object:
{% set json_obj = obj|tojson %}
// Deserialize the object with the array:
{% set transformed = json_obj|fromjson %}
{{ transformed['data'][0].a }}
The output is `9` ## groupby Groups a sequence of objects by a common attribute. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | dict | yes | The dict to iterate over and group by a common attribute | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The name of the common attribute to group by | **Example:** If you have a list of dicts or objects that represent persons with the attributes `gender`, `first_name`, and `last_name` attributes, you can group all the customers by gender this way:
{%- set contents = [
    {'gender': 'male', 'name': 'John'},
    {'gender': 'female', 'name': 'Jane'},
    {'gender': 'male', 'name': 'Bob'},
    {'gender': 'female', 'name': 'Alice'}
] -%}

<ul>
    {%- for group in contents|groupby('gender') -%}
    <li>
        Group: {{ group.grouper }}
        <ul>
        {%- for content in group.list -%}
            <li>{{ content.name }}</li>
        {%- endfor -%}
        </ul>
    </li>
    {%- endfor -%}
</ul>
Output:
<ul><li>
male
<ul><li>
    John
</li><li>
    Bob
</li></ul>
</li><li>
    female
    <ul><li>
        Jane
    </li><li>
        Alice
    </li></ul>
</li></ul>
## hash Returns the SHA-256 hash of a string.
{% set foo = "example@synerise.com"|hash("SHA-256") %}

{{ foo }}
{#  returns cab06d7019d42ed33dcb260dba8860f8028d243dd78184f3b5156d7bdae636dd  #}
## indent Uses whitespace to indent a string. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to indent | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | no | The number of spaces. Defaults to 4. | | boolean | no | If `true`, the first line will be indented. Defaults to `false`. | **Example:**
<pre>
    {% set var = "string to indent" %}

    {{ var|indent(2, true) }}
</pre>
## int Converts the value into an integer. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | The value to convert into an integer | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | value | no | The value to return if conversion fails. Defaults to `0`. | **Example:** This example converts a text field string value to a integer.
{% set my_text = "23" %}

{{ my_text|int }}
## iso8601_to_time Converts an ISO date-time string to a datetime object, which should be further formatted with [`datetimeformat`](#datetimeformat). **Input** | Type | Required | Description | | :--- | :--- | :--- | | string | no* | An ISO date-time string. Can include a timezone. If the resulting object is printed directly, the timezone isn't displayed. You should use formatting to display the time in the correct timezones. See examples below.| *An empty string applies the current time. **Example**
{{ "2023-01-19T09:15:40+03:00"|iso8601_to_time }}
{# returns the following object:
2023-01-19 09:15:40
#}
Note that the timezone is not displayed, but it's saved as part of the object. To ensure that the timezone matches the one you want to display, declare it when formatting the time:
{{ "2023-01-19T09:15:40+03:00"|iso8601_to_time|datetimeformat('%H:%M:%S','-01:00') }}
{# returns the string:
05:15:40
#}
For more details on formatting, see [`datetimeformat`](#datetimeformat). ## join Returns a string which is the concatenation of the values in the sequence. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | A list of values to join | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | no | The separator. Defaults to empty string. | | string | no | Dict object attribute to use in joining **Example:**
{%- set users = [
    {'username': 'john'},
    {'username': 'jane'},
    {'username': 'bob'}
] -%}

{{ users|join('|', attribute='username') }}
Output:
john|jane|bob
It is also possible to join certain attributes of an object:
{{ users|join('|', attribute='username') }}
## last Returns the last item of a sequence. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to process | **Example:**
{% set my_sequence = ['Item 1', 'Item 2', 'Item 3'] %}

{{ my_sequence|last }}
## length Returns the number of items in a sequence or mapping. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to process | **Example:**
{% set services = ['Web design', 'SEO', 'Inbound Marketing', 'PPC'] %}

{{ services|length }}
## list Converts the value into a list. If it was a string, the returned list will be a list of characters. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | Value to split into a list | **Example:**
{% set one = 1 %}
{% set two = 2 %}
{% set three = 3 %}
{% set list_num = one|list + two|list + three|list %}

{{ list_num|list }}
## lower Converts a value to lowercase. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The string to convert into lowercase | **Example:**
{{ "Text to MAKE Lowercase"|lower }}
## map Applies a filter on a sequence of objects or looks up an attribute. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | object | yes | Sequence to apply a filter to or a dict for attribute lookup | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | attribute pointer or string | yes | Filter to apply to the sequence or dict attribute to look up | **Example:** The basic usage is mapping by an attribute. Imagine you have a list of customers but you are only interested in a list of usernames.
{%- set users = [
    {'username': 'john'},
    {'username': 'jane'},
    {'username': 'bob'}
] -%}
Users on this page: {{ users|map(attribute='username')|join(', ') }}
Output:
Users on this page: john, jane, bob
Alternatively, you can let invoke a filter by passing the name of the filter and the arguments afterwards. A good example would be applying a text conversion filter on a sequence.
{% set seq = ['item1', 'item2', 'item3'] %}

{{ seq|map('upper') }}
## md5 Calculates the MD5 hash of the given object. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | Value for MD5 hash calculation | **Example:**
{% set content = {'absolute_url': 'https://example.com/page1'} %}
{{ content.absolute_url | md5 }}
Output:
d22158c78143eeca7fa617577d741866
## multiply Multiplies the current object with the given multiplier. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to be multiplied | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The multiplier | **Example:**
{% set n = 20 %}

{{ n|multiply(3) }}
## prettyprint Pretty print a variable. Useful for debugging. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | Object to pretty print | **Example:**
{% set this_var = "Variable that I want to debug" %}

{{ this_var|pprint }}
## random Returns a random item from the sequence. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | Sequence to return a random entity from | **Example:** The following example shows how to return the name of a random item from a recommendation:
{% recommendations3 campaignId=CAMPAIGN_ID %}
    {% set randomItem = recommended_products3|random %}
    {{ randomItem.name }}
{% endrecommendations3 %}
## reject Filters a sequence of objects by applying a [test](/developers/inserts/exptest) to the objects and excluding the ones that match the test. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to test | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The name of the test to apply | **Example:**
{%- set some_numbers = [10, 12, 13, 3, 5, 17, 22] -%}

{{ some_numbers | reject('even') }}
Output:
[13, 3, 5, 17]
## rejectattr Filters a sequence of objects by applying a [test](/developers/inserts/exptest) to an attribute of an object and rejecting the objects that match the test. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to test | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The name of the attribute to test | | string | no | The name of the test to apply. Defaults to `'truthy'`. | **Example:** This loop rejects any post with the `content.post_list_summary_featured_image` attribute.
{%- set contents = [
    {'title': 'Post 1', 'post_list_summary_featured_image': 'img1.jpg'},
    {'title': 'Post 2', 'post_list_summary_featured_image': ''},
    {'title': 'Post 3', 'post_list_summary_featured_image': null}
] -%}

{%- for content in contents|rejectattr('post_list_summary_featured_image') -%}
    {{content.title}} </br>
{%- endfor -%}
Output:
Post 2
Post 3
## replace Returns a copy of the value with all occurrences of a substring replaced with a new one. The first argument is the substring that should be replaced, the second is the replacement string. If the optional third argument `count` is given, only the first `count` occurrences are replaced. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | Base string | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | String to replace | | string | yes | The replacement value | | number | no | This many first occurrences are replaced | **Example:**
{{ "Hello World"|replace("Hello", "Goodbye") }}
{{ "aaaaargh"|replace("a", "d'oh, ", 2) }}
## reverse Reverses the object or returns an iterator that iterates over it the other way round. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | value | yes | The sequence or dict to reverse | **Example:**
{% set nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] %}

{%- for num in nums|reverse -%}
    {{ num }}
{%- endfor -%}
## round Rounds the number to a given precision. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number to round | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | no | The precision of rounding (digits after decimal point). Defaults to 0. | | string | no | The method of rounding. Allowed values: `ceil` (up), `floor` (down), `common` (down if `fraction < .5`). Defaults to `common`. **Example:**
Even if rounded to 0 precision, a float is returned. The fraction of that float is `.0`
{{ 42.55|round }}
{{ 42.55|round(1, 'floor') }}
If you need a real integer, pipe it through int.
{{ 42.55|round|int }}
## select Filters a sequence of objects by applying a [test](/developers/inserts/exptest) to the objects and only returning the ones that match the test. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to test | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The name of the test to apply | **Example:**
{% set some_numbers = [10, 12, 13, 3, 5, 17, 22] %}

{{ some_numbers|select('even') }}
## selectattr Filters a sequence of objects by applying a [test](/developers/inserts/exptest) to an attribute of an object and returning only the objects that match the test. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to test | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | string | yes | The name of the attribute to test | | string | no | The name of the test to apply. Defaults to `'truthy'`. | **Example:** This loop selects any posts containing content.post_list_summary_featured_image.
{%- set contents = [
    {'title': 'Post 1', 'post_list_summary_featured_image': 'img1.jpg'},
    {'title': 'Post 2', 'post_list_summary_featured_image': ''},
    {'title': 'Post 3', 'post_list_summary_featured_image': null}
] -%}

{%- for content in contents|selectattr('post_list_summary_featured_image') -%}
    {{ content.title }}
{%- endfor -%}
Output:
Post 1
## shuffle Randomly shuffles a given list, returning a new list with all of the items of the original list in a random order. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence to shuffle | **Example:** The example below is a standard blog loop, with order randomized on page load.
{%- for content in ['a','b','c','d','e']|shuffle -%}
    {{content}}
{%- endfor -%}
## slice Slices an iterator and returns a list of lists containing those items. **Input:** | Type | Required | Description | | :--- | :--- | :--- | | sequence | yes | The sequence or dict to slice | **Parameters:** | Type | Required | Description | | :--- | :--- | :--- | | number | yes | The number of slices to create | **Example:** Create a div containing three `