85
loading...
This website collects cookies to deliver better user experience
npx react-native init taxiApp --version 0.64.2
import React from "react"
import { SafeAreaView, StatusBar, StyleSheet, Text, View } from "react-native"
const App = () => {
return (
<SafeAreaView>
<StatusBar barStyle="dark-content" />
<View style={styles.sectionContainer}>
<Text style={styles.sectionTitle}>Welcome to Taxi App</Text>
</View>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: "600",
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: "400",
},
})
export default App
import App from "./App"
import App from "./src/App"
npx react-native start
npx react-native run-ios
npx react-native run-android
npm install react-native-maps --save-exact
...
<key>NSLocationWhenInUseUsageDescription</key>
<string>In order to work we need you to grant location access</string>
...
+ #import <GoogleMaps/GoogleMaps.h>
@implementation AppDelegate
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
+ [GMSServices provideAPIKey:@"_YOUR_API_KEY_"]; // add this line using the api key obtained from Google Console
...
# React Native Maps dependencies
rn_maps_path = '../node_modules/react-native-maps'
pod 'react-native-google-maps', :path => rn_maps_path
pod 'GoogleMaps'
pod 'Google-Maps-iOS-Utils'
npx pod-install
ext {
buildToolsVersion = "29.0.3"
minSdkVersion = 21
compileSdkVersion = 29
targetSdkVersion = 29
ndkVersion = "20.1.5948944"
playServicesVersion = "17.0.0" // <= 👈
androidMapsUtilsVersion = "2.2.0" // <= 👈
}
<application>
<!-- You will only need to add this meta-data tag, but make sure it's a child of application -->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="Your Google maps API Key Here"/>
<!-- You will also only need to add this uses-library tag -->
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
</application>
import React from "react"
import { SafeAreaView, StatusBar, StyleSheet } from "react-native"
import MapView, { PROVIDER_GOOGLE } from "react-native-maps"
const App = () => {
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" />
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: 57.709127,
longitude: 11.934746,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
/>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
alignItems: "center",
},
map: {
...StyleSheet.absoluteFillObject,
},
})
export default App
npm install --save-exact react-native-permissions@3.0.1
# React Native Permissions
permissions_path = '../node_modules/react-native-permissions/ios'
pod 'Permission-LocationWhenInUse', :path => "#{permissions_path}/LocationWhenInUse"
<key>NSLocationWhenInUseUsageDescription</key>
<string>In order to work we need you to grant location access</string>
npx pod-install
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
import React, { useEffect } from "react"
import { SafeAreaView, StatusBar, StyleSheet } from "react-native"
import MapView, { PROVIDER_GOOGLE } from "react-native-maps"
import { check, request, PERMISSIONS, RESULTS } from "react-native-permissions" // 👈
const App = () => {
const handleLocationPermission = async () => { // 👈
let permissionCheck = '';
if (Platform.OS === 'ios') {
permissionCheck = await check(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
if (
permissionCheck === RESULTS.BLOCKED ||
permissionCheck === RESULTS.DENIED
) {
const permissionRequest = await request(
PERMISSIONS.IOS.LOCATION_WHEN_IN_USE,
);
permissionRequest === RESULTS.GRANTED
? console.warn('Location permission granted.')
: console.warn('location permission denied.');
}
}
if (Platform.OS === 'android') {
permissionCheck = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION);
if (
permissionCheck === RESULTS.BLOCKED ||
permissionCheck === RESULTS.DENIED
) {
const permissionRequest = await request(
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
);
permissionRequest === RESULTS.GRANTED
? console.warn('Location permission granted.')
: console.warn('location permission denied.');
}
}
};
useEffect(() => {
handleLocationPermission()
}, [])
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" />
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: 57.709127,
longitude: 11.934746,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
showsUserLocation={true} // 👈
/>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
alignItems: "center",
},
map: {
...StyleSheet.absoluteFillObject,
},
})
export default App
initialRegion={{
latitude: 57.709127,
longitude: 11.934746,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
npm install react-native-geolocation-service@5.2.0 --save-exact
npx pod-install
import React, { useEffect, useState } from "react"
import { SafeAreaView, StatusBar, StyleSheet } from "react-native"
import MapView, { PROVIDER_GOOGLE } from "react-native-maps"
import { check, request, PERMISSIONS, RESULTS } from "react-native-permissions"
import Geolocation from "react-native-geolocation-service" // 👈
const App = () => {
const [location, setLocation] = useState(null) // 👈
const handleLocationPermission = async () => {
let permissionCheck = ""
if (Platform.OS === "ios") {
permissionCheck = await check(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE)
if (permissionCheck === RESULTS.DENIED) {
const permissionRequest = await request(
PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
)
permissionRequest === RESULTS.GRANTED
? console.warn("Location permission granted.")
: console.warn("Location perrmission denied.")
}
}
if (Platform.OS === "android") {
permissionCheck = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
if (permissionCheck === RESULTS.DENIED) {
const permissionRequest = await request(
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION
)
permissionRequest === RESULTS.GRANTED
? console.warn("Location permission granted.")
: console.warn("Location perrmission denied.")
}
}
}
useEffect(() => {
handleLocationPermission()
}, [])
useEffect(() => { // 👈
Geolocation.getCurrentPosition(
position => {
const { latitude, longitude } = position.coords
setLocation({ latitude, longitude })
},
error => {
console.log(error.code, error.message)
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
)
}, [])
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" />
{location && ( // 👈
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: location.latitude, // 👈
longitude: location.longitude,// 👈
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
showsUserLocation={true}
/>
)}
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
alignItems: "center",
},
map: {
...StyleSheet.absoluteFillObject,
},
})
export default App
const [location, setLocation] = useState(null)
.<MapView />
component only if location state isn't null.export const customStyleMap = [
{
elementType: "geometry",
stylers: [
{
color: "#242f3e",
},
],
},
{
elementType: "labels.text.fill",
stylers: [
{
color: "#746855",
},
],
},
{
elementType: "labels.text.stroke",
stylers: [
{
color: "#242f3e",
},
],
},
{
featureType: "administrative.locality",
elementType: "labels.text.fill",
stylers: [
{
color: "#d59563",
},
],
},
{
featureType: "poi",
elementType: "labels.text.fill",
stylers: [
{
color: "#d59563",
},
],
},
{
featureType: "poi.park",
elementType: "geometry",
stylers: [
{
color: "#263c3f",
},
],
},
{
featureType: "poi.park",
elementType: "labels.text.fill",
stylers: [
{
color: "#6b9a76",
},
],
},
{
featureType: "road",
elementType: "geometry",
stylers: [
{
color: "#38414e",
},
],
},
{
featureType: "road",
elementType: "geometry.stroke",
stylers: [
{
color: "#212a37",
},
],
},
{
featureType: "road",
elementType: "labels.text.fill",
stylers: [
{
color: "#9ca5b3",
},
],
},
{
featureType: "road.highway",
elementType: "geometry",
stylers: [
{
color: "#746855",
},
],
},
{
featureType: "road.highway",
elementType: "geometry.stroke",
stylers: [
{
color: "#1f2835",
},
],
},
{
featureType: "road.highway",
elementType: "labels.text.fill",
stylers: [
{
color: "#f3d19c",
},
],
},
{
featureType: "transit",
elementType: "geometry",
stylers: [
{
color: "#2f3948",
},
],
},
{
featureType: "transit.station",
elementType: "labels.text.fill",
stylers: [
{
color: "#d59563",
},
],
},
{
featureType: "water",
elementType: "geometry",
stylers: [
{
color: "#17263c",
},
],
},
{
featureType: "water",
elementType: "labels.text.fill",
stylers: [
{
color: "#515c6d",
},
],
},
{
featureType: "water",
elementType: "labels.text.stroke",
stylers: [
{
color: "#17263c",
},
],
},
]
/**
1. Copy and paste code from App.js
2. Rename component name from App to UserScreen
*/
import React, { useEffect, useState } from "react"
import { SafeAreaView, StatusBar, StyleSheet } from "react-native"
import MapView, { PROVIDER_GOOGLE } from "react-native-maps"
import { check, request, PERMISSIONS, RESULTS } from "react-native-permissions"
import Geolocation from "react-native-geolocation-service"
const UserScreen = () => {
const [location, setLocation] = useState(null)
const handleLocationPermission = async () => {
let permissionCheck = ""
if (Platform.OS === "ios") {
permissionCheck = await check(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE)
if (permissionCheck === RESULTS.DENIED) {
const permissionRequest = await request(
PERMISSIONS.IOS.LOCATION_WHEN_IN_USE
)
permissionRequest === RESULTS.GRANTED
? console.warn("Location permission granted.")
: console.warn("Location perrmission denied.")
}
}
if (Platform.OS === "android") {
permissionCheck = await check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
if (permissionCheck === RESULTS.DENIED) {
const permissionRequest = await request(
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION
)
permissionRequest === RESULTS.GRANTED
? console.warn("Location permission granted.")
: console.warn("Location perrmission denied.")
}
}
}
useEffect(() => {
handleLocationPermission()
}, [])
useEffect(() => {
Geolocation.getCurrentPosition(
position => {
const { latitude, longitude } = position.coords
setLocation({ latitude, longitude })
},
error => {
console.log(error.code, error.message)
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
)
}, [])
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" />
{location && (
<MapView
style={styles.map}
provider={PROVIDER_GOOGLE}
initialRegion={{
latitude: location.latitude,
longitude: location.longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
showsUserLocation={true}
/>
)}
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
alignItems: "center",
},
map: {
...StyleSheet.absoluteFillObject,
},
})
export default UserScreen
<UserScreen />
component and render that. We will use React Navigation inside App.js to handle all the screens of our app in the future./**
For now just import and render <UserScreen />
*/
import React from "react"
import UserScreen from "./screens/UserScreen"
const App = () => {
return <UserScreen />
}
export default App
...
import {customStyleMap} from '../styles'; // 👈
const UserScreen = () => {
...
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" />
{location && (
<MapView
...
customMapStyle={customStyleMap} // 👈
paddingAdjustmentBehavior="automatic" // 👈
showsMyLocationButton={true} // 👈
showsBuildings={true} // 👈
maxZoomLevel={17.5} // 👈
loadingEnabled={true} // 👈
loadingIndicatorColor="#fcb103" // 👈
loadingBackgroundColor="#242f3e" // 👈
/>
)}
</SafeAreaView>
);
};
...
export default UserScreen;
<UserScreen />
component and we're goin to use:npm install --save-dev @testing-library/react-native
npm install --save-dev @testing-library/jest-native
// package.json
"jest": {
"preset": "react-native",
// 👇
"setupFilesAfterEnv": [
"@testing-library/jest-native/extend-expect"
]
}
// ./jest-setup.js
import { jest } from "@jest/globals"
<UserScreen />
component. For that, inside src/screens, create __tests__
(double underscore, both sides) folder. Inside create the file named UserScreen.test.js.// ./src/screens/__tests__/UserScreen.test.js
import React from "react"
import { render, waitFor } from "@testing-library/react-native"
import UserScreen from "../UserScreen"
describe("<UserScreen />", () => {
test("should renders MapView and Marker with user current location", () => {
render(<UserScreen />)
})
})
npm run test
jest.mock("react-native-maps", () => {
const React = require("react")
const { View } = require("react-native")
class MockMapView extends React.Component {
render() {
const { testID, children, ...props } = this.props
return (
<View
{...{
...props,
testID,
}}
>
{children}
</View>
)
}
}
const mockMapTypes = {
STANDARD: 0,
SATELLITE: 1,
HYBRID: 2,
TERRAIN: 3,
NONE: 4,
MUTEDSTANDARD: 5,
}
return {
__esModule: true,
default: MockMapView,
MAP_TYPES: mockMapTypes,
PROVIDER_DEFAULT: "default",
PROVIDER_GOOGLE: "google",
}
})
"jest": {
"preset": "react-native",
"setupFilesAfterEnv": [
"@testing-library/jest-native/extend-expect"
],
// 👇
"setupFiles": [
"./jest-setup.js"
]
}
npm run test
jest.mock("react-native-permissions", () =>
require("react-native-permissions/mock")
)
export {PERMISSIONS, RESULT}
then you could try to fix adding transformIgnorePatterns to your Jest config inside package.json"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native-permissions|)" // See I added react-native-permissions
],
__mocks__
folder at the root of our project. Inside the mocks folder, add the name of the library react-native-geolocation-service.js. It has to be the same name.// ./__mocks__/react-native-geolocation-service.js
export default {
getCurrentPosition: jest.fn().mockImplementation(successCallback => {
const position = {
coords: {
latitude: 57.7,
longitude: 11.93,
},
}
successCallback(position)
}),
}
__tests__/App.test.js
file. We don’t go to test App.js for now. We‘re focusing on src/screens/__tests__/UserScreen.test.js
.npm run test
// src/screens/__tests__/UserScreen.test.js
import React from "react"
import { render, waitFor } from "@testing-library/react-native"
import UserScreen from "../UserScreen"
// Import check from react-native-permissions
import { check } from "react-native-permissions"
// Import Geolocation also
import Geolocation from "react-native-geolocation-service"
describe("<UserScreen />", () => {
test("should renders MapView and Marker with user current location", async () => {
render(<UserScreen />)
await waitFor(() => {
expect(check).toHaveBeenCalledTimes(1)
expect(Geolocation.getCurrentPosition).toHaveBeenCalledTimes(1)
})
})
})
...
const UserScreen = () => {
...
return (
<SafeAreaView style={styles.container}>
<StatusBar barStyle="dark-content" />
{location && (
<MapView
testID="map" // 👈
...
/>
)}
</SafeAreaView>
);
};
...
jest.mock('react-native-maps', () => {
const React = require('react');
const {View} = require('react-native');
class MockMapView extends React.Component {
render() {
const {testID, children, ...props} = this.props; // 👈
return (
<View
{...{
...props,
testID, // 👈
}}>
{children}
</View>
);
}
}
...
});
import React from "react"
import { render, waitFor } from "@testing-library/react-native"
import UserScreen from "../UserScreen"
import { check } from "react-native-permissions"
import Geolocation from "react-native-geolocation-service"
describe("<UserScreen />", () => {
test("should renders MapView and Marker with user current location", async () => {
const { getByTestId } = render(<UserScreen />) // 👈
await waitFor(() => {
expect(check).toHaveBeenCalledTimes(1)
expect(Geolocation.getCurrentPosition).toHaveBeenCalledTimes(1)
expect(getByTestId("map")).toBeDefined() // 👈
})
})
})