Skip to content
Eduardo Zatoni edited this page Mar 18, 2025 · 35 revisions

Contents

What is the Emarsys SDK

The Emarsys SDK enables you to use Mobile Engage and Predict in a very straightforward way. By incorporating the SDK in your app, we, among others, support you in handling credentials, API calls, tracking of opens and events as well as logins and logouts in the app.

MAUI binding for SAP Emarsys

Note

The currently supported platforms are iOS and Android.

The MAUI Binding for SAP Emarsys is the official binding to help integrate SAP Emarsys into your MAUI application. We have created a sample application to help in the integration and to give an example. The MAUI sample application is published here.

On this page we won't go into details about how the underlying Emarsys SDK works and how the supported features can be used. For more detailed information about the different features, please visit the documentation for the iOS SDK or the Android SDK.

As this Binding uses the respective Emarsys iOS and Emarsys Android SDK, their requirements apply (iOS SDK Requirements, Android SDK Requirements)

Requirements

Android

  • The minimum Android version should be at least API level 24.
  • Requires compileSdkVersion 33 or higher.
  • Emarsys SDK is using AndroidX.
  • Emarsys SDK is using Android Gradle Plugin 8.1.1

iOS

  • The iOS target should be iOS 11 or higher.
  • In order to be able to send push messages to your app, you need to have certifications from Apple Push Notification service (APNs).

1. First steps

1.1 ProjectReference

MAUI Binding for SAP Emarsys is now available on GitHub Packages.

https://github.com/emartech/maui-binding-for-sap-emarsys/pkgs/nuget/Maui.Binding.SAP.Emarsys

Create or update the nuget.config file, and add the following configuration.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="github" value="https://nuget.pkg.github.com/emartech/index.json" />
  </packageSources>
  <packageSourceCredentials>
    <github>
      <add key="Username" value="YOUR_GITHUB_USERNAME" />
      <add key="ClearTextPassword" value="YOUR_PERSONAL_ACCESS_TOKEN" />
    </github>
  </packageSourceCredentials>
</configuration>

Please refer to GitHub Packages doc for more detail.

Then add the package with dotnet command.

dotnet add package Maui.Binding.SAP.Emarsys

Or open the project's .csproj file and add the ProjectReference.

<ItemGroup>
  <PackageReference Include="Maui.Binding.SAP.Emarsys" Version="0.0.1" />
</ItemGroup>

If your project is targeted for frameworks other than Android and iOS, make sure to add the condition for the reference Condition="$(TargetFramework.Contains('android')) Or $(TargetFramework.Contains('ios'))".

To be able to use the SDK in your project import the Emarsys binding inside your project namespace like in the following example

namespace MyMAUIApp;

using EmarsysBinding;
using EmarsysBinding.Model;

1.2 Init

Emarsys setup should be implemented in the native mobile to ensure Setup method is the first thing to be called.

iOS

The SDK initialisation should be done in FinishedLaunching in AppDelegate.cs.

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
  var config = Emarsys.Config.Build(
    "EMSXX-XXXXX", // your application code
    "XXXXXXXXXXXXX", // your predict merchant ID
    null, // shared keychain access group
    true // enable console logging
  );
  Emarsys.Setup(config);
  //...
  return base.FinishedLaunching(application, launchOptions);
}

Notification Center delegate

The recommended way of using the iOS SDK is to enable the SDK to automatically handle the arrived push messages and TrackMessageOpen calls for you, please configure the delegate in FinishedLaunching.

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
  //...  
  Emarsys.Setup(config);
  
  Emarsys.Push.SetDelegate();
  //...

  return base.FinishedLaunching(application, launchOptions);
}

Android

Firebase

In order for push notifications to work, you need to obtain Firebase Cloud Messaging credentials for your app. Follow the instruction for the native SDK here: https://github.com/emartech/android-emarsys-sdk/wiki/Obtaining-Firebase-Cloud-Messaging-credentials, then copy the google-services.json file to the project directory of your MAUI project.

Add the GoogleServicesJson tag in the app's .csprojec file.

