原文地址:http://liu-hang.cn/2019/06/04/183-RN-open-app-except-page-from-webpage-or-otherapp/html
我使用 react-navigation 来管理路由,react-navigation自己支持 Deep Linking,可是我使用 react-navigation-redux-helpers 组件将路由也封装在 redux 下了,因此 react-navigation 自己的 deep-linking 功能就不能用了,在 react-navigation-redux-helpers 的 issue 下面我找到了其余的解决方案。react
// 为了监听APP从后台唤起的行为,因此我选择使用 AppState 接口,而后使用 Linking 获取 url,而后将获取到的地址初步解析提交给 LinkRoutes 方法
import { Linking, AppState } from 'react-native'
import LinkRoutes from './src/routes/linkRoutes'
...
componentDidMount(){
AppState.addEventListener('change', this._handleAppStateChange)
}
componentWillUnmount(){
AppState.removeEventListener('change', this._handleAppStateChange)
}
_handleAppStateChange = (nextAppState) => {
if(nextAppState==='active'){
Linking.getInitialURL().then(res => {
if(!!res){
LinkRoutes(res.split(':/')[1])
}
})
}
}
...
复制代码
// LinkRoutes 的实现,使用了 path-parser 作 url 解析,而后维护 APP 内须要跳转的页面的列表,而后调用 react-navigation 的navigate 方法,使用 dispatch 实现跳转到指定页面
import PathParser from 'path-parser'
import { NavigationActions } from 'react-navigation'
import store from '../reducers'
import _ from 'lodash'
const paths = [
{
routeName: 'Page',
path: new PathParser('/page')
}
]
const findPath = url => {
let idx = _.findIndex(paths, p => {
return p.path.test(url)
})
return idx > -1 ? paths[idx] : false
}
export default url => {
const pathObj = findPath(url)
if(!pathObj) return
const navigateAction = NavigationActions.navigate({
routeName: pathObj.routeName,
params: pathObj.path.test(url)
})
store.dispatch(navigateAction)
}
复制代码
// 修改 AppDelagate.m,添加
#if __IPHONE_OS_VERSION_MAX_ALLOWED > 100000
// 最新版本系统回调
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url options:options];
if (!result) {
// 其余如支付等SDK的回调
}
return result;
}
#endif
// 支持全部iOS系统,此方法在swift4.1(Xcode 9.3)已废弃,Objective-C项目不影响。
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url sourceApplication:sourceApplication annotation:annotation];
if (!result) {
// 其余如支付等SDK的回调
}
return result;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url];
if (!result) {
// 其余如支付等SDK的回调
}
return result;
}
复制代码
而后,修改 Url Types,添加 myappandroid
测试指令git
xcrun simctl openurl booted myapp://
复制代码
iOS 使用模拟器是 Linking 捕捉不到 url,因此我是打包后在手机上测试的github
在 .MainActivity 下添加配置,还能够设置host以及path等,可是由于我是经过RN作解析,这里就不加了web
<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="myapp" />
</intent-filter>
复制代码
测试指令shell
adb shell am start -W -a android.intent.action.VIEW -d "myapp://" com.myapp
复制代码