React native. I can't find my current location(Geolocation) IOS - ios

I need to access my location from GPS. So, i import geolocation to project.
first, I create following like this (install react native map, already link)
and I just already add NSLocationWhenInUseUsageDescription in my Xcode
also, I just already libRCTGeolocation.a in my Xcode
then, I just read map view in mapview from Airbnb. tell me to set showUserLocation set it to "true". when set true will ask user to access
location.
reference: https://github.com/airbnb/react-native-maps/blob/master/docs/mapview.md
finally, That is not ask anything to access
location. so, I don't know why. I can't find my current location.
and this is my picture step by step that I describe from begin
http://imgur.com/a/5TJZa
I will show you my code.
Route.js
import React, { Component, PropTypes } from 'react';
import {
StyleSheet,
View,
Text,
Image,
Dimensions,
} from 'react-native';
import MapView from 'react-native-maps';
var {height, width} = Dimensions.get('window');
export default class Route extends Component {
constructor(props){
super(props);
this.state = {
region: {
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}
};
this.onRegionChange = this.onRegionChange.bind(this);
}
onRegionChange(region) {
this.setState({ region });
}
render() {
return (
<View style={styles.container}>
<MapView style={styles.map}
mapType="standard"
showsUserLocation={true}
followsUserLocation={true}
showsCompass={false}
showsPointOfInterest={false}
region={this.state.region}
onRegionChange={this.onRegionChange}
/>
<View style={styles.container}>
<Text>
Latitude: {this.state.region.latitude}{'\n'}
Longitude: {this.state.region.longitude}{'\n'}
LatitudeDelta: {this.state.region.latitudeDelta}{'\n'}
LongitudeDelta: {this.state.region.longitudeDelta}
</Text>
</View>
</View>
);
}
}
Route.navigationOptions = { //this define from App.js option in SecondScreen
title: 'Route', //name top of StackNavigator
};
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
image: {
width: 200,
height: 200,
},
text: {
color: 'white',
fontWeight: 'bold',
backgroundColor: 'transparent',
marginTop: 20,
},
map: {
width: width,
height: height*2/3
}
});

In the iOS simulator it reads a fake location. Set a custom location using Debug > Location > Custom Location... in the simulator menu.
If you run it on a real device you will get the real location. If you continue to use the simulator you can just put your current location using the Custom Location menu. You can get your location a number of ways, including this: http://mylocation.org/.

Related

React-Native: Image NOT disappearing on IOS after changing image source to "null"

If I change the state of an image source to "null", the image should disappear, but it doesn't. This issue happens on IOS, but works correctly on Android. I'm using RN v 0.64.2. On a previous version, 0.60.1, this worked correctly for both platforms.
Edit: Also tried with the latest RN version, 0.66.4, and it still doesn't work correctly.
I have created a very simplified test app that reproduces this issue. Code below:
import React, {Component} from 'react';
import {View, StyleSheet, Text, Image, Pressable} from 'react-native';
class App extends Component {
constructor (props) {
super(props);
this.state = {
image_source: require('./test.png')
}
}
removeImage = () => {
this.setState({image_source: null});
//this.setState({image_source: require('./test2.png')});
}
checkImage = () => {
alert(this.state.image_source);
}
render() {
return (
<View>
<Text style={{marginTop: 200}}>
test text
</Text>
<Image
style={{width: 100, height: 100}}
source={this.state.image_source}
/>
<Pressable
style={{width: 80, height: 25, backgroundColor: 'blue'}}
onPress={() => this.removeImage()}
>
</Pressable>
<Pressable
style={{width: 80, height: 25, backgroundColor: 'red'}}
onPress={() => this.checkImage()}
>
</Pressable>
</View>
);
}
}
const styles = StyleSheet.create({
})
export default App;
Clicking the blue rectangle changes the state of the image source to "null" and the image should disappear, but doesn't. The red rectangle verifies the state was changed to "null". I'm able to switch to a different image; that works correctly, just can't remove it.
Try to set image in component life cycle
import React, {Component} from 'react';
import {View, StyleSheet, Text, Image, Pressable} from 'react-native';
class App extends Component {
constructor (props) {
super(props);
this.state = {
image_source:null
}
}
componentDidMount(){
this.setState({image_source: require('./test.png')});
}
removeImage = () => {
this.setState({image_source: null});
//this.setState({image_source: require('./test2.png')});
}
checkImage = () => {
alert(this.state.image_source);
}
render() {
return (
<View>
<Text style={{marginTop: 200}}>
test text
</Text>
<Image
style={{width: 100, height: 100}}
source={this.state.image_source}
/>
<Pressable
style={{width: 80, height: 25, backgroundColor: 'blue'}}
onPress={() => this.removeImage()}
>
</Pressable>
<Pressable
style={{width: 80, height: 25, backgroundColor: 'red'}}
onPress={() => this.checkImage()}
>
</Pressable>
</View>
);
}
}
const styles = StyleSheet.create({
})
export default App;
if this do not help, we often used this package for projects
https://www.npmjs.com/package/react-native-fast-image