<ItemGroup Condition="$(TargetFramework.Contains('android'))">
  <GoogleServicesJson Include="google-services.json" />
</ItemGroup>

Messaging service

When the push token arrives from Firebase, we need to set it using Emarsys.Push.SetPushToken(). The recommended way of using the Android SDK is to enable the SDK to handle SetPushToken automatically and TrackMessageOpen calls for you, please register the service in your /Android/AndroidManifest.xml file inside the <application> tag.

<service android:name="com.emarsys.service.EmarsysFirebaseMessagingService" android:exported="false">
  <intent-filter>
    <action android:name="com.google.firebase.MESSAGING_EVENT"/>
  </intent-filter>
</service>

Additionally, you can set a custom notification icon, by specifying it as a meta-data in your application tag:

<meta-data
android:name="com.emarsys.mobileengage.small_notification_icon"
android:resource="@drawable/notification_icon"
>

For receiving push notifications in the background to work, the SDK has to be initialised in the OnCreate method of the MainApplication.cs file.

public override void OnCreate()
{
  base.OnCreate();
  var config = Emarsys.Config.Build(
    this, //
    "EMSXX-XXXXX", // your application code
    "XXXXXXXXXXXXX", // your predict merchant ID
    null, // shared package names
    null, // shared secret
    true // enable console logging
  );
  Emarsys.Setup(config);
}

1.3 SetContact

The contact field ID should not be set to 3 (email). In order to prevent your customers' personal data (PII) from being stored in our cloud infrastructure, we require the use of unique, non-guessable and immutable contact identifiers. Customer IDs are considered secure. Salted email hash is no longer supported for new Mobile Engage implementations. To make sure the behavioural tracking is cross-devices (i.e. mobile and web), the Web Extend contact ID should also use Customer ID and match that used on mobile.

After the application setup is finished, you can use the setContact method to identify the user with contactFieldId and contactFieldValue. Without setContact all events will be tracked as anonymous usage.

int contactFieldId = 100010824;
string contactFieldValue = "123ABC";
var error = await Emarsys.SetContact(contactFieldId, contactFieldValue);

1.4 ClearContact

Calling this method will end the connection between the currently set contact and Emarsys through the SDK. Calling this method will not remove the contact from Emarsys systems. It will only change the current identified contact to an anonymous one.

Note

No need to call ClearContact every time, even if the user isn't logged in. Just make sure it is called when the user logs out of the application.

var error = await Emarsys.ClearContact();

1.5 TrackCustomEvent

If you want to track custom events, the TrackCustomEvent method should be used, where the eventName parameter is required, but the eventAttributes is optional.

string eventName = "testingEventName";
Dictionary<string, string> eventAttributes = new Dictionary<string, string>
{
  { "key1", "value1" },
  { "key2", "value2" }
};
var error = await Emarsys.TrackCustomEvent(eventName, eventAttributes);

2. Push Notifications

2.1 SetPushToken

Android

The Emarsys SDK automatically handles setPushToken for the device and it is recommended to leave this to the SDK. However, if you have your custom implementation of MessagingService, please use the SetPushToken() method, to set the push token.

In case of a custom implementation where it's needed to set the push token in a different momment, you can also set it "manually".

var error = await Emarsys.Push.SetPushToken(pushToken);

iOS

The push token should be set natively when it arrives in RegisteredForRemoteNotifications in the AppDelegate.cs:

public async void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
  var error = await Emarsys.Push.SetPushToken(deviceToken);
}

2.2 ClearPushToken

If you want to remove pushToken for the Contact, please use the ClearPushToken() method.

var error = await Emarsys.Push.ClearPushToken();

2.3 GetPushToken

If you want to get the push token for the contact, please use the GetPushToken() method.

var error = await Emarsys.Push.GetPushToken();

2.4 Rich Push Notifications

iOS

Push notification could show media content and action buttons besides the title and body. Push notifications with these types of contents are called Rich Notifications.

  1. Create a Notification Service Extension project
  2. Add the Maui.Binding.SAP.Emarsys package
