본문 바로가기
리액트(React)

React Native - 위치기반 날씨앱 만들기(1)

by 즐거운코딩 2024. 11. 9.
반응형

핸드폰 위치 기반으로 현재 위치의 날씨 정보를 표출하는 간단한 앱을 만들어 보겠습니다.

이를 통해 Expo 에서 핸드폰 위치를 가져오는 방법과 Open WeatherMap의 API 를 이용하여 현재 위치기반으로 날씨 정보를 가져와서 표출하고자 합니다.

 

1.  프로젝트 생성 및 라이브러리 설치

  • 앱명칭 : RN-weather 
    • 실행 : npx create-expo-app RN-weather --template blank
    • 참고 : --template blank 옵션 : javascript 로 개발
  • 핸드폰 위치조회 라이브러리 설치
    • npx expo install expo-location

2.  Expo Location 관련 주요 기능

  • 현재 위치 가져오기
    • 핸드폰 현재 위치를 한번 가져옴
  • 위치 자동업데이트(subscribe)
    • 실시간으로 위치변경사항 추적 기능
  • 백그라운드 위치 추적
    • 앱이 백그라운드 상태일 때 위치 추적
  • 지오펜싱
    • 특정 지역 진입 또는 진출시 알람 제공
  • 사용자 위치를 사용하기 위해서는 개인정보 보호를 위해 사전에 명시적 권한 요청이 필수 !!!

👉 공식문서 확인

https://docs.expo.dev/versions/latest/sdk/location/

 

Location

A library that provides access to reading geolocation information, polling current location or subscribing location update events from the device.

docs.expo.dev

 

 

3.  주요 기능 함수

  • 사전 동의 : requestPermissionsAsync()
    권한 거부시 대체 로직 구현 필수 (예: 수기 입력 또는 서비스 이용 제한 안내 등)
import * as Location from 'expo-location';

const requestPermission = async () => {
  const { status } = await Location.requestForegroundPermissionsAsync();
  if (status !== 'granted') {
    console.log('Permission to access location was denied');
    return;
  }
};
  • 현재위치 가져오기 : getCurrentPosisionAsync()
const getLocation = async () => {
  let location = await Location.getCurrentPositionAsync({});
  console.log(location);
};
  • 위치 따라가며 업데이트하기 : watchPositionAsync()
    🖐🏻 업데이트 주기(timeInterval)를 적절히 설정하여 불필요한 API 호출을 최소화 해야 함
const subscribeToLocationUpdates = async () => {
  await Location.watchPositionAsync(
    { accuracy: Location.Accuracy.High, timeInterval: 5000 },
    (location) => {
      console.log('New location:', location);
    }
  );
};
  • 백그라운드로 위치 추적 : startLocationUpdatesAsync()
    🖐🏻  백그라운드 지속적인 위치수집시 배터리 소모가 크므로 주의 사용 필요
          iOS에서는 추가적인 권한 설정 필요
import * as TaskManager from 'expo-task-manager';

const LOCATION_TASK_NAME = 'background-location-task';

TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
  if (error) {
    console.error(error);
    return;
  }
  if (data) {
    const { locations } = data;
    console.log('Received new locations', locations);
  }
});

const startBackgroundTracking = async () => {
  await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
    accuracy: Location.Accuracy.Balanced,
    timeInterval: 5000,
    foregroundService: {
      notificationTitle: 'Using your location',
      notificationBody: 'To turn off, go back to the app and switch something off.',
    },
  });
};

 

  • 유저가 특정지역 벗어날 때 알림(geofencing) : startGeofencingAsync(), stopGeofencingAsync()
const startGeofencing = async () => {
  await Location.startGeofencingAsync('geofence-task', [
    {
      identifier: 'my-location',
      latitude: 37.123,
      longitude: -122.456,
      radius: 50, // meters
    },
  ]);
};

TaskManager.defineTask('geofence-task', ({ data: { eventType, region }, error }) => {
  if (error) {
    console.error(error);
    return;
  }
  if (eventType === Location.GeofencingEventType.Enter) {
    console.log("You've entered region:", region);
  } else if (eventType === Location.GeofencingEventType.Exit) {
    console.log("You've left region:", region);
  }
});
플랫폼에 따른 구현 및 승인 방식에 차이가 있으므로 실제 기기 테스트가 필수 !!!

 

4.  날씨 앱 사용 위한 기본 라이브러리 살펴보기

  • 현재 위치 가져오기
    • 함수 : getCurrentPosisionAsync({accuracy : 5})
    • accuracy 옵션에 대한 설명
      • lowest 1 : Accurate to the nearest three kilometers
      • low 2 : Accurate to the nearest kilometer
      • balanced 3 : Accurate to within one hundred meters.
      • high 4 : Accurate to within ten meters of the desired target.
      • highest 5 : The best level of accuracy available.
      • best for navigation 6 : The highest possible accuracy that uses additional sensor data to facilitate navigation apps.
      • 🖐🏻 높은 정확도 설정은 배터리 소모가 크므로 필요에 따라 적절히 조절 
  • 경위도 위치로 주소정보 가져오기
    • const location = await Location.reverseGeocodeAsync({ latitude, longitude }, { useGoogleMaps: false });
    • return 값 예시
       [{"city": null, "country": "대한민국", "district": "양천구", "formattedAddress": "대한민국 서울특별시 양천구 남부순환로 83길 1", "isoCountryCode": "KR", "name": "83길 1", "postalCode": null, "region": "서울특별시", "street": null, "streetNumber": "83길 1", "subregion": null, "timezone": null}]
      • loaction[0].district  지정시 "양천구" 정보를 가져옴

 

다음 포스트에서 날씨정보 API 가져오기와 전체 샘플 코드 및 화면에 대해 보여주도록 하겠습니다.

반응형