StageUp
모바일 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에서 딥링크가 동작하지 않음

정상 동작입니다! Editor에서는 로그만 출력됩니다.

테스트 방법:

#if UNITY_EDITOR
[MenuItem("AdStage/Test DeepLink")]
public static void TestDeepLink()
{
    var testData = new DeepLinkData
    {
        ShortPath = "TEST123",
        Source = DeepLinkSource.Realtime,
        Parameters = new Dictionary<string, string>
        {
            { "promo", "EDITOR_TEST" }
        }
    };
    
    AdStage.SimulateDeepLink(testData);
}
#endif

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: Editor에서는 AdStage.SimulateDeepLink() 메서드로 시뮬레이션 가능합니다.

Q: Android와 iOS에서 동일한 딥링크 URL을 사용할 수 있나요?
A: 예, URL Scheme과 HTTPS 링크 모두 동일하게 사용 가능합니다.

Q: 디퍼드 딥링크는 어떻게 동작하나요?
A: 앱 설치 → 첫 실행 → Install Referrer 조회 → 저장된 딥링크 복원 → 콜백 호출

Q: 딥링크 파라미터 개수 제한이 있나요?
A: 서버 제한은 없으나, URL 길이 제한(~2000자)을 고려하세요.

Q: 오프라인에서도 딥링크가 동작하나요?
A: 실시간 딥링크는 네트워크 필요. 디퍼드 딥링크는 캐시되어 오프라인에서도 복원됩니다.

Q: Unity WebGL에서도 동작하나요?
A: WebGL은 네이티브 플러그인을 사용할 수 없어 지원하지 않습니다. 웹 환경에서는 URL 파라미터를 직접 파싱하세요.


지원

연락처:


© 2025 NBase. All rights reserved.

목차