Permission denied - geolocation in React Native - ios

I've been playing around with React Native, getting custom locations to work and setting the "NSLocationWhenInUseUsageDescription" key. The error, when running on the ios simulator, is this:
{
"code": 2,
"message": "Unable to retrieve location.",
"PERMISSION_DENIED": 1,
"POSITION_UNAVAILABLE": 2,
"TIMEOUT": 3
}
This is what I have, pretty much straight from the Geolocation example page https://facebook.github.io/react-native/docs/geolocation.html
/* eslint no-console: 0 */
'use strict';
var React = require('react');
var ReactNative = require('react-native');
var {
StyleSheet,
Text,
View,
} = ReactNative;
export default class GeolocationExample extends React.Component {
state = {
initialPosition: 'unknown'
};
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
}
render() {
return (
<View>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialPosition}
</Text>
</View>
);
}
}
var styles = StyleSheet.create({
title: {
fontWeight: '500',
},
});
Any help would be appreciated!

You need to set the location in the Simulator. There is an option for that in simulator menus as described in this question: Set the location in iPhone Simulator

In Simulator navigator, Choose Debug, at bottom choose Location, next choose Apple, then CMD+R to reload and it worked.

As Santosh suggested, you need to set the location in the iOS Simulator: Debug > Location.
Keep in my mind that from time to time, you will get the "PERMISSION_DENIED " error even tho you set the location in the simulator. If this is happening, you need to select a different predefined location and then the error goes away.

Adding an update to Santosh's answer, please note that in my current version of simulator (11.4) the option to set location is found in:
Features -> Location
(Posting this as a new answer since I am not allowed to comment yet).

I was testing on a real device and it was giving the same error.
I just restarted my device and it started working. Anyone who is still facing the issue can give it a try.

So, for those who are still looking for the answer in Physical device
if you're using
import Geolocation from '#react-native-community/geolocation';
then
Geolocation.getCurrentPosition(
info => {console.log(info)},error=>{console.log(error)}});
if you don't handle the error it will throw error or make your app crash.

Now it's iOS Simulator: Features > Location.

Related

Get Permission to Scan Barcodes on iOS with Flutter

I'm using qr_code_scanner to scan barcodes in my Flutter app and it works fine for Android, but when I try to scan for iOS a pop-up appears and looks like:
I'm using the descriptions Flutter code that looks like the following:
QRView(
key: qrKey,
onQRViewCreated: (controller) => {
controller.scannedDataStream.listen((code) async {
...
})
})
And in my Info.plist file I have the following fields:
<key>io.flutter.embedded_views_preview</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>Camera permission is required to scan QR codes.</string>
However even with these settings set, I can't seem to figure out how to have access to the camera. Thanks for any help.
Update
I followed #EvgeniyTrubilo suggestion and used permission_handler to request permission using the following code:
void getCameraPermission() async {
print(await Permission.camera.status); // prints PermissionStatus.granted
var status = await Permission.camera.status;
if (!status.isGranted) {
final result = await Permission.camera.request();
if (result.isGranted) {
setState(() {
canShowQRScanner = true;
});
} else {
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Please enable camera to scan barcodes')));
Navigator.of(context).pop();
}
} else {
setState(() {
canShowQRScanner = true;
});
}
}
The first time this code was executed it successfully requested permission to access camera, and once permission was granted, the same error showed up. Sequential tries the print statement at the top of the above function said the Permission was granted??
Update 2x
Just realized you can mock the camera in an iOS simulator like you can on Android. I will try this on an actual device and update.
You can use permission_handler. With this, you could ask for camera permission before build QRView. Of course, you should build QRView after camera permission is enabled.
I'm not sure it would be right solution for your issue, but I think that would be an awesome improvement.

How can I make React Native in Android aware of a click event in a tooltip in a Highcharts chart?