Unable to Trigger React Navigation from React Native Maps

I'm building a react native app using the react-native-maps dependency but am unable to navigate to other screens using react-navigator onPress from within the MapView.
I would like to pass the { communityId: ${community._id} } object to view the unique community screen.
code:
import React, { Component } from 'react';
import { View, Image, StyleSheet, Vibration, TouchableOpacity, Text } from 'react-native';
import MapView, { Callout } from 'react-native-maps';
import { Marker } from 'react-native-maps';
class LogoTitle extends React.Component {
render() {
return (
<Image
source={require("./logo.png")}
style={{ width: 60, height: 30 }}
/>
);
}
}
class MapScreen extends Component {
constructor(props) {
super(props);
this.state = {
latitude: null,
longitude: null,
error: null,
communities: ""
};
}
componentDidMount() {
fetch("http://localhost:4000/community")
.then(res => res.json())
.then(res => {
this.setState({ communities: res });
});
Vibration.vibrate();
navigator.geolocation.getCurrentPosition(
(position) => {
this.setState({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
error: null,
});
},
(error) => this.setState({ error: error.message }),
{ enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 },
);
}
static navigationOptions = {
headerTitle: <LogoTitle />
};
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
render() {
const LatLng = {
latitude: this.state.latitude,
longitude: this.state.longitude
}
let commcoords;
this.state.communities &&
(commcoords = this.state.communities.map((community, id) => {
let commlatlong;
commlatlong = {
latitude: community.location.lat,
longitude: community.location.long
};
return (
<Marker
key={id}
coordinate={commlatlong}
title={community.name}>
<Callout>
<TouchableOpacity
onPress={() => this.navigateToView("Community", { communityId: `${community._id}` })}
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
)
}))
return (
<View style={styles.container}>
{this.state.latitude &&
<MapView
style={styles.map}
initialRegion={{
latitude: this.state.latitude,
longitude: this.state.longitude,
latitudeDelta: 0.1011,
longitudeDelta: 0.1011,
}}>
<Marker
coordinate={LatLng}
title={`Latitude: ${this.state.latitude}`}
description={`Longitude: ${this.state.longitude}`}
pinColor='#000000'>
</Marker>
{commcoords}
</MapView>}
</View>
);
}
}
I have already attempted:
1) Using the normal navigation method.
onPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}
2) Using alternate touch methods, buttons, touchable highlights, etc.
3) Attempted to console.log the triggered touch method using the remote debugger. The console.log was never triggered in the console.
navigateToView(viewName, { param: value }) {
console.log(viewName);
const { navigate } = this.props.navigation;
navigate(viewName, { param: value });
}
4) Researched and attempted solutions to no avail from the following stackoverflow links:
React Native - How to use React Navigation with React Native Maps?
React native maps click pin to take you to another screen
I would like to resolve this maps navigation issue to increase functionality in this native app. If there is an alternative method, I am open to any and all suggestions. Thank you.
I figured out how to trigger an the onpress event by using onCalloutPress in the Marker:
<Marker
key={id}
coordinate={commlatlong}
title={community.name}
onCalloutPress={() => this.props.navigation.navigate("Community", { communityId: `${community._id}` })}>
<Callout>
<TouchableOpacity
style={styles.communityButton}>
<Text style={styles.communityButtonText}>{community.name}</Text>
<Text style={styles.descButtonText}>{community.description}</Text>
</TouchableOpacity>
</Callout>
</Marker>
I am now able to navigate to show screens from the map. Thanks to this post:
Marker click event on react native maps not working in react ios
Additional source:
onCalloutPress Callback that is called when a callout is tapped by the user.
https://github.com/react-native-community/react-native-maps/blob/master/docs/mapview.md

E2E: Select an image from a UIImagePickerController with Wix Detox