dotnet add package Maui.Binding.SAP.Emarsys
  1. Import Emarsys Binding
using EmarsysBinding;
  1. Implement Emarsys DidReceiveNotificationRequest
public override void DidReceiveNotificationRequest(UNNotificationRequest request, Action<UNNotificationContent> contentHandler)
{
  Emarsys.Push.DidReceiveNotificationRequest(request, contentHandler);
}
  1. Implement Emarsys TimeWillExpire
public override void TimeWillExpire()
{
  Emarsys.Push.TimeWillExpire();
}

NOTE: The constructor should not contain any initialization logic.

2.5 EventHandler

iOS

In order to react to an event triggered by push notification message, you should set the Emarsys handler in the FinishedLaunching method of the AppDelegate.cs.

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
  // ...
  Emarsys.Push.SetEventHandler((eventName, payload) => 
  {
    string payloadString = payload?.Description ?? "No payload";
    Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payloadString}");
  });
  // ...
  return base.FinishedLaunching(application, launchOptions);
}

Android

In order to react to an event triggered by push notification or in-app message, you should set the Emarsys Emarsys handlers in the OnCreate method of the MainApplication.cs.

public override void OnCreate()
{
  // ...
  Emarsys.Push.SetEventHandler((context, eventName, payload) => 
  {
    string payloadString = payload?.ToString() ?? "No payload";
    Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payloadString}");
  });
  // ...
}

2.6 SilentPushEventHandler

To be able to handle silent push, call set the event handle on the FinishedLaunching method in the AppDelegate.cs.

iOS

public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
{
  Emarsys.Push.SetSilentMessageEventHandler((eventName, payload) => 
  {
    Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payload?.Description ?? "No payload"}");
  });
}

Android

To be able to handle silent push, call set the event handle on the OnCreate method in the MainApplication.cs.

public override void OnCreate()
{
  Emarsys.Push.SetSilentMessageEventHandler((context, eventName, payload) => 
  {
    Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payload?.Description ?? "No payload"}");
  });
}

3. In-App

3.1 Overlay In-App

A full screen In-App dialog, that hovers in front of the application. Only one can be displayed at a time.

3.1.1 Pause

When a critical activity starts and should not be interrupted by In-App, use pause to pause method.

Emarsys.InApp.Pause();

3.1.2 Resume

In order to show In-App messages after being paused, use the resume method.

Emarsys.InApp.Resume();

3.1.3 IsPaused

Emarsys.InApp.IsPaused();

3.1.4 Event Handler

iOS

Emarsys.InApp.SetEventHandler((eventName, payload) => 
{
  string payloadString = payload?.Description ?? "No payload";
  Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payloadString}");
});

Android

Emarsys.InApp.SetEventHandler((context, eventName, payload) => 
{
  string payloadString = payload?.ToString() ?? "No payload";
  Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payloadString}");
});

3.2 Inline In-App

In-App message that takes place in the application's view hierarchy. Multiple inline In-App components are allowed on one screen.

To use the InlineInAppView control from the Emarsys binding, include the namespace in your XAML file by adding the following line:

xmlns:ems="clr-namespace:EmarsysBinding;assembly=Emarsys.Binding"

Add the following XAML code to display the InlineInAppView control within your layout:

<ems:InlineInAppView
  x:Name="inlineInAppView"
  HorizontalOptions="Fill"
  HeightRequest="0" />

Use ConfigureMauiHandlers to register custom handlers, like associating InlineInAppView with InlineInAppViewHandler for platform-specific rendering in the project's MauiProgram.cs file.

.ConfigureMauiHandlers(handlers =>
{
  handlers.AddHandler(typeof(EmarsysBinding.InlineInAppView), typeof(EmarsysBinding.InlineInAppViewHandler));
});

3.2.1 Load In-App

In order to load the inline in-app, LoadInApp must be called with the corresponding viewId.

inlineInAppView.LoadInApp("view-id");

3.2.2 Event Handler

In order to react to an event triggered by inline in-app message, you should set the inline inapp event handler.

inlineInAppView.SetEventHandler((eventName, payload) =>
{
  string payloadString = payload?.ToString() ?? "No payload";
  Utils.DisplayAlert("InlineInApp Event", $"Event: {eventName}\nData: {payloadString}");
});

3.2.3 Completion Listener

In order to react to an event triggered by inline load completion, you should set the inline inapp completion listener.

inlineInAppView.SetCompletionListener((error) =>
{
  if (error == null)
  {
    inlineInAppView.HeightRequest = 125;
  }
  else
  {
    Utils.LogResult("InlineInApp", error);
  }
});

3.2.4 Close Listener

In order to react to an event triggered by inline closed, you should set the inline inapp close listener.

inlineInAppView.SetCloseListener(() =>
{
  inlineInAppView.HeightRequest = 0;
});

3.3 OnEventActionEventHandler

In order to react to an event triggered by in-app on event actions, you should set the Emarsys handler.

iOS

Emarsys.InApp.SetOnEventActionEventHandler((eventName, payload) =>
{
  string payloadString = payload?.ToString() ?? "No payload";
  Utils.DisplayAlert("InlineInApp Event", $"Event: {eventName}\nData: {payloadString}");
});

Android

Emarsys.InApp.SetOnEventActionEventHandler((context, eventName, payload) =>
{
  string payloadString = payload?.ToString() ?? "No payload";
  Utils.DisplayAlert("InlineInApp Event", $"Event: {eventName}\nData: {payloadString}");
});

4. Inbox

User centric inbox solution. Emarsys SDK provides an Message named model class to make Inbox information easily accessible.

public class Message
{
  public string Id { get; set; }
  public string CampaignId { get; set; }
  public string? CollapseId { get; set; }
  public string Title { get; set; }
  public string Body { get; set; }
  public string? ImageUrl { get; set; }
  public int ReceivedAt { get; set; }
  public int? UpdatedAt { get; set; }
  public int? ExpiresAt { get; set; }
  public List<string>? Tags { get; set; }
  public Dictionary<string, object>? Properties { get; set; }
  public List<ActionModel>? Actions { get; set; }
}

The following action types are supported:

  • App event action
public class AppEventActionModel
{
  public string Id { get; set; }
  public string Title { get; set; }
  public string Type { get; set; }
  public string Name { get; set; }
  public Dictionary<string, object>? Payload { get; set; }
}
  • Custom event action
public class CustomEventActionModel
{
  public string Id { get; set; }
  public string Title { get; set; }
  public string Type { get; set; }
  public string Name { get; set; }
  public Dictionary<string, object>? Payload { get; set; }
}
  • Open External URL event action
public class OpenExternalUrlActionModel
{
  public string Id { get; set; }
  public string Title { get; set; }
  public string Type { get; set; }
  public string Url { get; set; }
}

4.1 FetchMessages

In order to receive the messageInbox content, you can use the FetchMessages method.

var results = await Emarsys.Inbox.FetchMessages();
if (results.Error != null)
{
  Utils.LogResult("FetchMessages", results.Error);
}
else
{
  Utils.LogResult("FetchMessages", null, $"{results.Messages.Count} messages found");
}

4.2 AddTag

To label a message with a tag, you can use AddTag method. (for example: "seen", "opened" etc)

var tag = "seen";
var messageId = message.Id;
var error = await Emarsys.Inbox.AddTag(tag, messageId);

4.3 RemoveTag

To remove a label from a message, you can use RemoveTag method.

var tag = "seen";
var messageId = message.Id;
var error = await Emarsys.Inbox.RemoveTag(tag, messageId);

5. Geofence

Important Note: Geofencing is disabled on Android devices, that do not have Google Play Services!

Geofence makes it available to trigger certain actions based on the user's location. When the user enters a predefined region (represented by latitude, longitude, and radius) EmarsysSDK fires a customEvent which can trigger an action, for example, a push notification. This requires permission for background locations from the user.

Note

