Possible solution
I found a solution myself in the meanwhile, probably not so 'clean'.
In App.js I specify my initialRouteName like this:
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);
Question
I want to be able to deep link to my React Native application from my iOS widget.
Linking works fine when the app is running in the background, it navigates to the correct page. But when the app is killed, it only opens the app, but does not navigate to the correct page anymore.
I followed this tutorial: https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e
With a few adjustments from the official documentation: 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>
);
}
}
So from my widget I link to the app like this:
extensionContext?.open(URL(string: "playgroundapp://form")! , completionHandler: nil)
Why doesn't it work when the app is not running in the background? I found a few similar questions, but no answers that worked for me or which were outdated.