-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Universal links callback doesn't work if launching closed app #11191
Comments
Thanks for providing all of this detailed information! I am still somewhat confused as to what the problem is. You can't add an event listener for "url" in a componentDidMount? That seems intentional - I would expect an event that opens the whole app to occur before a component mounted. Or am I misunderstanding what's going on here? |
No no, I When app is in the background and if I hit an universal link on some website, since app is already started and react modules loaded, app gets "opened" (not really opened but rather just foregrounded), mechanism behind it catches the URL, fires But case in which I don't get this if I repeat this scenario, but with app completely closed (not in background, not running/killed). How universal links are working in native iOS app is that this method from I was kinda expecting that this And your expectation that event that opens the whole app happens before a component is mounted is correct. That whole mechanism is controlled by iOS and end effect is that it opens the app and triggers Looking forward to hear your thoughts on this and do you think that this URL info should be delivered to JavaScript Cheers |
@uerceg We got this working in your app by using this:
This way you get the url the app startet initially with after that you use the listener to listen for url events while the app is running. |
And thanks for the answer. This is actually what I am using for the Android app in AndroidcomponentDidMount() {
const url = Linking.getInitialURL().then(url => {
if (url) {
// Do stuff with URL
}
});
} That's the only thing I have set up for Android app in this works in iOScomponentDidMount() {
Linking.addEventListener('url', this.handleDeepLink);
Linking.getInitialURL().then((url) => {
if (url) {
this.handleDeepLink({ url });
}
})
} componentWillUnmount() {
Linking.removeEventListener('url', this.handleDeepLink);
} handleDeepLink(url) {
// Do stuff with URL
} For iOS I actually need this kind of setup in order to support In scenario in which I am So for iOS, only combination of these two is providing me the URL in both scenarios (on different places, but it does provide). My question now is: Is this intended to be like this or should it be exactly the same like in Android? Thanks in advance for your answer. Cheers |
I think the different behavior on android is because android by default will open a new instance of your app when you hit a deeplink. You can disable this behavior by setting a flag in your Manifest file so it opens only one instance.
…Sent from my iPhone
On 5 Dec 2016, at 11:23, Uglješa Erceg ***@***.***> wrote:
Hi @philipheinser
And thanks for the answer. This is actually what I am using for the Android app in index.android.js file. This is now really really interesting. Here's how it looks like for me now:
Android
componentDidMount() {
const url = Linking.getInitialURL().then(url => {
if (url) {
// Do stuff with URL
}
});
}
That's the only thing I have set up for Android app in this works in both scenarios - if I open closed app with a click on a link which contains scheme which my app handles or if I "open" backgrounded app. Regardless of scenario, url is being obtained properly in this method and everything works like a charm.
iOS
componentDidMount() {
Linking.addEventListener('url', this.handleDeepLink);
Linking.getInitialURL().then((url) => {
if (url) {
this.handleDeepLink({ url });
}
})
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleDeepLink);
}
handleDeepLink(url) {
// Do stuff with URL
}
For iOS I actually need this kind of setup in order to support both scenarios.
In scenario in which I am opening closed app with the link, mechanism that gets me URL delivered once the app starts is this thing which you have suggested in your answer from above. Indeed, I am getting the URL in this method. But, if I try to open the app which is running in the background with the link, this method does not get called. In this scenario, my handleDeepLink gets called as part of this subscription mechanism to url event.
So for iOS, only combination of these two is providing me the URL in both scenarios (on different places, but it does provide).
My question now is: Is this intended to be like this or should it be exactly the same like in Android?
Thanks in advance for your answer.
Cheers
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.
|
Aham, you mean the |
Indeed, if I pick launching activity to have Okay, I guess that this solves all the issues I had with this topic. Thank you very much for your answers and help! Cheers |
Am facing an issue slightly similar to @uerceg .For Android, Deeplinking is working fine in both scenarios and come to IOS Not working as expected.That is if the app is not yet opened Now clicking on the link in mail app opened, getting the URL by using Linking.getInitialURL() Method in my component and if the app is running in the background calling the same Linking.getInitialURL() method but not returning any url.it gives a null.Can you guys help me out of this. here is my code componentDidMount() {
} componentWillUnmount() { // C |
Description
I am testing how universal links are working with react native. I have set up everything for the universal links handling in native iOS Xcode project:
applinks
parameter which opens my appLinking
project for which I have properly set up the header search paths and Xcode project compiles properly.AppDelegate.m
methods (I say both, because I am also testing custom URL scheme functionality in pre iOS 9 devices, but let's keep this issue tied to universal links only) and they look like this:index.ios.js
I am subscribing tourl
event to get info about the link which opened my app like this:I have tested two scenarios in which I am opening my app with click on the universal link:
In 1st scenario, everything works like a charm. Clicking the universal link is starting my app (pretty much bringing it back to foreground since it was backgrounded),
_handleOpenURL
method gets called and I nicely get info about the universal link as part of theevent.url
object. Lovely.In 2nd scenario upon clicking on link app gets opened, which is fine. But,
_handleOpenURL
method is never triggered after app starts.Reproduction
_handleOpenURL
method gets called (it doesn't and it should, or at least I guess it should).Solution
As far as I investigated, first problem I have encountered in this scenario your
RTCLinkingManager
class method gets called (https://github.com/facebook/react-native/blob/master/Libraries/LinkingIOS/RCTLinkingManager.m#L52) and seems like you're posting the notification in this method before yourRTCLinkingManager
instance subscribes to that event in this line https://github.com/facebook/react-native/blob/master/Libraries/LinkingIOS/RCTLinkingManager.m#L24.Since it seems that
RCTLinkingManager
instance exists as a singleton in your framework, I have adapted it a bit to solve this problem by adding small queueing mechanism which will gather notifications if object instance is not subscribed toRCTOpenURLNotification
and post notifications later once subscription happens. That worked well, I managed to enableRCTLinkingManager
not to miss these notifications but then I got into second issue.With these changes in framework, once opening the app with the click on the universal link,
RCTOpenURLNotification
notification was being announced so thatRCTLinkingManager
receives it, but once that was tried to be propagated up to JavaScript (which happens in this line: https://github.com/facebook/react-native/blob/master/Libraries/LinkingIOS/RCTLinkingManager.m#L67), I figured out that app itself still didn't manage to subscribe tourl
event. I got this warning:which happens in here:
react-native/React/Modules/RCTEventEmitter.m
Line 54 in 9ee815f
Further investigation guided me to the conclusion that after event towards JavaScript part is sent with this new queueing mechanism I added,
startObserving
gets called before_listenerCount
is incremented thus making JavaScript to miss this message from native part althoughcomponentDidMount()
was already executed and JavaScript callback is ready to receive this event. Because of this, I have added small changes toRCTEventEmitter.m
to support this special case now.You can check all the changes I did in here: https://github.com/uerceg/react-native/tree/deep-linking-fix
I assume that this is not the perfect solution, but this fixes the issue for me in this case. Since I am not aware of all aspects of your framework, I am not sure if this might cause issues on some other place, so looking forward to hear some comment from you on this.
Looking forward in solving this issue and enabling this feature in react native.
Cheers
Additional Information
The text was updated successfully, but these errors were encountered: