iOS Linking getInitialURL() always null
🐛 Bug Report
I can't get the deep link url that was called when my app is started on iOS.
Tried with Linking.getInitialUrl() promise and by listener addEventListener('url'...)
None of these methods return the initial url.
When the app is in background, the listener addEventListener('url', ...) is working well, and we can get the url. But when the app is launched via a deeplink, we don't have it.
I tried on React Native 0.53.3 it's working via getInitialUrl() and listener.
I tried on React Native 0.59.4 not working.
To Reproduce
1. Add URL type to info.plist.
2. Add this to your AppDelegate.m :
#import <React/RCTLinkingManager.h>
...
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
3. and just to test, update your App.js to look like this :
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View,
Linking
} from 'react-native';
type Props = {};
export default class App extends Component<Props> {
componentDidMount() {
Linking.getInitialURL().then((url) => { console.log('1', url) })
Linking.addEventListener('url', this.handleOpenURL);
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL(event) {
console.log('2', event.url);
}
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
</View>
);
}
}
Expected Behavior
I expect to get the initial URL called via deeplink via getInitialUrl or listener handler.
Environment
info
React Native Environment Info:
System:
OS: macOS 10.14.4
CPU: (8) x64 Intel(R) Core(TM) i7-6820HQ CPU @ 2.70GHz
Memory: 205.05 MB / 16.00 GB
Shell: 5.3 - /bin/zsh
Binaries:
Node: 11.11.0 - /usr/local/bin/node
Yarn: 1.15.2 - /usr/local/bin/yarn
npm: 6.7.0 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5.2
Android SDK:
API Levels: 19, 23, 24, 25, 26, 27, 28
Build Tools: 23.0.1, 24.0.1, 25.0.0, 25.0.2, 25.0.3, 26.0.1, 26.0.2, 26.0.3, 27.0.3, 28.0.3
System Images: android-19 | Google APIs ARM EABI v7a, android-19 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom, android-25 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom
IDEs:
Android Studio: 3.3 AI-182.5107.16.33.5264788
Xcode: 10.2/10E125 - /usr/bin/xcodebuild
npmPackages:
react: 16.8.3 => 16.8.3
react-native: 0.59.4 => 0.59.4
npmGlobalPackages:
create-react-native-app: 1.0.0
react-native-git-upgrade: 0.2.7
Thanks for your time ;)
same here https://github.com/dmitri-wm/deep-linking-sample sample fresh installed app with deep linking setup for IOS @matthieupinte did you find workaround?
React native 0.58.5 works fine
@dmitri-wm No, I don't have more information... and we can't go back to 0.58.5 because of Android requirements.
Android has supported 64-bit CPUs since 5.0 Lollipop, and the Play Store in 2017 announced that apps using native code must provide a 64-bit version in light of future chips that only support 64-bit code.
And I heard somewhere that only RN 0.59.x has support for Android 64-bit...
On Android getInitialURL() works as expected, the issue is on iOS, url always comes up null. react-native 0.59.x
I just encountered the same issue. getInitialURL was always null on iOS with react-native 0.59.x. I downgraded to 0.58.5 and it works as expected.
Have the same problem on RN 0.59.
npmPackages:
react: 16.8.3 => 16.8.3
react-native: 0.59.4 => 0.59.4
Hi, In my project with react-navigation 3.9.1 and react-native 0.59.5 deep linking don't work on ios simulator when "Debug JS remotely" is enabled, but work well when the debug is disabled. Could you try getInitialURL() without debug mode ?
I confirm getInitialURL() is always null when Debug JS remotely is enabled ( I use React Native debugger 0.9.7)
Hi, I have same problem in IOS. (Working only when remote debugging is disabled)
react: 16.8.3
react-native: 0.59.5 (and 0.59.8)
Xcode:
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
BOOL handledFB = [[FBSDKApplicationDelegate sharedInstance] application:application
openURL:url
sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey]
annotation:options[UIApplicationOpenURLOptionsAnnotationKey]
];
BOOL handleCustom = [RCTLinkingManager application:application openURL:url options:options];
return handledFB || handleCustom;
}
I can second this. Working on Android, not iOS
"react": "16.8.3",
"react-native": "0.59.3",
Edit: Can also confirm that its only when remote debugging is enabled.
Hi, In my project with react-navigation 3.9.1 and react-native 0.59.5 deep linking don't work on ios simulator when "Debug JS remotely" is enabled, but work well when the debug is disabled. Could you try getInitialURL() without debug mode ?
I also confirm : Linking.getInitialURL() will return your url once Debug JS Remotely is disabled
Confirm Linking.getInitialURL() and Linking.addEventListener('url', () => {}) not work
- iOS
- 0.59.5
- Simulator
- Universal Link
#UPDATE: my mistake. I solved it by adding this method to AppDelegate.m
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
Confirmed Linking.getInitialURL() always returns null when remote debug is enabled. iOS 0.59.8 Simulator Universal Link
Strange enough. Android simulator, android real device works. Real iPhone works. Simulator only works when debugging disabled.
Info React Native Environment Info: System: OS: macOS 10.14.4 CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz Memory: 74.79 MB / 16.00 GB Shell: 5.3 - /bin/zsh Binaries: Node: 10.10.0 - /usr/local/bin/node Yarn: 1.15.2 - /usr/local/bin/yarn npm: 6.7.0 - /usr/local/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman SDKs: iOS SDK: Platforms: iOS 12.2, macOS 10.14, tvOS 12.2, watchOS 5. IDEs: Android Studio: 3.1 AI-173.4720617 Xcode: 10.2.1/10E1001 - /usr/bin/xcodebuild npmPackages: react: 16.8.3 => 16.8.3 react-native: 0.59.5 => 0.59.5 npmGlobalPackages: react-native-cli: 2.0.1 react-native-git-upgrade: 0.2.7
I can also confirm it's not working on iOS when remote debugging is enabled.
"react": "16.8.3",
"react-native": "0.59.3",
I checked in my application using [email protected] and Xcode 10.2.1.
It works. Try it:
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:app openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
}
Update: I see what problem exist only when Debug JS Remotely enabled. Suggestion: Use Reactotron for debug this. Also I think it can be related with this commit.
It also happens when Live Reload is active or with any instance that refreshes bundled JS. To test is needed to be disconnected from debug and reload [email protected] && Xcode 10.2.1
Same problem here
can you try ?
getInitialUrl = async () => { const url = await Linking.getInitialURL() return url }
Yeah, pretty annoying issue, does anybody tracked commit, that introduced this regression?
@IljaDaderko I see You fixed universal links recently, maybe some ideas on where it has been introduced?
@todorone hard to tell. My change didn't touch that area.
For iOS native code is defined here https://github.com/facebook/react-native/blob/master/Libraries/LinkingIOS/RCTLinkingManager.m#L147-L161
And JavaScript implementation is here https://github.com/facebook/react-native/blob/master/Libraries/Linking/Linking.js#L86-L92
Judging by what I can see, these are being worked on right now, there was also change to use TurboModules, perhaps that affected it somehow?
Same here, also getting null back from getInitialURL on iOS.
Edit: Seems to work but only when debug/live reload is not active.
Any updates on this issue? Can confirm that is not working on react-native: 0.59.10, iOS + debugging on As a workaround, turn off debugging and use Reactotron or maybe Alert dialog to show urls.
having the same issue with RN 60.4, works if turn off remote debugger
on 0.59.10, tried without the remote debugger, no live reload.
Unfortunately, Linking.getInitialURL() is not working for me.
Linking.addListener is working fine... but I need Linking.getInitialURL...
getInitialUrl() does not work on both ios & android even if I turn off remote debugging mode:
[email protected]
[email protected](10E125)
Same here. Not working on Anroid with react-native: 0.61.2
Sames goes for me, does not work without debug mode
getInitialURL is null on iOS even when not remote debugging or live loading when the app is returning from a dead state opening a deeplink. Hence deeplinks from dead state are broken in the wild.
application openURL gets the correct url in Xcode.
"react-native": "0.59.9",
"react": "16.8.3",
Xcode 11.1.
I thought we were having this same issue until I realized it was because our RCTBridge was being torn down and re-initialized between the application launching and getInitialURL being called.
If you look at how RCTLinking works, it fetches the initialURL from the bridge (which is set up when the application launches). If the bridge is re-initialized, so is the state it collected when it was first started, so it returns null. If the bridge does not re-initialize between app launch and getInitialURL (no JS debugging session, etc), it should retain the value it collected at launch.
I recommend checking to see if your RCTBridge is getting invalidated and then re-initialized (as it does when debugging / live-loading). You can look for a line like this in your Xcode console:
Invalidating <RCTCxxBridge: 0x7fb6e7708810> (parent: <RCTBridge: 0x60000341ee60>, executor: RCTWebSocketExecutor)
If you see that, you likely need to figure out why your bridge is being torn down (and losing your launchOptions which contains the initialURL).
You can confirm that this is an issue with the bridge (on iOS) by doing the following:
Add this to the very top of your AppDelegate's application:didFinishLaunchingWithOptions:
[[[UIAlertView alloc] initWithTitle:@"AppDelegate"
message:[NSString stringWithFormat:@"%@", launchOptions]
delegate:nil
cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
And this to RCTLinkingManager's RCT_EXPORT_METHOD(getInitialURL (RCTPromiseResolveBlock)resolve reject:(__unused RCTPromiseRejectBlock)reject)
[[[UIAlertView alloc] initWithTitle:@"getInitialURL"
message:[NSString stringWithFormat:@"%@", self.bridge.launchOptions]
delegate:nil
cancelButtonTitle:@"cancel" otherButtonTitles:nil] show];
Now you won't need to be connected to the debugger to see what the application sees when it launches vs. what RCTLinking fetches from those options.
Also keep in mind that if you're using a push notification service with their own SDK, they might not be using the UIApplicationLaunchOptionsURLKey to store the initial URL, so you may have to dig it out of the UIApplicationLaunchOptionsRemoteNotificationKey instead 🙃