adstage
移动 SDK深度链接

Unity

AdStage DeepLink 集成指南(Unity)

目录

  1. 概述
  2. 项目设置
  3. Unity 项目设置
  4. Android 平台设置
  5. iOS 平台设置
  6. 创建深度链接
  7. 疑难排查

概述

AdStage DeepLink SDK for Unity 提供以下功能:

  • 实时深度链接:通过 URL Scheme、App Link/Universal Links 即时处理
  • 延迟深度链接:应用安装后首次启动时自动还原
  • 动态深度链接创建:通过服务器 API 创建可跟踪的链接
  • 归因跟踪:基于 UTM 参数的营销分析
  • 跨平台:Android/iOS 使用相同 API

支持的深度链接类型

  • URL Scheme: myapp://promo/summer
  • Android App Links: https://go.myapp.com/abc123
  • iOS Universal Links: https://go.myapp.com/abc123
  • 延迟深度链接:未安装应用时 商店 → 安装 → 启动应用时还原

项目设置

1. 安装软件包

通过 Package Manager 安装:

Window → Package Manager → + → Add package from git URL
https://github.com/nbase-io/NBase-SDK-Unity.git?path=/AdStageSDK-Package

或直接编辑 manifest.json:

{
  "dependencies": {
    "com.nbase.adstage": "https://github.com/nbase-io/NBase-SDK-Unity.git?path=/AdStageSDK-Package#3.0.0"
  }
}

2. 必需依赖

安装软件包时会自动包含:

  • Newtonsoft.Json:JSON 序列化
  • Native 插件:iOS/Android 桥接

Unity 项目设置

1. SDK 初始化

using AdStageSDK;
using UnityEngine;
 
public class AdStageInitializer : MonoBehaviour
{
    void Start()
    {
        // AdStage 初始化
        AdStage.Initialize(
            apiKey: "your-api-key-here"
        );
        
        // 注册深度链接监听器
        SetupDeepLinkListener();
        
        Debug.Log("✅ AdStage SDK 初始化完成");
    }
    
    private void SetupDeepLinkListener()
    {
        AdStage.SetDeepLinkListener(
            onDeepLink: (data) => {
                Debug.Log($"✅ 收到深度链接: {data.shortPath}");
                if (data.parameters != null && data.parameters.Count > 0)
                {
                    foreach (var param in data.parameters)
                    {
                        Debug.Log($"  - {param.Key}: {param.Value}");
                    }
                }
            },
            onError: (error) => {
                Debug.LogError($"❌ 深度链接失败: {error}");
            }
        );
    }
}

Android 平台设置

1. AndroidManifest.xml 设置

创建 Assets/Plugins/Android/AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    
    <application
        android:allowBackup="true"
        android:icon="@drawable/app_icon"
        android:label="@string/app_name">
        
        <activity
            android:name="com.unity3d.player.UnityPlayerActivity"
            android:theme="@style/UnityThemeSelector"
            android:screenOrientation="fullSensor"
            android:launchMode="singleTask"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
            android:exported="true">
            
            <!-- 默认启动器 -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            
            <!-- URL Scheme 深度链接 -->
            <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="your_app_scheme" />
            </intent-filter>
        </activity>
        
    </application>
</manifest>

2. launchMode 重要事项

android:launchMode="singleTask"
  • ✅ singleTask:复用已有的 Activity(推荐)
  • ⚠️ singleTop:仅在位于栈顶时才复用
  • ❌ standard:每次都创建新实例(会产生深度链接重复)

iOS 平台设置

1. 在 Xcode 中设置 Info.plist

<!-- URL Scheme 设置 -->
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>com.example.myapp</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>your_ios_scheme</string>
        </array>
    </dict>
</array>

创建深度链接

public async void CreateDetailedDeepLink()
{
    try
    {
         var builder = new DeepLinkBuilder("Unity Test Link")
             .SetDescription("Unity SDK 测试")
             .SetCampaign("unity_test")
             .SetChannel("app_channel")
             .SetRedirectType(RedirectType.APP)
             .SetAndroidConfig("your.package.name","your_aos_scheme", "https://yourdomain.com")
             .SetIOSConfig("your.appstoreid", "your_ios_scheme", "https://yourdomain.com")
             .SetWebConfig("https://yourdomain.com")
             .AddParameter("user_id", "value")
             .AddParameter("test", "true");
        
         AdStage.CreateDeeplink(
             builder: builder,
             onSuccess: (shortUrl) =>
             {
                 InAppLog("✅ 深度链接创建成功!");
                 InAppLog($"  URL: {shortUrl}");
             },
             onError: (error) =>
             {
                 InAppLog($"❌ 深度链接创建失败: {error}");
             }
         );
        
    }
    catch (System.Exception e)
    {
        Debug.LogError($"❌ 错误: {e.Message}");
    }
}

RedirectType 说明

public enum RedirectType
{
    STORE,  // 跳转到商店
    
    APP,    // 未安装应用时 → 跳转到商店
            // 已安装应用时 → 启动应用(实时深度链接)
    
    WEB     // 始终跳转到网页 URL
            // 与应用是否安装无关
}

Android 深度链接流程:

