Deep linking
Cold, warm, and deferred deep links — what each one is, how to wire them, and where Reflect helps.
Three flavors
| Type | What it is | Example |
|---|---|---|
| Cold | App was NOT running. User taps a link → OS launches the app + delivers the URL. | Universal Link from email; intent filter on Android. |
| Warm | App already running. OS dispatches a new URL. | Push notification deep link; iOS scene continueUserActivity. |
| Deferred | User clicked a link, app wasn’t installed, they were sent to the store, installed, and now we want to honor the original intent. | “Promo for spring sale” → install → land on the spring sale screen. |
Subscribe to deep-link events
using Reflect;
void Awake() {
ReflectSDK.OnDeepLink += HandleDeepLink;
}
void OnDestroy() {
ReflectSDK.OnDeepLink -= HandleDeepLink;
}
void HandleDeepLink(DeepLinkData data) {
Debug.Log($"[DL] {data.Source} → {data.Url} (path: {data.Path})");
// Route within your app:
if (data.Path?.StartsWith("/promo/") == true) {
Router.GoTo(data.Path);
}
}DeepLinkData.Source is one of Cold, Warm, Deferred. The SDK also fires a deep_link_opened event so you can measure deep-link conversion in reports.
Deferred — works out of the box
When you create a tracking link in the admin panel, set Deep link path (e.g. /promo/spring2026). Reflect threads it through:
- Android: into the Play Install Referrer as
dl=.... - iOS: into the AdServices payload as
ct2=....
The SDK reads it on first launch and fires OnDeepLink with Source=Deferred after app_install. Zero extra setup.
Cold + warm — wire from your platform code
Reflect deliberately doesn’t auto-swizzle Activity/AppDelegate methods (it’d conflict with your other SDKs). Call HandleDeepLink from your own handlers:
Android
In your launcher Activity:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Uri uri = intent.getData();
if (uri != null) {
UnityPlayer.UnitySendMessage("ReflectCallbackReceiver", "OnExternalDeepLink", uri.toString());
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri coldUri = getIntent() != null ? getIntent().getData() : null;
if (coldUri != null) {
UnityPlayer.UnitySendMessage("ReflectCallbackReceiver", "OnExternalDeepLinkCold", coldUri.toString());
}
}iOS
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
UnitySendMessage("ReflectCallbackReceiver", "OnExternalDeepLink", url.absoluteString.UTF8String);
return YES;
}
- (BOOL)application:(UIApplication *)app
continueUserActivity:(NSUserActivity *)activity
restorationHandler:(void (^)(NSArray * _Nullable))handler {
if ([activity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb] && activity.webpageURL) {
UnitySendMessage("ReflectCallbackReceiver", "OnExternalDeepLink", activity.webpageURL.absoluteString.UTF8String);
return YES;
}
return NO;
}From C# directly
If you already have your own deep-link handler in C#:
Application.deepLinkActivated += url => {
// Call us — we'll fire OnDeepLink for your subscribers.
ReflectSDK.HandleDeepLink(url, isCold: !ReflectSDK.IsInitialized);
};Set a deep_link_path on a tracking link
Admin panel → Tracking Links → create / edit a link → Deep link path field. Server appends it to the store URL on every redirect; the SDK delivers it via OnDeepLink with Source=Deferred on first launch.