Description
I need to write an e2e test that in some point it has to select an image in UIImagePickerController, I tried to use element(by.type('UIImagePickerController')). tapAtPoint() with no use. I need a way to select an image. I have found a way to do it with native tests.
Also mocking isn't an option for me since I use a higher version that the one react-native-repackeger needs.
Steps to Reproduce
Use with any application that uses image picker
Try to use element(by.type('UIImagePickerController')).tapAtPoint({ x: 50, y: 200 })
Detox, Node, Device, Xcode and macOS Versions
Detox: 6.0.2
Node: 8.9.0
Device: iOS Simulator 6s
Xcode: 9.2
macOS: 10.13.1
React-Native: 0.46.4
Device and verbose Detox logs
There's no logs, the device taps on the right location but the tap doesn't make an effect.
Noticed the original question stated that mocks were not an option in the case presented, but I came across this Stack Overflow question a few times in my searches for a solution and thought to share what I ultimately came up with for my situation.
I was able to get around the limitations for the e2e test by wrapping react-native-image-picker in my own export:
ImagePicker.js
import ImagePicker from 'react-native-image-picker';
export default ImagePicker;
And then creating a mock with a custom extension (i.e. e2e.js):
ImagePicker.e2e.js
const mockImageData = '/9j/4AAQSkZ...MORE BASE64 DATA OF CUTE KITTENS HERE.../9k=';
export default {
showImagePicker: function showImagePicker(options, callback) {
if (typeof options === 'function') {
callback = options;
}
callback({
data: mockImageData,
});
},
};
Finally, configure the metro bundler to prioritize your custom extension:
[project root]/rn-cli.config.js
const defaultSourceExts = require('metro-config/src/defaults/defaults')
.sourceExts;
module.exports = {
resolver: {
sourceExts: process.env.RN_SRC_EXT
? process.env.RN_SRC_EXT.split(',').concat(defaultSourceExts)
: defaultSourceExts,
},
};
Then run with the RN_SRC_EXT environment variable set to the custom extension:
RN_SRC_EXT=e2e.js react-native start
See the Detox Mocking Guide for more information.
Not sure if this is related, but for iOS 11 I can't even see those native view types in the Debug View Hierarchy.
For iOS 9 and 10 however, I would solve the problem like this:
it('select first image from camera roll', async () => {
// select a photo
await element(by.id('select_photo')).tap();
// Choose from Library...
await element(by.traits(['button']).and(by.type('_UIAlertControllerActionView'))).atIndex(1).tap();
// select Cemara Roll, use index 0 for Moments
await element(by.type('UITableViewCellContentView')).atIndex(1).tap();
// select first image
await element(by.type('PUPhotoView')).atIndex(0).tap();
});
There are probably many other possibilities to solve this problem with different native view types and accessibility traits.
I just used the example provided from react-native-image-picker to test with above code:
import React from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
PixelRatio,
TouchableOpacity,
Image,
} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class App extends React.Component {
state = {
avatarSource: null,
videoSource: null
};
selectPhotoTapped() {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled photo picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
let source = { uri: response.uri };
// You can also display the image using data:
// let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source
});
}
});
}
selectVideoTapped() {
const options = {
title: 'Video Picker',
takePhotoButtonTitle: 'Take Video...',
mediaType: 'video',
videoQuality: 'medium'
};
ImagePicker.showImagePicker(options, (response) => {
console.log('Response = ', response);
if (response.didCancel) {
console.log('User cancelled video picker');
}
else if (response.error) {
console.log('ImagePicker Error: ', response.error);
}
else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
}
else {
this.setState({
videoSource: response.uri
});
}
});
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity testID="select_photo" onPress={this.selectPhotoTapped.bind(this)}>
<View style={[styles.avatar, styles.avatarContainer, {marginBottom: 20}]}>
{ this.state.avatarSource === null ? <Text>Select a Photo</Text> :
<Image style={styles.avatar} source={this.state.avatarSource} />
}
</View>
</TouchableOpacity>
<TouchableOpacity onPress={this.selectVideoTapped.bind(this)}>
<View style={[styles.avatar, styles.avatarContainer]}>
<Text>Select a Video</Text>
</View>
</TouchableOpacity>
{ this.state.videoSource &&
<Text style={{margin: 8, textAlign: 'center'}}>{this.state.videoSource}</Text>
}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
avatarContainer: {
borderColor: '#9B9B9B',
borderWidth: 1 / PixelRatio.get(),
justifyContent: 'center',
alignItems: 'center'
},
avatar: {
borderRadius: 75,
width: 150,
height: 150
}
});
AppRegistry.registerComponent('example', () => App);

navigator.geolocation.watchPosition not working correctly on ios device

