Home

Awesome

UnityDeeplinks

A set of tools for Unity to allow handling deeplink activation from within Unity scripts, for Android and iOS, including iOS Universal Links.

Known Issues/Limitations

Disclaimer

This is NOT a TROPHiT SDK - this repo is an open-source contribution to developers for handling deeplink activations in a unified way for both iOS and Android. It can be used independently and regardless of TROPHiT services in order to intercept deeplinks for whatever purpose. If you are looking for info about TROPHiT integration modules, visit the TROPHiT Help Center

Usage

Example: Track Deeplinks with Adjust

public void onDeeplink(string deeplink) {
    AdjustEvent adjustEvent = new AdjustEvent("abc123");
    adjustEvent.addCallbackParameter("deeplink", deeplink); // optional, for callback support
    Adjust.trackEvent(adjustEvent);
}
#import "Adjust.h"  // <==== add this
...

- (void)onNotification:(NSNotification*)notification {
    if (![kUnityOnOpenURL isEqualToString:notification.name]) return;
    ...
    [Adjust appWillOpenUrl:url]; // <==== add this right before UnityDeeplinks_dispatch
    UnityDeeplinks_dispatch([url absoluteString]);
}

Example: Track Deeplinks with Tune

public void onDeeplink(string deeplink) {
   TuneEvent event = new TuneEvent("deeplink");
   event.attribute1 = deeplink;
   Tune.MeasureEvent(event);
}

Example: Track Deeplinks with Kochava

public void onDeeplink(string deeplink) {
   Kochava.DeeplinkEvent(deeplink, null);
}

Example: Track Deeplinks with AppsFlyer

public void onDeeplink(string deeplink) {
    System.Collections.Generic.Dictionary<string, string> values =
        new System.Collections.Generic.Dictionary<string, string>();
    values.Add("link", deeplink);
    AppsFlyer.trackRichEvent("deeplink", values);
}

Integration

Android

Subclass the default UnityPlayerActivity in order to add deeplink-handling code that marshals deeplinks into your Unity script:

<!--
<activity android:name="com.unity3d.player.UnityPlayerActivity" ...
-->
<activity android:name="com.trophit.MyUnityPlayerActivity" ...
<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:scheme="myapp" />
</intent-filter>

Why not handle deeplinks in a second activity?

Some might suggest having a "side-activity" e.g. MyDeeplinkActivity to handle the deeplink and start the main Unity player activity. This way, the main Unity player activity remains clean of "outside code", right? Wrong. Consider the Unity app is currently not running. Then:

Native libraries not loaded - dropping message for ...

Bottom line: you need the Unity player activity initialized in order to call Unity functions from native code. The only way to handle the scenario above would be to have the Unity player activity itself handle the deeplink. Unity will make sure it's initialized prior to the call.

Building the UnityDeeplinks.jar file

Only perform this step if you made changes to any .java file under Assets/UnityDeeplinks/Android/ or would like to rebuild it using an updated version of Unity classes, Android SDK, JDK and so on.

Prerequisites

Build instructions

Run the build script:

cd MY_UNITY_PROJECT_ROOT/Assets/UnityDeeplinks/Android
./build_jar.sh

Example output:

Compiling ...
/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home/jre/lib
/Applications/Unity/PlaybackEngines/AndroidPlayer/Variations/mono/Release/Classes/classes.jar:/kankado/dev/tools/android-sdk-macosx/platforms/android-23/android.jar
Creating jar file...
adding: com/(in = 0) (out= 0)(stored 0%)
adding: com/trophit/(in = 0) (out= 0)(stored 0%)
adding: com/trophit/DeeplinkActivity.class(in = 2368) (out= 1237)(deflated 47%)
adding: com/trophit/MyUnityPlayerActivity.class(in = 1504) (out= 789)(deflated 47%)

This creates/updates a UnityDeeplinks.jar file under your Unity project's Assets/UnityDeeplinks folder.

Finally, continue to build and test your Unity project as usual in order for any jar changes to take effect

iOS

UnityDeeplinks implements a native plugin for iOS, initialized by Assets/UnityDeeplinks/UnityDeeplinks.cs. The plugin listens for URL/Univeral Link activations and relayes them to the Unity script for processing. It, too, uses a similar approach as the one used for Android: the main Unity app controller gets subclassed.

Also, like in the Android case, if the app is currently not running, we can't simply have the native low-level deeplinking code make calls to Unity scripts until the Unity libraries are initialized. Therefore, we store the deeplink in a variable, wait for the app to initialize the plugin (an indication that the Unity native libraries are ready), and then send the stored deeplink to the Unity script.

Testing

<body>
<a href="myapp://?a=b">deeplink test</a>
</body>

Special Cases

AppsFlyer

AppsFlyer already provides some implementation for iOS and Android to handle deeplinks. However, it has some inconsistencies:

For those reasons, we provide an implementation to completent AppsFlyer. Assuming you have already followed AppsFlyer's integration guide and performed the integration instructions above, follow the extra steps below and later proceed with testing as usual

Android

protected void onDeeplink(Intent intent) {
   AppsFlyerLib.getInstance().setDeepLinkData(intent); // <== add this
   // if (Intent.ACTION_VIEW.equals(intent.getAction())) ...
}

iOS

#if UNITY_IOS
AppsFlyer.setAppID ("123456789");
AppsFlyer.getConversionData();
// ...
// IMPL_APP_CONTROLLER_SUBCLASS(AppsFlyerAppController)
#import "AppsFlyerTracker.h"
...
// Add as the first line inside application:continueUserActivity:
[[AppsFlyerTracker sharedTracker] continueUserActivity:userActivity restorationHandler:restorationHandler];