You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo托管应用中Branch Deeplink实现问题求助(附代码)

Expo托管应用集成Branch Deeplink问题排查与实现指导

我在Expo托管应用中尝试用Branch实现深度链接,已完成基础配置和插件添加,但动态链接生成环节出现问题:Android端调用函数时直接崩溃,iOS端崩溃前有警告日志。以下是当前配置、代码及问题排查/实现指导:


一、当前配置与代码

1. app.config.ts 配置

export default {
    expo: {
        name: getAppName(),
        slug: 'my_app',
        version: '1.0.0',
        platforms: ['ios', 'android'],
        orientation: 'portrait',
        icon: './assets/images/icon.png',
        scheme: ['myapp'],
        userInterfaceStyle: 'automatic',
        splash: {
            image: './assets/images/splash.png',
            resizeMode: 'cover',
            backgroundColor: '#431F81',
        },
        ios: {
            usesAppleSignIn: true,
            supportsTablet: true,
            bundleIdentifier: getUniqueIdentifier(),
            config: {
                usesNonExemptEncryption: false,
                branch: {
                    apiKey: 'key_live_xxx',
                },
            },
            infoPlist: {
                CFBundleURLTypes: [
                    {
                        CFBundleURLSchemes: [
                            'com.googleusercontent.apps.xxx',
                        ],
                    },
                ],
                UIViewControllerBasedStatusBarAppearance: true,
            },
        },
        android: {
            config: {
                branch: {
                    apiKey: 'key_live_xxx',
                },
            },
            adaptiveIcon: {
                foregroundImage: './assets/images/adaptive-icon.png',
                backgroundColor: '#ffffff',
            },
            package: getUniqueIdentifier(),
        },
        androidStatusBar: {
            barStyle: 'light-content',
            backgroundColor: '#431F81',
        },
        androidNavigationBar: {
            barStyle: 'dark-content',
            backgroundColor: '#431F81',
        },
        updates: {
            url: 'https://u.expo.dev/xxx',
        },
        runtimeVersion: {
            policy: 'appVersion',
        },
        plugins: [
            'expo-router',
            'expo-font',
            'expo-secure-store',
            'expo-apple-authentication',
            [
                '@react-native-google-signin/google-signin',
                {
                    iosUrlScheme: 'com.googleusercontent.apps.xxx',
                },
            ],
            ['@config-plugins/react-native-branch'],
        ],
        experiments: {
            typedRoutes: true,
            tsconfigPaths: true,
        },
        extra: {
            router: {
                origin: false,
            },
            eas: {
                projectId: 'xxx',
            },
        },
    },
}

2. 动态链接生成函数

type BranchOptions = {
    title: string
    contentDescription: string
}

type LinkProperties = {
    feature?: string
    channel?: string
    campaign?: string
    stage?: string
    tags?: string[]
}

type ControlParams = {
    $fallback_url?: string
    $desktop_url?: string
    $ios_url?: string
    $ipad_url?: string
    $android_url?: string
    $samsung_url?: string
    [key: string]: any
}

export const createJoinLink = async (
    identifier: string,
    options: BranchOptions,
    linkProperties: LinkProperties,
    controlParams: ControlParams,
): Promise<string | null> => {
    try {
        let buo = await branch.createBranchUniversalObject(`${identifier}`, options)

        let { url } = await buo.generateShortUrl(linkProperties, controlParams)

        return url
    } catch (e) {
        Alert.alert('Error', 'Unable to create deep link: ' + e.message)
        return null
    }
}

3. 函数调用示例

const generateDeepLink = (joinId: string) => {
        setLoading(true)

        let options = {
            title: 'Come join in the fun',
            contentDescription: '',
        }
        let linkProperties = {
            feature: 'share',
            channel: 'social',
        }

        let controlParams = {
            $android_url: 'https://play.google.com/store/apps',
            $ios_url: 'https://www.apple.com/app-store/',
            $deeplink_path: 'myapp://',
            joinCode: joinId,
            referring_user_id: userId?.toString(),
        }
        createJoinLink(`join-group/${joinId}`, options, linkProperties, controlParams)
            .then((url) => {
                setLink(`${url}?joinId=${joinId}`)
                setLoading(false)
            })
            .catch((e) => {
                setError(e.message)
                setLoading(false)
            })
    }

useEffect(() => {
if (joinId) {
generateDeepLink(joinId)
}
}, [joinId])

二、问题排查与修复方案

1. 基础配置修正

  • 补充iOS Scheme配置:当前infoPlist的CFBundleURLSchemes仅包含谷歌登录的scheme,缺少自定义的myapp,这是iOS警告/崩溃的核心原因。修改后:
    infoPlist: {
        CFBundleURLTypes: [
            {
                CFBundleURLSchemes: [
                    'com.googleusercontent.apps.xxx',
                    'myapp' // 添加自定义scheme
                ],
            },
        ],
        // 其他配置...
    },
    
  • 区分Branch环境Key:测试阶段改用key_test_xxx,避免生产环境的权限限制。
  • 插件版本兼容性:确认@config-plugins/react-native-branch版本与当前Expo SDK版本匹配,可参考插件文档的版本适配表。

2. 代码逻辑优化

  • 添加Branch初始化步骤:在App启动时完成Branch初始化,避免未初始化就调用生成函数:
    import branch from 'react-native-branch'
    
    useEffect(() => {
      const initBranch = async () => {
        try {
          await branch.initSession()
          console.log('Branch初始化成功')
        } catch (e) {
          console.error('Branch初始化失败:', e)
        }
      }
      initBranch()
    }, [])
    
  • 修正参数错误:
    • 移除controlParams中的$deeplink_path: 'myapp://',Branch会自动结合配置的scheme生成深度链接,手动设置会导致冲突。
    • 去掉生成链接后的?joinId=${joinId}拼接,joinCode已通过controlParams传递,Branch会自动将参数嵌入链接,重复拼接会导致解析错误。
  • 完善错误捕获:避免非Error类型的报错无法获取message:
    catch (e) {
      const errorMsg = e instanceof Error ? e.message : String(e)
      Alert.alert('Error', 'Unable to create deep link: ' + errorMsg)
      return null
    }
    

3. 崩溃问题排查

  • Android端:
    • 用adb logcat | grep Branch捕获实时崩溃日志,定位具体错误点。
    • 检查本地构建的AndroidManifest.xml(通过eas build --local生成),确认Branch的intent-filter是否被插件正确添加。
    • 确保Branch后台配置的Android包名与app.config.ts中的package字段一致。
  • iOS端:
    • 检查Branch后台配置的iOS Bundle Identifier是否与当前项目一致。
    • 确认ATS配置允许Branch域名(Expo默认允许,若有自定义ATS规则需添加branch.io例外)。

4. 测试流程

  • 使用自定义开发客户端(而非Expo Go)测试,Expo Go的scheme为exp+my_app,需额外在Branch后台配置该scheme才能正常测试。
  • 生成链接后先在浏览器打开,验证跳转逻辑是否符合预期,再在真机上测试App内深度链接解析。

内容的提问来源于stack exchange,提问作者Chinenye Ikpa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 13:35:11