Based on our experiences so far, the accuracy of geofencing is inconsistent and can be different based on device types and the environment of usage. We recommend adding at least 100m of radius to your geofences, to ensure that the triggers happen. Based on the Android documentation only 100 geofences/app can be used, so please be aware that our current geofencing solution only works well when there are no other geofencing solutions used by the application.

For more instructions on how to turn on Geofencing for different platforms please turn to our native Android and iOS documentation.

5.1 Enable

The Enable method is responsible for the activation of this feature

var error = await Emarsys.Geofence.Enable();

5.2 Disable

The Disable method is responsible for disabling this feature

Emarsys.Geofence.Disable();

5.3 IsEnabled

The IsEnabled method returns if the geofencing is currently enabled or not

Emarsys.Geofence.IsEnabled();

5.4 EventHandler

In order to react to an event triggered by geofence events, you should set the Emarsys handler.

iOS

Emarsys.Geofence.SetEventHandler((eventName, payload) => 
{
  string payloadString = payload?.Description ?? "No payload";
  Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payloadString}");
});

Android

Emarsys.Geofence.SetEventHandler((context, eventName, payload) => 
{
  string payloadString = payload?.ToString() ?? "No payload";
  Utils.DisplayAlert("Handle event", $"Event: {eventName}\nPayload: {payloadString}");
});

5.5 SetInitialEnterTriggerEnabled

When SetInitialEnterTriggerEnabled is true, Emarsys SDK will trigger all the affected geofences with Enter type triggers at the moment when the geofence is enabled if the device is already inside that geofence. By default, this value is set to false.

Emarsys.Geofence.SetInitialEnterTriggerEnabled(true);

6. Config

Config can be used to access information about the values set in the Emarsys SDK.

6.1 ChangeApplicationCode

The binding provides a way to change the applicationCode set in the setup. For this, use the ChangeApplicationCode method defined in the Emarsys.Config

Emarsys.Config.ChangeApplicationCode(<newAppCode : String>);

Note

Please keep in mind, if any error occurs during the change process the involved feature will be turned off.

When ChangeApplicationCode has been called, the SDK will log out the user and a SetContact(contactFieldId, contactFieldValue) must be called again with the correct contactFieldValue and contactFieldId.

Use cases of applicationCode change can be found on the native SDK wiki pages.

6.2 ChangeMerchantId

The binding provides a way to change the merchantId set in the setup. For this, use the ChangeMerchantId method defined in the Emarsys.Config

Emarsys.Config.ChangeMerchantId(<newMerchantId : String>);

6.3 GetApplicationCode

Provides what is the actual applicationCode set in the SDK.

Emarsys.Config.GetApplicationCode();

6.4 GetMerchantId

Provides the actual merchantId set in the SDK.

Emarsys.Config.GetMerchantId();

6.5 GetContactFieldId

Provides the actual contactFieldId set in the SDK.

Emarsys.Config.GetContactFieldId();

6.6 GetClientId

Provides the actual clientId set in the SDK.

Emarsys.Config.hardwareId();

6.7 GetLanguageCode

Provides what is the actual languageCode set in the SDK.

Emarsys.Config.GetLanguageCode();

6.8 GetSdkVersion

Note

This is not the MAUI binding version.

Provides what is the actual native sdkVersion set in the SDK.

Emarsys.Config.GetSdkVersion();

6.9 GetMauiBindingVersion

Note

This is not the native Emarsys SDK version.

Provides the actual mauiBindingVersion.

Emarsys.Config.GetMauiBindingVersion();

7. Predict

We won't go into the details to introduce how Predict works, and what its capabilities are, rather we aim to explain the mapping between the Predict commands and our interface. Please visit Predict's documentation for more information.

7.1 Initialization

To use the Predict functionality you have to setup your merchantId during the initialization of the SDK. In order to track Predict events, you can use the methods available on our Predict interface.

7.2 TrackCart

When you want to track the cart items in the basket, you can call the TrackCart method with a list of CartItems. CartItem is an interface that can be used in your application for your own CartItems and then simply use the same items with the SDK.

List<CartItem> items = new List<CartItem>
{
  new CartItem("item1", 1.1, 1.0),
  new CartItem("item2", 2.2, 2.0)
};
Emarsys.Predict.TrackCart(items);

