Unity Plugin
This is the mParticle Unity plugin - use it to send your data to the mParticle platform and off to 100+ app services. The plugin exposes a native C# interface for direct use from Unity scripts, and is bundled with mParticle's native SDKs for iOS and Android. With the mParticle Unity SDK, developers can leverage mParticle's wide range of supported integrations that are otherwise unsupported by Unity.
Plugin Setup
Download and import the plugin package to get started:
- Navigate to the releases page, download
mParticle.unitypackage
- Open an existing Unity project or create a new project
- Open the package directly, or import it to your project by selecting Assets -> Import Package -> Custom Package...
iOS Setup
mParticle.unitypackage
contains the mParticle Apple SDK as a dynamic framework library and the required headers which will be automatically imported into your project.
You may need to add the mParticle Apple SDK as an embedded library in your xcode project build settings (under General -> Embedded Binaries). You may also need to build the "Device SDK" project from Unity (under Player Settings -> Target Device) first and then switch to "Simulator SDK" if you wish to run on the simulator.
Warning: the binary artifact for iOS contains simulator architectures (x86_64 and i386). These are provided to allow you to test on the simulator but must be stripped prior to submitting to the App Store or your app may be rejected. See this radar for more information: http://www.openradar.me/radar?id=6409498411401216
Automated Xcode configuration
mParticle.unitypackage
includes PostprocessBuildPlayer_mParticle
that automates several Xcode project configuration steps that are required to successfully build your application for the iOS platform. During the build process, Unity will locate and execute this script.
Starting with Unity 5.3, post-process scripts are not run automatically. In those cases, the script will be run by
mParticleBuildPostprocessor.cs
instead.
Ensure your Xcode project is in a folder called iOS
and that the folder is in the root of your unity project folder.
Manual Xcode configuration
You can also configure Xcode manually by adding the required frameworks specified in the Apple SDK's manual installation guide.
Android Setup
mParticle.unitypackage
contains the mParticle core AAR artifact which will be automatically imported into your project.
Usage
mParticle Singleton
The mParticle Unity package contains a class file named MParticle.cs
, which is a Unity Monobehavior
that exposes the mParticle API via MParticle.Instance
. The package also contains the classes MParticleiOS
and MParticleAndroid
. These classes are used by the mParticle singleton to interact with the native iOS and Android libraries. You should never access those classes directly from your code.
Initialization
The plugin must be initialized with your mParticle workspace key and secret prior to use, for example by placing the following into you main script's Awake
method:
using UnityEngine;
using mParticle;
namespace MyProject
{
public class Example : MonoBehaviour
{
void Awake ()
{
//use the correct workspace API key and secret for iOS and Android
#if UNITY_ANDROID
apiKey = "REPLACE ME ANDROID KEY";
apiSecret = "REPLACE ME ANDROID SECRET";
#elif UNITY_IPHONE
apiKey = "REPLACE ME IOS KEY";
apiSecret = "REPLACE ME IOS SECRET";
#endif
}
new MParticle().Initialize(new MParticleOptions()
{
ApiKey = apiKey,
ApiSecret = apiSecret
});
}
}
MParticleOptions
It is now required to initialize the SDK with an MParticleOptions object. MParticleOptions' only required fields are ApiKey and ApiSecret:
MParticle.Instance.Initialize (new MParticleOptions () {
ApiKey = key,
ApiSecret = secret,
InstallType = InstallType.KnownUpgrade,
Environment = mParticle.Environment.Development,
DevicePerformanceMetricsDisabled = false,
IdDisabled = false,
UploadInterval = 650,
SessionTimeout = 50,
UnCaughtExceptionLogging = false,
LogLevel = LogLevel.VERBOSE,
LocationTracking = new LocationTracking ("GPS", 100, 350, 22),
PushRegistration = new PushRegistration () {
AndroidSenderId = "12345-abcdefg",
AndroidInstanceId = "andriod-secret-instance-id",
IOSToken = "09876654321qwerty"
},
});
Initial Identify Request & IdentityStateListeners
The identity API is an integral part of the mParticle platform. The SDK operates is such a way that requires a current MParticleUser
to be present. It is explained more in the Android & iOS documentation, but the way we go about ensuring this is to make a call to the IdentityApi.Identify()
endpoint upon initialization. By default, we use the user identities associated with the current, stored MParticleUser
, or an empty request if an application is running for the first time.
Using MParticleOptions
, you have an option to override this default behavior, by registering a custom IdentityApiRequest
.
Additionally, you may set a global OnUserIdentified delegate in MParticleOptions
, which will be the most effective way to listen for any current MParticleUser
changes that may take place as a result of the initial Identify request:
new MParticle().Initialize(new MParticleOptions()
{
ApiKey = apiKey,
ApiSecret = apiSecret,
IdentifyRequest = new IdentityApiRequest () {
UserIdentities = new Dictionary<UserIdentity, string> () {
{ UserIdentity.CustomerId, "Customer ID 1" }
},
UserAliasHandler = ((previousUser, newUser) => newUser.SetUserAttribute("key", "value"))
},
IdentityStateListener = newUser => Console.WriteLine("New MParticleUser found, Mpid = " + newUser.Mpid);
});
Events
Events are central to many of mParticle's integrations; analytics integrations typically require events, and you can create mParticle Audiences based on the recency and frequency of different events.
App Events
App Events represent specific actions that a user has taken in your app. At minimum they require a name and a type, but can also be associated with a free-form dictionary of key/value pairs:
MParticle.Instance.LogEvent (new MPEvent("Hello world", EventType.Navigation) {
Duration = 1000,
StartTime = 123456789,
EndTime = 1234557789,
Info = new Dictionary<string, string>{{ "foo", "bar" }},
CustomFlags = new Dictionary<string, List<string>> {
{ "custom flag 1", new List<string> () { "one", "two", "five" } },
{ "custom flag 2", new List<string> () { } },
{ "custom flag 3", new List<string> () { "singleVal" } }
}
}
);
Commerce Events
The CommerceEvent
is central to mParticle's eCommerce measurement. CommerceEvents
can contain many data points but it's important to understand that there are 3 core variations:
- Product-based: Used to measure datapoints associated with one or more products
- Promotion-based: Used to measure datapoints associated with internal promotions or campaigns
- Impression-based: Used to measure interactions with impressions of products and product-listings
Here's an example of a Product-based purchase event:
Product[] products = new Product[2];
products[0] = new Product("foo name", "foo sku", 42, 2) {
Brand = "foo brand",
Category = "foo category",
CouponCode = "foo coupon",
CustomAttributes = new Dictionary<string, string>() {
{
"Key1",
"Value1"
},
{
"Key2",
"Value2"
}
}
products[1] = new Product("foo name 2", "foo sku 2", 100, 3) {
Brand = "foo brand 2";
Category = "foo category 2";
CouponCode = "foo coupon 2";
}
TransactionAttributes transactionAttributes = new TransactionAttributes("foo transaction id") {
Revenue = 180,
Shipping = 10,
Tax = 15,
Affiliation = "foo affiliation",
CouponCode = "foo coupon code"
};
CommerceEvent eCommEvent = new CommerceEvent (
ProductAction.Purchase,
products,
transactionAttributes
) {
ScreenName = "HomeScreen",
Currency = "USD",
CustomAttributes = new Dictionary<string, string>() {
{"key1", "value1"}
}
}
MParticle.Instance.LogEvent(eCommEvent);
Screen events
MParticle.Instance.LogScreen("Test screen");
Identity
Version 2 of the MParticle Unity SDK supports the full range of IDSync features. For more in depth information about MParticle's Identity features, checkout either the Android docs or the iOS docs on the topic
Accessing IdentityApi
To get a reference to the IdentityApi
:
var identityApi = MParticle.Instance.Identity;
Updating Identities
User identities allow you to associate specific identifiers with the current user:
IdentityApiRequest request = new IdentityApiRequest(identityApi);
request.UserIdentities.Add(UserIdentity.CustomerId, "customerId");
request.UserIdentities.Remove(UserIdentity.Email);
identityApi.Modify(request);
or
identityApi.Modify(new IdentityApiRequest()
{
UserIdentities = new Dictionary<UserIdentity, string>()
{
{ UserIdentity.CustomerId, "" }
}
});
In addition to this, the underlying iOS and Android SDKs will automatically collect device IDs.
User Attributes
User attributes allow for free form description of a user for segmentation and analytics:
identityApi.CurrentUser.SetUserAttribute("foo attribute", "bar value");
identityApi.CurrentUser.SetUserTag("foo tag");
identityApi.CurrentUser.RemoveUserAttribute("foo attribute");
Identity Change Callbacks
Since the identity API calls, Identify()
, Login()
, Logout()
, and Modify()
are asynchronous, you can register a callback for the results of the request:
identityApi.Logout()
.AddSuccessListener(success => Console.WriteLine(success.User.UserAttributes))
.AddFailureListener(failure => Console.WriteLine("HttpCode = " + failure.HttpCode + "/nErrors = " + failure.Errors));
Additionally, the identity API allows you to register a global `MParticleUser state change listener. Any time the currentUser value changes, the callback will be invoked:
OnUserIdentified onUserIdentified = newUser => Console.WriteLine("New MParticleUser found, Mpid = " + newUser.Mpid);
identityApi.Identity.AddIdentityStateListener(onUserIdentified);
These delegates are tracked by references, so it is wise to maintain a reference to the listener if you plan on later removing it:
identityApi.RemoveIdentityStateListener(onUserIdentified);
User Aliasing
When a new user is returned through an identity API request, you may want to transition the SDK and data from the previous user to the new user:
identityApi.Login(new IdentityApiRequest()
{
UserAliasHandler = (previousUser, newUser) =>
{
// do some stuff, but for example:
var persistentAttribute = "persistent user attribute";
if (previousUser.UserAttributes.ContainsKey(persistentAttribute))
{
newUser.UserAttributes.Add(persistentAttribute, previousUser.UserAttributes.GetValueOrDefault(persistentAttribute));
}
}
});
####Identity Error Handling
The SDK will not retry Identity requests automatically. Identity Requests will return an IdentityHttpResponse
object containing information on the error. On rare occurances you may receive and retry throttling errors:
identityApi.Login()
.AddFailureListener(failure => {
if (failure.HttpCode == IdentityApi.ThrottleError) {
//retry request here
}
Console.WriteLine("Http Code = " + failure.HttpCode + "/nErrors = " + failure.Errors.Aggregate ("", (composit, nextError) => composit += nextError.Message + ", "));
});