adstage
移动 SDK深度链接

React Native

AdStage DeepLink 集成指南 (React Native)

目录

  1. 概述
  2. 安装
  3. 各平台设置
  4. SDK 初始化
  5. 深度链接接收处理
  6. 创建深度链接
  7. 疑难解答

概述

AdStage DeepLink SDK for React Native 提供以下功能:

  • 实时深度链接:通过 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
  • 延迟深度链接:未安装应用时 应用商店 → 安装 → 启动应用时还原

安装

npm / yarn 安装

# npm
npm install @adstage/react-native-sdk
 
# yarn
yarn add @adstage/react-native-sdk

iOS 依赖项安装

cd ios && pod install

各平台设置

iOS 设置

1. ATT (App Tracking Transparency) 权限(必需)

在 ios/YourApp/Info.plist 中添加以下内容:

<key>NSUserTrackingUsageDescription</key>
<string>用于衡量广告成效并提供个性化广告。</string>

2. URL Scheme 设置

在 ios/YourApp/Info.plist 中添加以下内容:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLName</key>
        <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>your_app_scheme</string>
        </array>
    </dict>
</array>

在 ios/YourApp/YourApp.entitlements 中添加以下内容:

<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:go.yourapp.com</string>
</array>

4. 修改 AppDelegate.mm

在 ios/YourApp/AppDelegate.mm 文件中添加用于处理深度链接的方法:

#import <AdapterAdStage/AdapterAdStage-Swift.h>
 
// URL Scheme 处理
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
            options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
    // AdStage 深度链接处理
    [[DeepLinkManager shared] handleDeepLink:url];
    return YES;
}
 
// Universal Links 处理
- (BOOL)application:(UIApplication *)application
    continueUserActivity:(NSUserActivity *)userActivity
      restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
    if ([userActivity.activityType isEqualToString:NSUserActivityTypeBrowsingWeb]) {
        [[DeepLinkManager shared] handleUniversalLink:userActivity];
        return YES;
    }
    return NO;
}

Android 设置

1. 添加 Maven 仓库(必需)

在 android/settings.gradle 或 android/build.gradle 中添加:

dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url 'https://jitpack.io' }
        maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }
        maven { url "https://maven.adstage.io/repository/public" }
    }
}

2. minSdkVersion 设置

在 android/build.gradle 中确认:

buildscript {
    ext {
        minSdkVersion = 24  // 最低需要 24 以上
    }
}

3. AndroidManifest.xml 设置

在 android/app/src/main/AndroidManifest.xml 中添加 Intent Filter:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTask"
    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>
    
    <!-- App Links (HTTPS) -->
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="https"
            android:host="go.yourapp.com" />
    </intent-filter>
</activity>

4. launchMode 重要事项

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

SDK 初始化

基本初始化

import { AdStage } from '@adstage/react-native-sdk';
 
// 应用启动时初始化
const initializeAdStage = async () => {
  try {
    await AdStage.initialize({
      apiKey: 'your-api-key-here'
    });
    
    // 设置深度链接监听器
    setupDeepLinkListener();
    
    // 确认 Pending 深度链接(冷启动)
    AdStage.deepLink.checkPendingDeepLink();
    
    console.log('✅ AdStage SDK 初始化完成');
  } catch (error) {
    console.error('❌ AdStage 初始化失败:', error);
  }
};
 
// 在 App.tsx 中调用
useEffect(() => {
  initializeAdStage();
}, []);

深度链接接收处理

1. 设置深度链接监听器

import { AdStage } from '@adstage/react-native-sdk';
 
const setupDeepLinkListener = () => {
  // 统一的深度链接监听器
  AdStage.deepLink.setListener((data) => {
    console.log('✅ 深度链接接收:', data);
    console.log('  - Short Path:', data.shortPath);
    console.log('  - Link ID:', data.linkId);
    console.log('  - Parameters:', data.parameters);
    
    // 处理业务逻辑
    handleDeepLink(data);
  });
};
 
const handleDeepLink = (data: DeepLinkData) => {
  const { shortPath, parameters } = data;
  
  // 根据参数跳转画面
  if (parameters?.product_id) {
    // 跳转到商品详情画面
    navigation.navigate('ProductDetail', { 
      productId: parameters.product_id 
    });
  } else if (parameters?.campaign) {
    // 跳转到广告系列画面
    navigation.navigate('Campaign', { 
      campaignId: parameters.campaign 
    });
  } else if (parameters?.promo) {
    // 应用推广代码
    applyPromoCode(parameters.promo);
  } else {
    // 默认: 首页
    navigation.navigate('Home');
  }
};

2. DeepLinkData 结构

interface DeepLinkData {
  linkId: string;              // 深度链接唯一 ID(服务器签发)
  shortPath: string;           // 深度链接 short path(例如 "abc123")
  parameters: Record<string, string>; // 自定义参数
  source: DeepLinkSource;      // 深度链接来源(实时/延迟)
  eventType: string;           // 事件类型(例如 "OPEN"、"INSTALL")
  timestamp?: string;          // 时间戳
}
 
type DeepLinkSource =
  | 'realtime'   // 实时深度链接(应用运行中/接收 URL、Universal Link)
  | 'install'    // 延迟深度链接(安装后首次启动时还原)
  | 'unknown';   // 未知

3. Pending 深度链接处理

应用完全退出的状态下通过深度链接启动时:

// SDK 初始化后确认 Pending 深度链接
await AdStage.initialize({ apiKey: 'your-api-key' });
 
// 先设置监听器
AdStage.deepLink.setListener((data) => {
  console.log('深度链接:', data);
  handleDeepLink(data);
});
 
// 确认并处理 Pending 深度链接
AdStage.deepLink.checkPendingDeepLink();

4. 实战示例:React Navigation 对接

import React, { useEffect } from 'react';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { AdStage } from '@adstage/react-native-sdk';
 
function App() {
  const navigationRef = React.useRef(null);
  
  useEffect(() => {
    const initSDK = async () => {
      await AdStage.initialize({ apiKey: 'your-api-key' });
      
      // 设置深度链接监听器
      AdStage.deepLink.setListener((data) => {
        const { parameters } = data;
        
        // 使用 React Navigation 跳转画面
        if (navigationRef.current) {
          if (parameters?.screen) {
            navigationRef.current.navigate(parameters.screen, parameters);
          }
        }
      });
      
      // 确认 Cold start 深度链接
      AdStage.deepLink.checkPendingDeepLink();
    };
    
    initSDK();
  }, []);
  
  return (
    <NavigationContainer ref={navigationRef}>
      {/* 导航栈 */}
    </NavigationContainer>
  );
}

创建深度链接

基本深度链接创建

import { AdStage } from '@adstage/react-native-sdk';
 
const createDeepLink = async () => {
  try {
    const result = await AdStage.deepLink.create({
      name: '夏季推广链接',
      description: '2025 年夏季折扣活动',
      
      // 归因参数
      channel: 'instagram',
      subChannel: 'social',
      campaign: 'summer_sale_2025',
      
      // 重定向设置
      redirectConfig: {
        type: 'APP', // 'STORE' | 'APP' | 'WEB'
        android: {
          packageName: 'com.yourapp.android',
          appScheme: 'yourapp://promo',
          webUrl: 'https://yourapp.com/promo',
        },
        ios: {
          appStoreId: '1234567890',
          appScheme: 'yourapp://promo',
          webUrl: 'https://yourapp.com/promo',
        },
        desktop: {
          webUrl: 'https://yourapp.com/promo',
        },
      },
      
      // 自定义参数
      parameters: {
        promo_code: 'SUMMER25',
        discount: '20',
        screen: 'PromoDetail',
      },
    });
    
    console.log('✅ 深度链接创建成功');
    console.log('  - Short URL:', result.shortUrl);
    console.log('  - Short Path:', result.shortPath);
    console.log('  - Link ID:', result.linkId);
    
    // 分享链接
    shareDeepLink(result.shortUrl);
    
  } catch (error) {
    console.error('❌ 深度链接创建失败:', error);
  }
};

CreateDeepLinkRequest 参数

参数类型必需说明
namestring✅深度链接名称
descriptionstring-深度链接说明
shortPathstring-Short Path 自定义
channelstring-渠道
subChannelstring-子渠道
campaignstring-广告系列
adGroupstring-广告组
creativestring-广告素材
contentstring-内容
keywordstring-关键词
redirectConfigRedirectConfig-重定向设置
parametersobject-自定义参数

RedirectConfig 结构

interface RedirectConfig {
  type: 'STORE' | 'APP' | 'WEB';   // 重定向类型
  android?: PlatformConfig;          // Android 平台设置
  ios?: PlatformConfig;              // iOS 平台设置
  desktop?: { webUrl?: string };     // 桌面设置
}
 
interface PlatformConfig {
  storeUrl?: string;     // 应用商店 URL
  appScheme?: string;    // 应用自定义 scheme
  webUrl?: string;       // 网页回退 URL
  packageName?: string;  // 包名(Android) / Bundle ID(iOS)
  appStoreId?: string;   // App Store ID (iOS)
}
类型应用已安装应用未安装
STORE前往应用商店前往应用商店
APP启动应用(实时深度链接)前往应用商店 → 安装后走延迟深度链接
WEB前往网页 URL前往网页 URL

实用函数

提取 Short Path

// 从 URL 中提取 Short Path
const shortPath = AdStage.deepLink.extractShortPath('https://adstage.net/ABCDEF');
console.log(shortPath); // "ABCDEF"

Android Intent 手动处理

import { Linking } from 'react-native';
 
// Android 上应用已在运行时处理新的 Intent
Linking.addEventListener('url', ({ url }) => {
  // 原生端会自动处理,必要时可手动调用
  AdStage.deepLink.handleIntent();
});

疑难解答

iOS 问题

收不到深度链接

  1. 确认 Info.plist 中是否正确设置了 URL Scheme
  2. 确认 AppDelegate.mm 中是否添加了深度链接处理方法
  3. 若使用 Universal Links,确认是否设置了 Associated Domains

ATT 权限弹窗不显示

  • 确认 Info.plist 中是否有 NSUserTrackingUsageDescription 键

Android 问题

深度链接重复接收

  • 确认 android:launchMode="singleTask" 设置

收不到深度链接

  1. 确认 AndroidManifest.xml 的 Intent Filter
  2. 确认 android:exported="true" 设置
  3. 若使用 App Links,确认 Digital Asset Links 文件

通用问题

延迟深度链接不工作

  1. 确认是否在 SDK 初始化完成后才设置监听器
  2. 确认是否调用了 checkPendingDeepLink()
  3. 确认网络连接状态

参数未被传递

  • 确认创建深度链接时是否在 parameters 对象中正确设置了值

目录