7.3 TrackPurchase

To report a purchase event, you should call TrackPurchase with the items purchased and with an orderId.

string orderId = "order1";
List<CartItem> items = new List<CartItem>
{
  new CartItem("item1", 1.1, 1.0),
  new CartItem("item2", 2.2, 2.0)
};
Emarsys.Predict.TrackPurchase(orderId, items);

7.4 TrackItemView

If an item was viewed, use the TrackItemView method with an itemId as required parameter.

string itemId = "item1";
Emarsys.Predict.TrackItemView(itemId);

7.5 TrackCategoryView

When the user navigates between the categories, you should call TrackCategoryView in every navigation. Be aware to send categoryPath in the required format. Please visit Predict's documentation for more information.

string categoryPath = "Bikes > Road Bikes";
Emarsys.Predict.TrackCategoryView(categoryPath);

7.6 TrackSearchTerm

To report search terms entered by the contact, use TrackSearchTerm method.

string searchTerm = "search";
Emarsys.Predict.TrackSearchTerm(searchTerm);

7.7 TrackTag

To track custom tags, use the TrackTag method, where, the eventName parameter is required, but the tagAttributes is optional.

string tag = "tag";
Dictionary<string, string> attributes = new Dictionary<string, string>
{
  { "key1", "value1" },
  { "key2", "value2" }
};
Emarsys.Predict.TrackTag(tag, attributes);

7.8 RecommendProducts

7.8.1 logic

This is a required parameter of the RecommendProducts method.

The currently supported logics are:

  • SEARCH - based on searchTerm
  • CART - based on cartItems
  • RELATED - based on itemViewId
  • CATEGORY - based on categoryPath
  • ALSO_BOUGHT - based on itemViewId
  • POPULAR - based on categoryPath
  • PERSONAL - based on current browsing and activity, supports variants
  • HOME - based on most recent browsing behaviour, supports variants

Note

For more information on the recommender logics, please visit the official documentation.

You can pass the values to the chosen recommendation logic, but if you leave it empty, the SDK handles it and uses the last tracked values.

7.8.2 filters

This is an optional parameter of the RecommendProducts method.

You can filter product recommendations with the SDK by building RecommendationFilters. There are two types of filters: Exclude or Include.

In every case there are four types of comparators you can use to compare your chosen field to expectationValue:

  • IsValue - checking if the field is matching the value
  • InValues - any of the values has a match with the field
  • HasValue - One of the field values is equal to expectation value (applicable only to fields containing multiple values)
  • OverlapsValues - One or more of the field values are found in expectation values (applicable only to fields containing multiple values)

For further information please check the predict documentation.

7.8.3 limit

This is an optional parameter of the recommendProducts method.

You can limit the number of recommended products received by defining a limit. This is an optional parameter, by default its value is 5.

7.8.4 availabilityZones

This is an optional parameter of the recommendProducts method.

You can personalize the recommendation further by setting the availabilityZones parameter of the recommendation, to only recommend the locally available products.

For more information please check the Emarsys Predict documentation

7.8.5 Usage

The SDK is going to retrieve recommended products as result of the recommendProducts method

Logic logic = Logic.Home(["1", "2"]);
List<Filter> filters = new List<Filter> { Filter.ExcludeIsValue("field", "value") };
int limit = 3;
string availabilityZone = "en";
var result = await Emarsys.Predict.RecommendProducts(logic, filters, limit, availabilityZone);

7.9 TrackRecommendationClick

The Emarsys SDK doesn't track automatically recommendationClicks, so you have to call manually trackRecommendationClick when an interaction happens with any of the recommended products.

Emarsys.Predict.TrackRecommendationClick(RecommendedProduct);

Data flows in the plugin

Using this MAUI binding means that the automated tracking of the respective Android and iOS Emarsys SDK features will also be active. Details of this are documented for Android and iOS. In addition, when the Emarsys.Setup method is called, the MAUI binding will submit an Emarsys custom event reporting that the setup was called from MAUI.