adstage
Mobile SDKDeep Link

Unity

คู่มือการเชื่อมต่อ AdStage DeepLink (Unity)

สารบัญ

  1. ภาพรวม
  2. การตั้งค่าโปรเจกต์
  3. การตั้งค่าโปรเจกต์ Unity
  4. การตั้งค่าแพลตฟอร์ม Android
  5. การตั้งค่าแพลตฟอร์ม iOS
  6. การสร้าง deep link
  7. การแก้ไขปัญหา

ภาพรวม

AdStage DeepLink SDK for Unity มีฟีเจอร์ดังต่อไปนี้:

  • Deep link แบบเรียลไทม์: ประมวลผลทันทีผ่าน URL Scheme และ App Link/Universal Links
  • Deferred deep link: กู้คืนโดยอัตโนมัติเมื่อเปิดแอปครั้งแรกหลังการติดตั้ง
  • การสร้าง deep link แบบไดนามิก: สร้างลิงก์ที่ติดตามได้ผ่าน API ของเซิร์ฟเวอร์
  • การติดตาม attribution: การวิเคราะห์การตลาดบนพื้นฐานของพารามิเตอร์ UTM
  • ข้ามแพลตฟอร์ม: API เดียวกันสำหรับ Android/iOS
  • URL Scheme: myapp://promo/summer
  • Android App Links: https://go.myapp.com/abc123
  • iOS Universal Links: https://go.myapp.com/abc123
  • Deferred deep link: เมื่อยังไม่ได้ติดตั้งแอป จะกู้คืนเมื่อ สโตร์ → ติดตั้ง → เปิดแอป

การตั้งค่าโปรเจกต์

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. Dependency ที่จำเป็น

จะถูกรวมเข้ามาโดยอัตโนมัติเมื่อติดตั้งแพ็กเกจ:

  • Newtonsoft.Json: การ serialize JSON
  • Native plugin: บริดจ์ 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: สร้างอินสแตนซ์ใหม่ทุกครั้ง (ทำให้ deep link ซ้ำซ้อน)

การตั้งค่าแพลตฟอร์ม iOS

1. การตั้งค่า Info.plist ใน Xcode

<!-- 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로 이동
            // 앱 설치 여부 무관
}

ขั้นตอนการทำงานของ deep link บน 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)
  ↓
사용자 콜백 호출

ขั้นตอนการทำงานของ deep link บน 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)
  ↓
사용자 콜백 호출

การแก้ไขปัญหา

เป็นการทำงานปกติ! AdStage SDK ทำงานเฉพาะบนแพลตฟอร์มมือถือ (Android/iOS) เท่านั้น ใน Editor เมื่อเรียก AdStage.Initialize() แล้ว IsInitialized() จะคืนค่า false และ callback ของ deep link จะถูกรับเฉพาะบนเครื่องจริงเท่านั้น

วิธีตรวจสอบ:

#if UNITY_EDITOR
Debug.Log("📊 [Editor Mode] 딥링크는 실제 기기에서만 동작합니다");
#endif

วิธีทดสอบ: ติดตั้งบิลด์ Android/iOS จริงลงบนเครื่อง แล้วตรวจสอบการรับ deep link ด้วย การทดสอบ Intent / URL Scheme (ข้อ 2 และ 3) ในส่วนการแก้ไขปัญหาด้านล่าง

รายการตรวจสอบ:

  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

รายการตรวจสอบ:

  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
    • ตรวจสอบข้อความ error
    • ตรวจสอบ log การรับ deep link

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. ตั้งค่า Install Referrer ใน Play Console

สาเหตุ: ใช้ 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. ข้อผิดพลาดในการ serialize 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: ทดสอบ deep link ใน Unity Editor ได้ไหม?
A: ไม่ได้ เนื่องจาก SDK ทำงานเฉพาะบนแพลตฟอร์มมือถือเท่านั้น การทดสอบ deep link จึงต้องทำบนเครื่อง Android/iOS จริง

Q: ใช้ deep link URL เดียวกันบน Android และ iOS ได้ไหม?
A: ได้ ทั้ง URL Scheme และลิงก์ HTTPS ใช้ได้เหมือนกัน

Q: Deferred deep link ทำงานอย่างไร?
A: ติดตั้งแอป → เปิดครั้งแรก → ค้นหา Install Referrer → กู้คืน deep link ที่บันทึกไว้ → เรียก callback

Q: มีข้อจำกัดจำนวนพารามิเตอร์ของ deep link ไหม?
A: ไม่มีข้อจำกัดที่เซิร์ฟเวอร์ แต่ควรคำนึงถึงข้อจำกัดความยาว URL (~2000 ตัวอักษร)

Q: Deep link ทำงานแบบออฟไลน์ได้ไหม?
A: Deep link แบบเรียลไทม์ต้องใช้เครือข่าย ส่วน deferred deep link จะถูกแคชไว้และกู้คืนได้แม้แบบออฟไลน์

Q: ทำงานบน Unity WebGL ได้ไหม?
A: WebGL ไม่สามารถใช้ native plugin ได้ จึงไม่รองรับ ในสภาพแวดล้อมเว็บให้ parse พารามิเตอร์ URL โดยตรง


การสนับสนุน

ช่องทางติดต่อ:


© 2025 NBase. All rights reserved.

สารบัญ