用户点击深度链接 (myapp://abc123)
  ↓
Android System 创建 Intent
  ↓
UnityPlayerActivity 启动/恢复
  ↓
AdStageLifecyclePlugin.onActivityCreated/Resumed()
  ↓
AdStageUnityWrapper.handleIntent(intent)
  ↓
AdStage.handleIntent(context, intent)
  ↓
DeeplinkHandler.handleIntent()
  ├─ 提取 URI: myapp://abc123
  ├─ 解析 shortPath: abc123
  ├─ 调用 API: GET /deeplinks/abc123
  └─ DeeplinkListener.onDeeplinkReceived()
       ↓
UnitySendMessage("AdStageCallbackReceiver", "OnDeepLinkReceived", json)
  ↓
AdStageCallbackReceiver.OnDeepLinkReceived(json)
  ↓
调用用户回调

iOS 深度链接流程:

用户点击深度链接 (myapp://abc123)
  ↓
iOS System 传递 URL
  ↓
AdStageUnityAppController.application:openURL: 或
AdStageUnityAppController.application:continueUserActivity:
  ↓
AdStageUnityBridge.AdStageIOS_HandleDeepLink(url)
  ↓
AdStageManager.shared.handleDeepLink(url)
  ↓
DeepLinkManager.handleDeepLink()
  ├─ 解析 URL
  ├─ 调用 API
  └─ DeepLinkDelegate.onDeepLinkReceived()
       ↓
UnitySendMessage("AdStageCallbackReceiver", "OnDeepLinkReceived", json)
  ↓
AdStageCallbackReceiver.OnDeepLinkReceived(json)
  ↓
调用用户回调

疑难排查

1. 深度链接在 Unity Editor 中不工作

这是正常行为! AdStage SDK 仅在移动平台(Android/iOS)上运行。 在 Editor 中调用 AdStage.Initialize() 时 IsInitialized() 会返回 false, 深度链接回调只能在真实设备上接收。

确认方法:

#if UNITY_EDITOR
Debug.Log("📊 [Editor Mode] 深度链接仅在真实设备上工作");
#endif

测试方法: 将实际的 Android/iOS 构建安装到设备后,用下方疑难排查中的 Intent / URL Scheme 测试(第 2 项、第 3 项)确认深度链接的接收。

2. Android 构建后收不到深度链接

检查清单:

  1. 确认 AndroidManifest.xml

    • 确认 android:launchMode="singleTask" 设置
    • 确认 Intent Filter 是否正确
  2. 确认 adb logcat

adb logcat | grep -i adstage
  1. Intent 测试
# URL Scheme 测试
adb shell am start -W -a android.intent.action.VIEW -d "myapp://promo/summer" com.example.myapp
 
# HTTPS App Link 测试
adb shell am start -W -a android.intent.action.VIEW -d "https://go.myapp.com/abc123" com.example.myapp

3. iOS 构建后收不到深度链接

检查清单:

  1. 确认 Info.plist

    • CFBundleURLTypes 设置
    • Associated Domains 设置
  2. Universal Links 验证

# 确认 Apple App Site Association 文件
curl https://go.myapp.com/.well-known/apple-app-site-association
  1. 确认 Xcode Console
    • 确认错误消息
    • 确认深度链接接收日志

4. 延迟深度链接未被还原

Android:

# 确认 Install Referrer
adb shell dumpsys package com.example.myapp | grep -i referrer

解决方法:

  1. 在 AndroidManifest.xml 中添加权限:
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE" />
  1. 在 Play Console 中设置 Install Referrer

5. 深度链接被重复调用

原因: 使用了 launchMode="standard"

解决:

<!-- AndroidManifest.xml -->
android:launchMode="singleTask"

6. Unity 2021+ IL2CPP 构建错误

问题:

TypeLoadException: Could not load type 'AdStageSDK.DeepLinkData'

解决: 创建 link.xml 文件

Assets/link.xml:

<linker>
    <assembly fullname="AdStageSDK" preserve="all"/>
    <assembly fullname="AdStageSDK.Models" preserve="all"/>
    <assembly fullname="Newtonsoft.Json" preserve="all"/>
</linker>

7. JSON 序列化错误

问题:

JsonSerializationException: Error converting value

解决:

// Parameters 使用 Dictionary<string, object>
var parameters = new Dictionary<string, object>
{
    { "key1", "value1" },
    { "key2", 123 },  // int 也可以
    { "key3", true }  // bool 也可以
};

确认方法:

# Digital Asset Links 验证
curl https://go.myapp.com/.well-known/assetlinks.json

检查清单:

  • ✅ 使用 HTTPS
  • ✅ Content-Type: application/json
  • ✅ 确认 SHA256 指纹是否正确
  • ✅ 包名一致

FAQ

Q: 可以在 Unity Editor 中测试深度链接吗?
A: 不可以。SDK 仅在移动平台上运行,因此深度链接测试必须在真实的 Android/iOS 设备上进行。

Q: Android 与 iOS 可以使用相同的深度链接 URL 吗?
A: 可以,URL Scheme 与 HTTPS 链接都可以相同地使用。

Q: 延迟深度链接是如何工作的?
A: 安装应用 → 首次启动 → 查询 Install Referrer → 还原已保存的深度链接 → 调用回调

Q: 深度链接的参数个数有限制吗?
A: 服务器没有限制,但请考虑 URL 长度限制(约 2000 个字符)。

Q: 离线状态下深度链接也能工作吗?
A: 实时深度链接需要网络。延迟深度链接会被缓存,离线状态下也能还原。

Q: 在 Unity WebGL 上也能工作吗?
A: WebGL 无法使用原生插件,因此不支持。在 Web 环境中请直接解析 URL 参数。


支持

联系方式:


© 2025 NBase. All rights reserved.

目录