React native , open a url in webview - react-native

Im not familiar with ios app development , but is there a simple way to open a url in myApp's webview , in a simple way ?
Im looking for the same behaviour of facebook's app. once you click on http link , a webview is opened by the app.
clickHndlr: function() {
someNativeOrNonNativeModule.openUrl('http://google.com');
}
<Text onClick={this.clickHndlr}>google</Text>
Thanks.

Hi You can use WebView component in reactnative.
var {
....,
WebView,
} = React;
and in initial state give a default url or no url
getInitialState: function() {
return {
url: '', // or default url
yourInitialStates: 'value',
};
},
and then at inside render add component
<WebView ....your styles, properties
url={this.state.url}
/>
Now add your code
clickHndlr: function() {
this.setState({url:'http://google.com'});
}
This will give the result

Related

how to perform deep linking on React Native Navigation

I have a request to implement deep linking in our React Native application whereby clicking a link will take them directly into the installed app. I am able to successfully direct them to the app. However, it must navigate to a certain page.
To address the problem, I use the code below. If there is a better approach to handle the problem, I would appreciate it if you could share it with me!
const useUrl = async () => {
const url = await Linking.getInitialURL();
if (url) {
Navigation.push(componentId, {
component: {
name: 'screen',
},
});
}
};
react-native and react-navigation both handle this as part of a feature set within the "Linking" that they offer. I can't find a way to handle that with React Native Navigation?
For me, I just add path to my stack navigator in react native like this
Product: {
screen: ProductScreen,
path: 'product/:productId'
},
and make sure your web that handle deep link have a similar path in routing. For example https://yourweb.com/product/:productId
And in your screen file, add this
useEffect(() => {
Linking.addEventListener('url', _handleDeepLink)
return () => {
Linking.removeEventListener('url', _handleDeepLink);
}
}
const _handleDeepLink = (event) => {
if (event) {
const route = event.url.replace(/.*?:\/\//g, '')
const id = route.match(/\/([^\/]+)\/?$/)[1];
if (id !== undefined) {
// do your code here if screen just opened via deep link
}
}
}

Deep linking - doesn't work if app is closed

I'm implementing deep linking with expo in my react native app. I've managed to do it using this code with this tutorial and this documentation for adjusting it to my nested stacks:
const linking = {
prefixes:[prefix],
config: {
screens: {
Drawer: {
screens: {
Tabs: {
screens: {
Profile:"profile"
}
}
}
},
}
}
}
return (
<NavigationContainer linking={linking}>
<RootStackScreen actions={actions} showLoader={showLoader} user={user} {...props} />
</NavigationContainer>
)
}
If I use myscheme://profile it works as expected, but only if the app is opened in the background. When the app is closed, then it just open it in my initial home screen, I tried googling and searching but couldn't find any explanation that fits what I did. I also tried adding the getInitialRoute function to linking, which triggers when the app was closed and was opened from a deep link, but couldn't figure how I can use it to activate the navigation.
async getInitialURL() {
const url = await Linking.getInitialURL(); // This returns the link that was used to open the app
if (url != null) {
//const { path, queryParams } = Linking.parse(url);
//console.log(path,queryParams)
//Linking.openURL(url)
return url;
}
},
I suppose that you confirmed that your function getInitialURL is getting called when your app is launched? Also, the commented code within the if (url != null) { aren't supposed to be commented right?
If the above is fine then the issue could be related to the debugger being enabled. As per React Native's documentation (https://reactnative.dev/docs/linking#getinitialurl):
getInitialURL may return null while debugging is enabled. Disable the debugger to ensure it gets passed.
I was experiencing this same issue and doing the following helped me
From the component at the root of your navigation stack, where you configure deep linking, add the following code:
const ApplicationNavigator = () => {
useEffect(() => {
// THIS IS THE MAIN POINT OF THIS ANSWER
const navigateToInitialUrl = async () => {
const initialUrl = await Linking.getInitialURL()
if (initialUrl) {
await Linking.openURL(initialUrl)
}
}
navigateToInitialUrl()
}, [])
const linking = {
prefixes: ['<your_custom_scheme>://'],
config: {
/* configuration for matching screens with paths */
screens: {},
},
}
return (
// Your components/navigation setup
)
}
So apparently, your app received the url but somehow "uses" it to wake the app up from background. When it is in the foreground, the useEffect runs and uses the URL to navigate to the intended screen.
PS: Make sure that your linking tree matches your app tree
There are a couple of things you can check.
Verify that the structure for linking.config matches your navigation structure. I've had a similar issue in the past, and resolved it by making sure my config structure was correct.
Ensure that the linking object is setup properly. Refer to the docs to verify. From the looks of it, the linking object you've showed doesn't have the getInitialURL property in it.
Confirm that you've setup the native side of things as documented.
Hopefully something works out! Let me know if it doesn't. 🙂
Based on https://documentation.onesignal.com/v7.0/docs/react-native-sdk#handlers
Deep linking in iOS from an app closed state
You must be Modify the application:didFinishLaunchingWithOptions in your AppDelegate.m file to use the following:
NSMutableDictionary *newLaunchOptions = [NSMutableDictionary dictionaryWithDictionary:launchOptions];
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
if (remoteNotif[#"custom"] && remoteNotif[#"custom"][#"u"]) {
NSString *initialURL = remoteNotif[#"custom"][#"u"];
if (!launchOptions[UIApplicationLaunchOptionsURLKey]) {
newLaunchOptions[UIApplicationLaunchOptionsURLKey] = [NSURL URLWithString:initialURL];
}
}
}
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:newLaunchOptions];
also in reactnavigation:
https://reactnavigation.org/docs/deep-linking/
const linking = {
prefixes: ["https://example.com", "example://"],
config,
async getInitialURL() {
const url = await Linking.getInitialURL();
if (url != null) {
return url;
}
},
};
<NavigationContainer linking={linking}>
...
</NavigationContainer>
I was having the same problem. In iOS(flutter build) I solved this by adding "Content Available." The article is here: Apple Content Available Document. I am using OneSignal so in the api I added that field. Now even if the app is forced closed it awakes and deep links work. For Onesignal I had to use "content_available" : true. The complete Onesignal postman code is:
{
"app_id": "1234",
"included_segments": ["Test"],
"content_available" : true,
"contents": {
"en": "Hi"
},
"data": {
"dynamic_link": "https://google.com"
},
"headings": {
"en": "Testing"
}
}

How do i get a user to open my react native app from a text message (basically i need to make share profile in my react native app)

## import ##
import {Share, Button } from 'react-native'
Function to share. This function need to have link to a page of this app which will be sent to another user, who can see the same page if the app is installed, and if it's not, then it must be redirected to play store.
const onShare = async () => {
try {
const result = await Share.share({
message:
'React Native | A framework for building native apps using React https://play.google.com/store/apps/details?id=com.test',
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
// shared with activity type of result.activityType
} else {
// shared
}
} else if (result.action === Share.dismissedAction) {
// dismissed
}
} catch (error) {
alert(error.message);
}
};
button:
<Button onPress={onShare} title="Share" />
To add a feature to open the app from the link then we should have to implement the firebase dynamic-link library and use it in our app navigation to check whether we have received the link in our app then we have to set the initial route to open a specific screen otherwise fallback to play store link if app not installed the fallback will auto handled by the dynamic-link library.
checkout the doc.
https://rnfirebase.io/dynamic-links/usage

Unable to do any other action than "alert" when triggering the click event on Highcharts (React Native)

Im using Highcharts in React Native
For a bar chart I have the following click event defined:
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: () => {
alert("Clicked!");
}
}
}
}
}
I would like to setState on the click event to be able to display the elements of the clicked bar, but I cant even console.log() on it.
I checked examples and all I saw was "alerts" inside the callback function.
Any ideas?
Thanks!
It's working now! The problem was the following (as I understand it):
Highcharts for React Native renders the chart within a WebView. For this reason only alerts can be made.
If you try to console.log directly (or call a method or anything else) it won't work because it's not getting to React Native, it's in the webview.
So the question was: how to pass data from the webview to React Native? And the answer iiiiis... window.postMessage()
Like this:
In the config object (passed to the chart):
plotOptions: {
series: {
point: {
events: {
click: function() {
window.postMessage( //data you want to send to react native )
}
}
}
}
}
Pass the onMessage method as prop to the ChartView such as you would pass it to a WebView (https://facebook.github.io/react-native/docs/webview#onmessage)
<ChartView style={{ height: 300 }} config={conf} onMessage={m => onMessage(m)} options={options}></ChartView>
Just now you can console.log, setState, or do anything in your react native onMessage function
onMessage = (m) => {
console.log(m.nativeEvent.data)
}
And that's it, now I can click a bar and change the state of my component ;)
Only alert supports since Highcharts is rendering inside Webview.
so for this
let data = "ClickedWebView" ;
Any message it could be *
Note : window.postMessage will not work .
WebView version > 5 gives us this modified function,
write the following code in config as
plotOptions: {
series: {
point: {
events: {
click: function() {
window.ReactNativeWebView.postMessage(data);
}
}
}
}
}
in ChartView Code Code would be
<ChartView style={{ height: 400 }} config={confi} onMessage={m => this.onMessage(m)} options={options}></ChartView>
can write custom message function as
onMessage = (message) => {
console.log(message.nativeEvent.data)
}

React Native save an image to iOS camera roll

How can I save an image in react native's tag to iOS camera roll? has a uri source.
CameraRoll class has a method named saveImageWithTag but it's not clear how to use it. I think documentation is not good enough.
I have the same issue, and i check the react native CameraRoll API, it provide a static function
static saveImageWithTag(tag, successCallback, errorCallback)
Help you to save the image to the camera roll / gallery.
1.First, make sure your /node_modules/react-native/Libraries/CameraRoll/RCTCameraRoll.xcodeproj has been correctly linked to your current project.If not, you should do it first by following the official document here. (https://facebook.github.io/react-native/docs/linking-libraries-ios.html#content)
2.Second, get your image source well-prepared.For me, I put it in the project assets-library.
3.Coding like this.In this case, I save my image when componentDidMount execute.
(Here is my reference link: https://thebhwgroup.com/blog/accessing-iphone-camera-roll-images-react-native)
'use strict';
var React = require('react-native');
var {
CameraRoll,
View,
} = React;
var CameraRollTest = React.createClass({
componentDidMount() {
CameraRoll.saveImageWithTag('YOUR_IMAGE_TAG/URI', function(data) {
console.log(data);
}, function(err) {
console.log(err);
});
},
render: function() {
return (
<View>
</View>
);
}
});
module.exports = CameraRollTest;