Project/softsphere

[React Native] Location (feat. Expo API)

written by yunwon 2021. 10. 19. 08:41

 

 

 

애플리케이션 만들 때 한번씩은 만든다는 날씨 앱 🌞 !

React Native 학습 중에도 빠지지 않고 등장했다.

 

늘 그렇듯 OpenWeather API 를 사용하면서,

사용자의 위치를 토대로 날씨 정보를 불러왔다.

여기서 " 사용자의 위치 " 를 받기 위해 expo 가 만든 Location API 를 활용했다.

 

나름 날씨 앱을 제작하면서 복잡한 (?) 부분이었기에

짚고 넘어가고자 한다.

 

 


 

Geolocation

본격적으로 expo 에서 제공하는 location API 에 대해 알아보기 전에,

React Native 에서 제공된 (현재는 커뮤니티가 관리하는) geolocation 에 대해 알아보자.

 

사용하는 방법으로는 아래 코드 블럭과 같이 직접 설치해주거나,

navigator.geolocation 을 통해 임포트 없이도 사용 가능하다.

// install
$ npm install @react-native-community/geolocation --save
$ react-native link @react-native-community/geolocation

// usage
import Geolocation from '@react-native-community/geolocation';

Geolocation.getCurrentPosition(info => console.log(info));

하지만 아래와 같이 expo의 location에 비해

사용 가능한 메서드가 다양하지는 않다.

  • setRNConfiguration
  • requestAuthorization
  • getCurrentPosition : 현재 위치 가져오기
  • watchPosition : 위치 지켜보기
  • clearWatch : 위치 보기 지역 해제
  • stopObserving : 관찰 정지

 

geolocation 에 대해 더 자세한 내용은

📜공식 문서를 참조하자

 

 


 

Expo's Location

본격적으로 expo 에서 제공하는 location 에 대해 보자.

우선 직전에 설명한 geolocation 보다 다양한 기능을 제공한다.

 

예시로 권한 (permission) 인증을 받거나,

기능을 enable / disable 하거나,

현재 위치를 얻을 수도 있고 ㆍ 위치를 탐색할 수도 있고,

gps 또는 network 가 사용 가능한지 알려주거나,

주소 문자열로 위도 ㆍ 경도를 반환해주거나 그 반대로 해주거나,

background location (자동 위치 추적) 을 해주거나,

사용자가 어떤 지역에 들어갔을 때 ㆍ 떠났을 때를 알려주거나,

 

등등 정말 많은 기능들이 내포되어있다.

디폴트로 설치되어있지 않기에 아래와 같은 설치 작업을 해주어야 한다.

$ expo install expo-location

 

 

 


 

Location 사용법

import * as Location from 'expo-location';

const API_KEY = "YOUR_WEATHER_API_KEY";

export default function App() {
  const [city, setCity] = useState("Loading...");
  const [days, setDays] = useState([]);
  const [ok, setOk] = useState(true);
  const getWeather = 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].region);
    const response = await fetch(`https://api.openweathermap.org/data/2.5/onecall?lat=${latitude}&lon=${longitude}&exclude=alerts&appid=${API_KEY}&units=metric`);
    const json = await response.json();
    setDays(json.daily);
  };

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

위 코드는 이번 프로젝트에서

 

1) 사용자에게 위치 권한을 허용 받아,

2) 현재 사용자 위치 기반 위경도 값을 받고,

3) 그 값을 주소 문자열로 변환한다.

 

이같은 프로세스를 코드로 작성한 것이다.

📜공식문서에서 볼 수 있듯이 정말 많은 기능들이 있지만,

전부 살펴보기는 어렵기에 위 기능들 중점으로 사용법을 익혀보자 !

 

(1) 권한 인증 받기

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

우선 사용자의 현재 위치를 받아오기 위해서 우리의 앱은,

사용자에게 위치 서비스 권한 인증을 받아야 한다.

 

그를 위해 Location.requestPermissionAsync() 가 쓰인다.

하지만 이 메서드는 더이상 사용되지 않고 아래 두가지 갈래로 업데이트되었다.

  • requestForegroundPermissionsAsync()
  • requestBackgroundPermissionsAsync()

그 중에서 foreground 를 사용하여,

앱을 사용 중에만 사용자의 위치를 받아오도록 설정한다.

 

위 코드의 if 문은 권한을 허용해준 경우 위치 값이 ok 되도록 하였다.

 

 

(2) 현재 위치 받기

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

사용자의 현재 위치를 받아오기 위해서는

Location.getCurrentPositionAsynce() 를 사용한다.

이는 Async 함수 이므로 await 가 필요하다.

 

여기서는 위치 값을 얼마나 정확하게 받아올지 작성할 수 있는데,

accuracy <- 를 사용하여 작성한다. (값이 커질수록 정확하다)

 

 

 

(3) 주소 변환

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

위에서 위경도로 받아온 값들을 사용할 수 있도록,

주소로 변환해주는 작업을 하기 위해 Location.reverseGeocodeAsync() 를 사용한다.

 

이제 이렇게 해주면 !

아래와 같은 형식으로 location 객체에 들어오게 된다.

원하는 데이터를 선택하여 사용해보자 🎉

Array [
  Object {
    "city": null,
    "country": "대한민국",  
    "district": "XX구",   
    "isoCountryCode": "KR", 
    "name": "번지수",  
    "postalCode": "우편번호",
    "region": "서울특별시",
    "street": "XX동",
    "subregion": null,
    "timezone": null,
  },
 }

 

 

 

 

 

 

© 참고

https://docs.expo.dev/versions/v42.0.0/sdk/location/ (Expo Location 공식 문서)

Nomad Coder Location 강의

react native 날씨 앱 따라 만들기