I have a strange behavior and can not find a solution. In my React Native application I'm using the navigator.geolocation to determine the current position. My application is almost identical as the example in Facebook's Geolocation Code.
In the simulator my application works perfectly, but when I deploy it to my iphone the returning position (by getCurrentPosition and watchPosition) is not correctly. For example speed and heading is -1, accuracy is 65. Longitude and latitude seem to be valid, but not my real position (is in another country).
It does not matter whether I deploy the application via debug or release to the iphone, it always reacts same.
But if I start for example TomTom and put this application in the background, and then start my GeolocationExample application, everything works as it should.
My application I have created as follows:
react-native init GeolocationExample
And then I replaced the file index.ios.js with this code.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
export default class GeolocationExample extends React.Component {
state = {
initialPosition: 'unknown',
lastPosition: 'unknown',
};
watchID: ?number = null;
componentDidMount() {
navigator.geolocation.getCurrentPosition(
(position) => {
var initialPosition = JSON.stringify(position);
this.setState({initialPosition});
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
);
this.watchID = navigator.geolocation.watchPosition((position) => {
var lastPosition = JSON.stringify(position);
this.setState({lastPosition});
});
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID);
}
render() {
return (
<View style={styles.main}>
<Text>
<Text style={styles.title}>Initial position: </Text>
{this.state.initialPosition}
</Text>
<Text>
<Text style={styles.title}>Current position: </Text>
{this.state.lastPosition}
</Text>
</View>
);
}
}
var styles = StyleSheet.create({
main: {
margin: 30
},
title: {
fontWeight: '500',
},
});
AppRegistry.registerComponent('GeolocationExample', () => GeolocationExample);
1st option : add parameter
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000, accuracy:10 //ten meters not in the document}
2nd option : set line 28
#define RCT_DEFAULT_LOCATION_ACCURACY kCLLocationAccuracyBest //default was kCLLocationAccuracyHundredMeters

React Native: component on top of another component

I'm building a location based iOS app using react-native-maps and react-native-google-places-autocomplete.
In my code, I have the search bar code first and the map code second - this is so the search bar renders on top of the map. The problem is, I can't move the map because the search bar component seems to have a transparent element that takes up the whole screen. When the search bar is removed, I can move the map. How can I have the search bar on top of the map and also move the map.
I welcome alternative/better ways of doing what I'm trying to do.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Dimensions
} from 'react-native';
import MapView from 'react-native-maps';
var {GooglePlacesAutocomplete} = require('react-native-google-places-autocomplete');
const homePlace = {description: 'Home', geometry: { location: { lat: 42.3969, lng: -71.1224 } }};
const workPlace = {description: 'Work', geometry: { location: { lat: 42.3, lng: -71.1 } }};
var screenWidth = Dimensions.get('window').width;
export default class myapp extends Component {
render() {
return (
<View style={styles.container}>
<MapView
style={styles.map}
initialRegion={{
latitude: 42.3967,
longitude: -71.1223,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}>
<MapView.Marker
coordinate={{
latitude: 42.3967,
longitude: -71.1223
}}/>
</MapView>
<GooglePlacesAutocomplete
placeholder='Search location'
minLength={2}
autoFocus={false}
autoCorrect={false}
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={(row) => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data)
console.log(details)
}}
getDefaultValue={() => {
return ''; // text input default value
}}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaSyAUYfbKtctkIibOgFnNN2x9Xg9i0sVxlhQ',
language: 'en',
types: 'geocode'
}}
styles={{
description: {
fontWeight: 'bold',
},
predefinedPlacesDescription: {
color: '#1faadb',
},
textInputContainer: {
backgroundColor: 'rgba(0,0,0,0)',
top: 15,
width: screenWidth-10,
borderWidth: 0
},
textInput: {
marginLeft: 0,
marginRight: 0,
height: 38,
color: '#5d5d5d',
fontSize: 16,
borderWidth: 0
},
listView: {
backgroundColor: 'rgba(192,192,192,0.9)',
top: 23
}
}}
currentLocation={true}
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch'
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
types: 'food'
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3', 'sublocality', 'administrative_area_level_2', 'administrative_area_level_1']}
// filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[homePlace, workPlace]}
debounce={200}
//renderLeftButton={() => <Image source={require('left-icon')} />}
renderLeftButton={() => <Text></Text> }
renderRightButton={() => <Text></Text> }
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
map: {
left: 0,
right: 0,
top: 0,
bottom: 0,
position: 'absolute'
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('myapp', () => myapp);
Add position styles to the react-native-google-places-autocomplete style property:
styles={{
container:{
position: 'absolute',
top: 0
},
description: {
fontWeight: 'bold',
},
.....

Resources