与此同时,我自己找到了一个解决方案,可能不太干净。
在App.js中,我这样指定我的initialRouteName:
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import Home from './screens/Home';
import Form from './screens/Form';
import {Linking, Platform} from 'react-native';
import React from 'react';
function getRoute() {
let route = "";
Linking.getInitialURL().then(url => {
route = url;
})
if (route === 'playgroundapp://form') {
return 'Form';
} else {
return "Home"
}
}
const AppNavigator = createStackNavigator(
{
Home: { screen: Home },
Form: { screen: Form },
}, {
initialRouteName: getRoute()
});
export default createAppContainer(AppNavigator);
我希望能够从我的iOS小部件深入链接到我的React Native应用程序。当应用程序在后台运行时,链接可以正常工作,并导航到正确的页面。但是当该应用被终止时,它只会打开该应用,而不再导航到正确的页面。
我遵循了本教程:https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e
[根据官方文档进行了一些调整:https://facebook.github.io/react-native/docs/linking
AppDelegate.m
#import "AppDelegate.h"
#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTLinkingManager.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}
@end
App.js
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import Home from './screens/Home';
import Form from './screens/Form';
const AppNavigator = createStackNavigator({
Home: { screen: Home },
Form: { screen: Form },
});
export default createAppContainer(AppNavigator);
Home.js
import React, {Component} from 'react';
import {
Linking,
Platform,
Text,
View,
} from 'react-native';
import Form from './Form';
export default class Home extends Component {
componentDidMount() {
if (Platform.OS === 'android') {
Linking.getInitialURL().then(url => {
this.navigate(url);
});
} else {
Linking.addEventListener('url', this.handleOpenURL);
}
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL = event => {
console.log(event.url)
this.navigate(event.url);
};
navigate = url => {
const {navigate} = this.props.navigation;
const route = url.replace(/.*?:\/\//g, '');
const routeName = route.split('/')[0];
if (routeName === 'form') {
navigate('Form');
}
};
}
render() {
return (
<View style={styles.container}>
<Text style={styles.h1}>Playground</Text>
</View>
);
}
}
因此,从我的小部件中,我这样链接到应用程序:extensionContext?.open(URL(string: "playgroundapp://form")! , completionHandler: nil)
为什么当应用程序不在后台运行时,它为什么不起作用?我发现了一些类似的问题,但没有对我有用或过时的答案。
如果对于iOS,您已按以下方式处理了RCTLinkingManager
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<NSString *, id> *)options
{
BOOL handled = [[RNFirebaseLinks instance] application:application openURL:url options:options];
if(!handled)
{
handled = [RCTLinkingManager application:application openURL:url options:options];
}
return handled;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
BOOL handled = [[RNFirebaseLinks instance] application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
if(!handled)
{
handled = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}
return handled;
}
并且您已按照React Native linking中所述的步骤进行操作。
_dynamicLinkListener; // variable defined to hold listeener instance
componentDidMount() {
this.setUpDynamicLink();
this.setUpDeepLink();
}
componentWillUnmount() {
this.cleanUpDynamicLink();
this.cleanUpDeepLink();
}
setUpDynamicLink = () => {
// will work when link is opening the app
Firebase.links()
.getInitialLink()
.then((url) => {
this.handleURL(url);
});
// listener will work when app is already opened
this._dynamicLinkListener = Firebase.links().onLink((url) => {
this.handleURL(url);
});
}
setUpDeepLink = () => {
// will work when link is opening the app
Linking.getInitialURL().then(url => {
this.handleURL(url);
});
// listener will work when app is already opened
Linking.addEventListener('url', this.handleURL);
}
cleanUpDynamicLink = () => {
this._dynamicLinkListener();
}
cleanUpDeepLink = () => {
Linking.removeEventListener('url', this.handleURL);
}
handleURL = (event) => {
let url = "";
if (!event) {
return "";
}
if (typeof event == 'string') {
url = event;
} else {
url = (event.url) ? event.url : "";
}
if (!url) {
return;
}
console.debug(url);
}
那么你很好。当应用程序处于foreground
,background
但不处于killed
状态时,我得到了深层链接回调。
禁用应用程序的调试,并使用某些Alert
显示url
,而不使用控制台输出。启用调试时,Linking
有问题。之后,我可以在警报中看到网址。
上面提到的代码还具有用于动态链接的Firebase
实现,您可以删除不需要的代码。