I have a React Native application built with Expo. On How can I add links in a Highcharts tooltip that will open on mobile's browser? I was able to pass a URL to Highcharts so that when a tooltip is clicked, that URL is opened:
return(
<View style={styles.container}>
<ChartView
onMessage={m => this.onMessage(m)}
config={config}
/>
</View>
This triggers this method to open the URL:
onMessage = (m) => {
let data = JSON.parse(m.nativeEvent.data);
Linking.openURL(data.url)
};
And the URL gets populated through a global variable window.myURL and sending the message with postMessage():
render() {
let Highcharts = "Highcharts";
let config ={
...
plotOptions: {
series: {
stickyTracking: false,
point: {
events: {
click: function(e) {
window.postMessage(JSON.stringify({'url': window.myUrl}));
}
}
}
},
},
tooltip: {
useHTML: true,
formatter: function () {
window.myUrl = extras.url;
return `<div class="text">some text</div>`;
}
};
This works well on iOS (both physical and emulator), but does not on Android (neither physical nor emulator).
I have gone through different Github issues such as onMessage not called in native code even though sent from webview( android) and react native html postMessage can not reach to WebView and they tend to suggest using some timeout on window.postMessage(). However, I see that even this does not work:
plotOptions: {
series: {
point: {
events: {
click: function(e) {
setTimeout(function() {
console.log('bla');
window.postMessage(JSON.stringify({'url': window.myUrl}));
}, 200);
}
}
}
},
},
Since even console.log() does not work, it looks to me as if the click event is not being caught by Android.
How can I make Android aware of this event so that I can go through the message and then open the URL?
The "click" event is fine. Problem is that, RN core's <WebView> implementation for Android is flawed at polyfilling window.postMessage(). This issue has been well discussed in this github issue.
So it seems the nature of problem, is RN has to polyfill the native window.postMessage for some reason, but the override didn't take place timely, causing window.postMessage calls still made to the native one.
One solution (for Android) proposed in that github issue, is simply stop using the native window.postMessage, and directly use the internal interface, which is the actual polyfill function.
// in place of `window.postMessage(data)`, use:
window.__REACT_WEB_VIEW_BRIDGE.postMessage(String(data))
One heads-up though, this API is not public and might be subject to change in future.

Apache Cordova listens event too late on ios after action

I develop iOS app with Apache Cordova on Xcode. The problem is when I test my app on device, Cordova listens events too late. For example, when I click share button on iOS, the share box runs after 2 minutes. Another example is I use admob pro pluginfor admob, the ads run after 5 minutes on device ready. I recognized that this problem is exist only on Cordova and its plugins events.
I checked and tried everything but couldn't find a solution. On android platform everything is work fine.
How can I fix this? Is there anybody can help me ?
the admob responding after 2-5 minutes. I did type simple javascript function that is alert for device ready. its working fine.
the code snippet is below;
function reklamYukle() {
var admobid = {};
// TODO: replace the following ad units with your own
if (/(android)/i.test(navigator.userAgent)) {
admobid = { // for Android
banner: 'ca-app-pub-5534669392136777/3711456161',
interstitial: 'ca-app-pub-5534669392134577/5454702358'
};
} else if (/(ipod|iphone|ipad)/i.test(navigator.userAgent)) {
admobid = { // for iOS
banner: 'ca-app-pub-5534669392136777/7457497261',
interstitial: 'ca-app-pub-5534669392136777/5896501200'
};
} else {
admobid = { // for Windows Phone
banner: 'ca-app-pub-6869992474017983/8878394753'
};
}
AdMob.createBanner({
adId: admobid.banner,
position: AdMob.AD_POSITION.BOTTOM_CENTER,
overlap: false,
offsetTopBar: true,
bgColor: 'black',
autoshow: true
});
AdMob.prepareInterstitial({
adId: admobid.interstitial,
autoShow: true
});
}
function onDeviceReady() {
reklamYukle();
}
document.addEventListener("deviceready", onDeviceReady, false);

Ionic IOS & Firebase (White Screen of Death)

I've hit a very difficult bug so if you're up for a challenge, read on. :)
Steps to recreate what I'm seeing:
Deploy my app to a device. (this bug never happens on emulate, serve, or Xcode)
Leave the app running in the background for an undetermined amount of time (usually a day or so).
Sometimes when opening the app again you'll get a white screen of death.
I have a feeling that something is happening to the firebase connection and when the app opens it can't resolve $requireAuth() in the route.
Any help would be appreciated. Is there anyway issues like that can get logged somewhere?
Here is part of my route file:
$urlRouterProvider.otherwise(function ($injector) {
var $state = $injector.get("$state");
$state.go("app.dashboard");
});
$stateProvider.state('app', {
url: '/app',
abstract: true,
templateUrl: 'skinsaver/app/app.html',
controller: 'AppController as app',
resolve: {
"userAuth": ["AppAuth", resolveUser]
},
});
$stateProvider.state('app.dashboard', {
url: '/dashboard',
templateUrl: 'skinsaver/app/dashboard/dashboard.html',
controller: 'DashboardController as dashboard',
});
function resolveUser(AppAuth){
return AppAuth.firebaseAuth.$requireAuth();
};
//watch for route errors to redirect to login
$rootScope.$on('$stateChangeError', function(event, toState, toParams, fromState, fromParams, error) {
if(error === 'AUTH_REQUIRED'){
event.preventDefault();
AppAuth.returnToState = toState;
$state.go("public.login");
}
});

React Native & Meteor implementation

I'm working on a react native app with a meteor backend. I know to tie these two together I have to use the node package ddp-client for the app to connect. https://www.npmjs.com/package/ddp-client
But what is the best practice for going about this. Should I:
Define the DDPClient and connect in index.ios.js where i keep connected and find some way to issue requests from the main app component? (I wouldnt know how to do this however but it would be a start.)
Only connect through dpp on each component that I need this for and issue a request each time?
Really any real example would help. Most of the code I find online are single page examples with not much else. Or just a push in the right direction.
p.s. The app is a marketplace. Thanks!
'use strict';
var React = require('react-native');
var {
AppRegistry,
NavigatorIOS,
StyleSheet,
StatusBarIOS,
} = React;
var DDPClient = require("ddp-client");
class AppWrapper extends React.Component{
componentDidMount() {
var ddpClient = new DDPClient({url: 'ws://localhost:3000/websocket'});
ddpClient.connect(function(error, wasReconnect) {
if (error) {
console.log('DDP connection error!');
return;
}
if (wasReconnect) {
console.log('Reestablishment of a connection.');
}
console.log('connected!');
});
}
render(){
return(
<NavigatorIOS
barTintColor='black'
titleTextColor='white'
tintColor='white'
style={styles.container}
translucent={false}
initialRoute={{
backButtonTitle: ' ',
component: Homeios,
title: 'hombro',
}}
/>
)
}
}
var styles = StyleSheet.create({
container: {
flex: 1,
},
});
AppRegistry.registerComponent('someApp', () => AppWrapper);
You can use react-native-meteor package in your react native app which is pretty easy. https://www.npmjs.com/package/react-native-meteor check this link for documentation it has many awesome functions including Accounts package ready to use.

Resources