본문 바로가기

React Native

Expo Location API 사용해보기

이 내용은 노마드코더의 React Native로 날씨앱 만들어보기를 학습하면서 작성한 글이다.

 

오늘은 React Native로 날씨앱을 만들기 위해서 Location API를 사용해볼 것이다.

즉, 유저가 현재 어디에 있는지 API를 사용해서 정보를 가져오는 것이다. 

이번 내용은 React Native와는 연관 없는 내용으로 이루어져있다. 

하지만, API를 가져오고 사용하는 방법을 공부하면 앞으로 개발할 때 도움이 많이 되므로 한 번쯤 학습해보는 건 나쁘지 않다고 생각하는 편이다.

 

그럼 시작해볼까요?!

 

1. Expo Location 설치해주기

API는 Expo의 Location을 사용할 것이니 해당 Expo Location을 설치해주는 게 첫 번째이다.

해당 내용에 관련한 공식 문서는 아래와 같으니 참고하면 좋을 것 같다!

https://docs.expo.dev/versions/v44.0.0/sdk/location/

 

Location - Expo Documentation

Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React.

docs.expo.dev

 

설치는 Expo 공식 문서에 나오있는 것처럼 아래 명령어를 사용해서 설치해줄 것이다.

expo install expo-location

내가 현재 작업하고 있는 프로젝트 위치로 와서 터미널을 연 후 설치해주면 된다.

 

2. 선언 및 변수 셋팅해주기

import React, { useState, useEffect } from 'react';
import * as Location from 'expo-location';

..... 이하 생략

export default function App() {
	
    const [location, setLocation] = useState();
 	const [ok, setOk] = useState(true);
 	const ask = async => {
    	
  	}

 	useEffect(() => {
    	ask();
  	}, [])

}

 

3. 권한 요청하기

권한 요청은 requestPermissionsAsync() 메서드를 사용해줄 것이다.

 

기본적으로 코딩은 공식 문서에 있는 Usage 쪽에 나와있는 예시를 기반으로 개발이 될 것이니 참고하면 문서랑 같이 확인하면서 개발하면 더 도움이 많이 될 것 같다.

export default function App() {
	
    const [location, setLocation] = useState();
    const [ok, setOk] = useState(true);
    const ask = async () => {
      const permission = await Location.requestPermissionsAsync();
    };

    useEffect(() => {
      ask();
    }, []);

}

해당 메서드를 사용하고 난 후 저장을 한 후, expo go 애플리케이션에 자동 반영된 내용을 확인해보자.

나의 위치 반영을 허용할 것인지에 대한 내용이 뜨는 것을 확인할 수 있을 것이다.

그리고 허용함을 누르면 오류가 발생할 것이다.

해당 오류는 지금 사용한 requestPermissionsAsync() 권한 요청 메서드가 사용 불가능하다는 걸 알려주는 경고이다.

또한, 현재 사용한 메서드를 대신하여 background 혹은 foreground 메서드 중 하나를 선택해서 사용 가능하다는 것을 알려주고 있다.

그럼, 공식 문서를 보면서 두 개의 차이점은 무엇이고 어떤 걸 사용할 지 선택해보면 된다.

foreground는 앱 사용 중에만, background는 언제든지 허용이다.

foreground 메서드를 사용해서 권한을 요청해보자!

export default function App() {
	
    const [location, setLocation] = useState();
    const [ok, setOk] = useState(true);
    const ask = async () => {
      const permission = await Location.requestForegroundPermissionsAsync();
    };

    useEffect(() => {
      ask();
    }, []);

}

 

 

4. 사용자가 허용했는지, 안했는지의 값을 가져오기

권한 허용 부분을 완료하였으니 이제 사용자가 설정한 위치 허용 여부의 정보를 가져올 것이다.

const ask = async () => {
    const {granted} = await Location.requestForegroundPermissionsAsync();
    if(!granted) {
      setOk(false);
    }
  };

granted는 허용 여부에 대한 값을 가지고 있는 변수이다.

만약, grated가 false라면 위치를 허용하는 걸 거부했다는 의미이므로 setOk부분에 false로 설정해줄 것이다.

 

5. 사용자의 위치 정보 가져오기

사용자의 현재 위치를 가져오는 내용도 공식 문서에서 확인해볼 수 있다.

const ask = async () => {
    const {granted} = await Location.requestForegroundPermissionsAsync();
    if(!granted) {
      setOk(false);
    }
    
    const { coords:{latitude, longitude} } = await Location.getCurrentPositionAsync({accuracy: 5});

  };

해당 메서드를 사용해서 경도와 위도 값을 가지고 올 수 있다.

경도와 위도 값을 가지고 왔으면 경도, 위도 값에 맞는 위치를 파악할 수 있는 API를 사용해서 정보를 요청해야한다.

해당 메서드는 reverse 메서드이다.

공식 문서를 보면 알 수 있다시피 위도와 경도 값, 그리고 구글맵의 사용 여부 값을 넘겨야한다.

.. 이하 생략
const { coords:{latitude, longitude} } = await Location.getCurrentPositionAsync({accuracy: 5});

const location = await Location.reverseGeocodeAsync({latitude, longitude}, {useGoogleMaps: false});

location에는 내가 있는 위치의 도시명을 담겨져 있을 것이다.

location은 array로 이루어져있으므로 가져올 때는 array형식으로 가져와야한다.

console.log(location[0].city);

 

6. View 화면 수정하기

그럼, 이제 Seoul로 하드코딩 되어있던 부분을 수정해주자.

import * as Location from 'expo-location';
import React, { useState, useEffect } from 'react';
import { Text, View, StyleSheet, ScrollView, Dimensions } from 'react-native';

const { width: SCREEN_WIDTH } = Dimensions.get("window");

export default function App() {
  const [city, setCity] = useState("Loading...");
  const [location, setLocation] = useState();
  const [ok, setOk] = useState(true);
  const ask = async () => {
    const {granted} = await Location.requestForegroundPermissionsAsync();
    if(!granted) {
      setOk(false);
    }
    const { coords:{latitude, longitude} } = await Location.getCurrentPositionAsync({accuracy: 5});
    const location = await Location.reverseGeocodeAsync(
      {latitude, longitude}, 
      {useGoogleMaps: false}
    );
    setCity(location[0].city);
  };

  useEffect(() => {
    ask();
  }, []);

  return 
  	<View style={styles.container}>
      <View style={styles.city}>
        <Text style={styles.cityName}>{city}</Text>
      </View>
      
      ... 이하 생략
      
    </View>;
}

Loading... 이 떴다가 바로 위치 정보 값을 가져와서 출력하고 있는 것을 볼 수 있다.

 

사용자의 위치 값을 가져오는 개발을 완료하였다!

다음 시간에는 날씨 API를 사용해보고, 위치에 맞는 날씨 API 정보를 요청하는 부분을 개발할 것이다.

SMALL