加入视频通话最快捷的方法是通过点击专属链接(unique link)。下面这个教程会教大家如何使用 React Native 框架下的通用链接打开用 React Native UIKit 搭建的视频通话或直播推流 app。
想了解更多关于 React Native UIKit 的信息,可查看 GitHub。点击 这里 获得本文项目的完整版。
前期准备
- Node.js LTS
- Expo CLI (
npm i -g expo-cli
) - 了解 React Native 和 Expo 的基础知识
为了方便大家快速了解基础样板,我用 expo-cli
创建了一个 tabs (TypeScript)
模板项目。大家可以跟着我逐步操作,首先,执行 expo-cli init
,看到选择模板的提示时,选择 tabs 选项。所有使用 react-navigation 库的 app 都可以采取以上步骤。
要在 Expo 项目中使用 UIKit,需要安装 expo-dev-client
包(expo install expo-dev-client
)和声网Agora Native UIKit 包(npm i agora-rn-uikit react-native-agora
)。
用 Expo 使用链接
有两种链接到 app 的方式:深度链接和通用链接。深度链接类似这个链接:exp://com.uikit/screen-one?data=hello
。深度链接不使用 http/https 协议,它使用的 scheme。Expo app 的 scheme 被设置为 exp
,大家可以根据自己的 app 作出相应改变,这里我们使用 uikit://
。
通用链接是 app 支持的常见 web URL。例如,https://myapp.com/screen-one?data=hello
这样的 URL 可以在网站中打开,也可以直接在支持该链接的 app 中打开。我们接下来会讨论如何使用深度链接和通用链接。如果对本文的理念有任何疑惑,可以查看 Expo docs 资源库。
更新 app.json
文件夹,为通用链接定义支持,使用 example.com
作为主机名:
"scheme": "uikit",
...
"ios": {
"supportsTablet": true
"supportsTablet": true,
"bundleIdentifier": "com.ekaansh.uikitlink",
"infoPlist": {
"LSApplicationQueriesSchemes": ["uikit"],
"NSCameraUsageDescription": "camera perm",
"NSMicrophoneUsageDescription": "mic perm"
},
"associatedDomains": ["applinks:example.com"]
},
...
"android": {
...
"package": "com.ekaansh.uikitlink",
"intentFilters": [
{
"action": "VIEW",
"data":{
"scheme": "https",
"host": "*.example.com"
},
"category": [
"BROWSABLE",
"DEFAULT"
]
}
]
},
保存更改,执行 expo prebuild
。这样可以改变本地项目文件(如 AndoidManifest.xml
和 info.plist
),添加域名配置。
设置域名
IOS 系统的 AASA 配置
要在 IOS 系统上使用通用链接,必须首先从 web 服务器提供一个 Apple App Site Association (AASA)文件,以验证域名是否属于本人。该文件必须由 /.well-known/apple-app-site-association
提供(不能延展)。在 CDN 上添加合适的标头,确保这个文件以 Content-Type=application/pkcs7-mime
为标头。
示例 AASA 文件如下:
{
"applinks": {
"apps": [],
"details": [{
"appID": "<APPLE_TEAM_ID.APP_BUNDLE_ID>",
"paths": ["*"]
}]
}
}
可以用下面示例中的 vercel.json 文件给 vercel 设置标头:
{
"headers": [{
"source": "/apple-app-site-association"
"headers" : [{
"key" : "Content-Type",
"value" : "application/pkcs7-mime"
}]
}]
}
如果你想获得更多 AASA 的 format,可查看 Apple 文档。
在安卓系统中验证域名(可选)
点击通用链接时,默认会出现选择 app 的对话框。如果不想弹出选择 app 的对话框,并且让链接总是打开特定 app,必须在 /.well-known/assetlinks.json
上发布一个 JSON 文件,说明安卓 app ID 和 app 应打开的链接,更多信息请查看安卓文档 。
设置链接
更新 navigation/LinkingConfiguration.tsx
文件中的 prefix 来支持通用链接:
prefixes: [‘https://example.com', Linking.createURL(‘/’)]
这样,app 路由可以同时处理通用链接和深度链接。
现在,修改第二屏幕(./screens/TabTwoScreen.tsx
)以打开 UIKit,把该频道保存为状态变量。我们会在 URL 中添加一个监听器,从查询中提取频道并更新状态。
import { StyleSheet } from 'react-native';
import AgoraUIKit from 'agora-rn-uikit';
import * as Linking from 'expo-linking';
import { Text, View } from '../components/Themed';
import { useEffect, useState } from 'react';
export default function TabTwoScreen() {
const [channel, setChannel] = useState('')
Linking.addEventListener('url', (u) => {
let query = Linking.parse(u.url).queryParams
if(query.channel) {
setChannel(query.channel)
}
})
...
然后,创建 useEffect
钩子,当通过通用链接打开 app 时,用useEffect
钩子从查询中获取频道。接下里,使用 getInitialUrl
和 parse
方法提取频道,更新状态:
...
useEffect(() => {
const fn = async () => {
let link
link = await Linking.getInitialURL();
if (link) {
let query = Linking.parse(link).queryParams
if(query.channel) {
console.log('joining channel', query.channel)
setChannel(query.channel)
}
}
}
fn()
}, [])
...
最后,渲染 UIKit。记得一定要把你的 App ID 添加到 rtcProps
。
...
return (
<View style={styles.container}>
{channel ?
<AgoraUIKit
styleProps={{ UIKitContainer: { flex: 1, height: '100%', width: '100%', backgroundColor: '#ff00ff' } }}
rtcProps={{ appId: '<YourAgoraAppID>', channel: channel }}
callbacks={{EndCall: () => {setChannel('')}}}
/> :
<Text> Didn't get Channel </Text>
}
</View>
);
}
const styles = StyleSheet.create({
container: {flex: 1,alignItems: 'center',justifyContent: 'center'},
});
可以使用 expo 的 Linking
,调用深度链接 uikit://two?channel=test
,从而在 app 内打开 UIKit 屏幕。我添加了一个 <Text>
组件以导航到 ./screens/TabOneScreen.tsx
中的 UIKit:
const createLink = () => {
const ts = new Date().getTime()
let link = Linking.createURL(`/?channel=${ts}`)
return link
}
生成链接
调用 JavaScript 中的 Date
对象来使用当前时间戳,这是生成专属链接的速成法。可以用下面这个简易函数创建一个聊天室:
const createLink = () => {
const ts = new Date().getTime()
let link = Linking.createURL(`/?channel=${ts}`)
return link
}
总结
使用 React Native 和 Expo 设置安卓和 iOS 系统都兼容的通用链接可不容易,本教程教给大家的是一个相对较容易的方法~
如果想了解更多信息,可以参考 Expo 和 React Navigation 文档。
如果你在学习这篇教程或使用声网 React Native UIKit 时遇到任何问题,欢迎随时在GitHub 仓库提出功能需求或报告 bug。
原文作者:Ekaansh Arora
原文链接:https://www.agora.io/en/blog/use-meeting-urls-for-an-agora-video-call-with-the-react-native-uikit/