inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

배달앱 클론코딩 [with React Native]

네이버맵 사용자 위치 추적

659

김정숙

작성한 질문수 13

0

안녕하세요

네이버맵 연동 시 아래 사진과 같은 기능을 연동하려고 합니다KakaoTalk_Photo_2024-04-09-13-42-54.jpeg

method 확인 시

setLocationTrackingMode <- 해당 method 인 것 같은데.. 연동 방식을 잘 모르겠습니다.

 

도움 부탁드립니다.

 

고맙습니다.

react-native

답변 1

0

제로초(조현영)

function MyMap() {
	const ref = useRef(null);

	const changeTrackingMode = () => {
		ref.current.showsMyLocationButton(true); // 또는
		ref.current.setLocationTrackingMode(TrackingMode.Follow) // 트래킹 모드 설정
	}

	return <>
		<NaverMapView
			ref={ref}
			mapType={1}
			style={styles.nMapContainer}
		/>
	</>

이런 식으로 ref.current 통해서 호출하실 수 있습니다.

0

김정숙

아래 전체 소스입니다

모드 변경 버튼 클릭 시 반응이 없는 것 같습니다.

import {
  Alert,
  Dimensions,
  Linking,
  Platform,
  SafeAreaView,
  Text,
  TouchableOpacity,
  View,
} from 'react-native';
import NaverMapView, {Marker, Path, TrackingMode} from 'react-native-nmap';
// import LocationTerms from "./LocationTerms";
import {useEffect, useRef, useState} from 'react';
import {check, PERMISSIONS, RESULTS} from 'react-native-permissions';
import Geolocation from 'react-native-geolocation-service';

function NMap() {
  const handleMapClick = (e: any) => {
    console.log('latitude : ', e.latitude);
    console.log('latitude : ', e.longitude);
  };

  /** 장소 저장 */
  function handleLocationSave(e: any) {
    // console.log('e : ', e);
    // 현재 위치 조회
  }

  const ref = useRef(null);

  const handleChangeMode = () => {
    // console.log('ref : ', ref.current.setLocationTrackingMode);
    // console.log('ref : ', ref.current.showsMyLocationButton);
    ref.current.showsMyLocationButton(true);
    ref.current.setLocationTrackingMode(TrackingMode.Follow);
  };

  const [myPosition, setMyPosition] = useState<{
    latitude: any;
    longitude: any;
  } | null>(null);

  function getMyPosition() {
    Geolocation.getCurrentPosition(
      position => {
        console.log('position : ', position);
        setMyPosition({
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
        });
      },
      err => {
        console.log('error : ', err);
        Alert.alert('위치정보 권한 오류!', '위치정보 권한을 허용해주세요!', [
          // {
          //   text: 'Cancel',
          //   onPress: () => console.log('Cancel Pressed'),
          //   style: 'cancel',
          // },
          {
            text: '확인',
            onPress: () => {
              Linking.openSettings();
              // navigation.pop();
            },
          },
        ]);
      },
      {
        enableHighAccuracy: true,
        timeout: 20000,
        maximumAge: 10000,
      },
    );
  }

  const handleAndroidPermissions = () => {
    console.log('os : ', Platform.OS);
    console.log('version : ', Platform.Version);
    if (Platform.OS === 'android' && Platform.Version >= 23) {
      check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION)
        .then(result => {
          console.log('check location', result);
          if (result === RESULTS.BLOCKED || result === RESULTS.DENIED) {
            Alert.alert(
              '이 앱은 위치 권한 허용이 필요합니다.',
              '앱 설정 화면을 열어서 항상 허용으로 바꿔주세요.',
              [
                {
                  text: '네',
                  onPress: () => {
                    Linking.openSettings();
                    // navigation.popToTop();
                  },
                },
                {
                  text: '아니오',
                  onPress: () => {
                    // navigation.popToTop();
                  },
                  style: 'cancel',
                },
              ],
            );
          } else {
            // 위치정보 조회
            getMyPosition();
          }
        })
        .catch(console.error);
    }
  };

  useEffect(() => {
    if (Platform.OS === 'android') {
      handleAndroidPermissions();
    }
  }, []);

  return (
    <SafeAreaView style={{flex: 1, backgroundColor: '#ff5800'}}>
      <View
        style={{
          flex: 1,
          width: Dimensions.get('window').width,
          height: Dimensions.get('window').height,
          // marginTop: 10,
        }}>
        {myPosition && (
          <NaverMapView
            ref={ref}
            // mapType={1}
            style={{width: '100%', height: '100%'}}
            zoomControl={true}
            // showsMyLocationButton={true}
            onMapClick={handleMapClick}
            center={{
              zoom: 15,
              tilt: 10,
              // latitude: (lat1 + lat9) / 2,
              // longitude: (lng1 + lng9) / 2,
              latitude: Number(myPosition?.latitude),
              longitude: Number(myPosition?.longitude),
            }}
          />
        )}
      </View>

      <TouchableOpacity
        onPress={handleChangeMode}
        style={{paddingVertical: 15}}>
        <Text style={{textAlign: 'center', fontWeight: 'bold', color: '#fff'}}>
          모드 변경
        </Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
}
export default NMap;

0

제로초(조현영)

클릭할 때 handleChangeMode 내부 console.log는 기록되나요?

0

김정숙

네 잘 찍힙니다

ref :  {"current": {"_reactInternalInstance": {}, "_reactInternals": {"_debugHookTypes": null, "_debugNeedsRemount": false, "_debugOwner": [FiberNode], "_debugSource": undefined, "actualDuration": 2.820422001183033, "actualStartTime": 16016914.962003, "alternate": null, "child": [FiberNode], "childLanes": 0, "deletions": null, "dependencies": null, "elementType": [Function NaverMapView], "flags": 513, "index": 0, "key": null, "lanes": 0, "memoizedProps": [Object], "memoizedState": null, "mode": 2, "pendingProps": [Object], "ref": [Circular], "return": [FiberNode], "selfBaseDuration": 0.4006919991225004, "sibling": null, "stateNode": [Circular], "subtreeFlags": 512, "tag": 1, "treeBaseDuration": 0.43930700048804283, "type": [Function NaverMapView], "updateQueue": [Object]}, "animateToCoordinate": [Function anonymous], "animateToCoordinates": [Function anonymous], "animateToRegion": [Function anonymous], "animateToTwoCoordinates": [Function anonymous], "context": {}, "dispatchViewManagerCommand": [Function anonymous], "handleOnCameraChange": [Function anonymous], "handleOnMapClick": [Function anonymous], "nodeHandle": 307, "props": {"center": [Object], "onMapClick": [Function handleMapClick], "showsMyLocationButton": true, "style": [Object], "zoomControl": true}, "ref": {"_children": [Array], "_internalFiberInstanceHandleDEV": [FiberNode], "_nativeTag": 307, "viewConfig": [Object]}, "refs": {}, "resolveRef": [Function anonymous], "setLayerGroupEnabled": [Function anonymous], "setLocationTrackingMode": [Function anonymous], "showsMyLocationButton": [Function anonymous], "state": null, "updater": {"enqueueForceUpdate": [Function enqueueForceUpdate], "enqueueReplaceState": [Function enqueueReplaceState], "enqueueSetState": [Function enqueueSetState], "isMounted": [Function isMounted]}}}

 

위 내용으로 찍힙니다

0

제로초(조현영)

버튼을 눌렀을 때 지도가 내 위치로 이동하지도 않고, 오른쪽에 내 위치 버튼이 뜨지도 않는 건가요?

0

김정숙

한가지 애매한 부분은 ..

image

위 사진처럼 ref.current 의 2가지 method 가 비활성 상태로 되어있습니다.

0

김정숙

버튼을 눌렀을 때 지도가 내 위치로 이동하지도 않고, 오른쪽에 내 위치 버튼이 뜨지도 않는 건가요?

<== 네 아무런 반응이 없는 상태입니다

0

김정숙

image

위에 전달해주신 소스 기준으로 다른 부분 제외하고 최소화한 소스입니다.

 

image

위 화면에서 'Tracking Mode' 버튼 클릭해도 아무런 변화없이 위 화면 그대로 머물러 있습니다

 

changeTrackingMode 함수에서는 console.log 잘 찍힙니다.

 

0

제로초(조현영)

지금 빨갛게 뜨는 이유는 useRef에 타이핑이 안 되어있어서 그렇습니다.

useRef<NaverMapViewProps>(null) 이런 식으로 하면 타이핑 됩니다.

라이브러리가 현재 유지보수가 안 되고 있어서 라이브러리 버그일 수도 있습니다.

0

김정숙

타이핑은 잘 맞췄습니다.

그럼 혹시.. 다른 방법을 찾아야 하는 걸까요? ㅠ

0

제로초(조현영)

이 부분은 사실 네이티브단까지 들여다보긴 해야합니다. setLocationTrackingMode 함수 호출이 안드로이드 단으로 전파되는지를 체크해야하는데 네이티브쪽을 모르면 이 과정이 어렵긴 합니다 ㅠㅠ

0

제로초(조현영)

처음부터 showsMyLocationButton이랑 locationTrackingMode를 NaverMapView에 props로 넣으면 그건 동작하나요?

0

김정숙

image

showsMyLocationButton <- 해당 속성은 잘 동작합니다.

locationTrackingMode <- 해당 속성은 없는 속성으로 확인됩니다ㅠ

0

제로초(조현영)

아니면 저기 onInitialized 저기서 하는건 잘 돌아가나요?

0

김정숙

onInitialized <- 해당 method 에서 console.log 는 잘 찍히는데..

ref.current?.setLocationTrackingMode(TrackingMode.Follow);
ref.current?.showsMyLocationButton(true);

위 2가지 속성은 여전히 아무 반응이 없습니다.ㅠ

앱실행시 네이버맵 [401] 에러

0

960

2

스타일링 라이브러리

0

147

2

expo, cli 선택 중에 고민이 있습니다.

0

167

2

JDK 버전이 달라도 괜찮나요?

0

223

2

dimenstion usewindowdeminstion

0

121

3

[맥 전용]환경 설정하기 1편 & [맥 전용]환경 설정하기 2편의 영상이 안나옵니다.

0

209

1

jdk11 버전과 gradle 버전의 호환성 관련 질문드립니다.

0

399

2

강의 외 질문입니다!

0

157

2

react native랑 맞는 ui 라이브러리 어떤게 좋을까요?

0

1489

2

react native와 spring boot 연결

0

353

1

java가 아닌 .kt에서 code push 에러가 발생합니다.

0

210

2

flipper 239 에러가 발생합니다.

0

163

2

package.json에 /lib/panino.js 문제입니다.

0

465

2

window - mac 협업 과정 질문합니다

0

214

1

ios 빌드 중 RCTBridgeDelegate.h import 오류

0

289

2

ios 앱 빌드 중 hermesEnabled 관련 오류발생

0

238

2

Socket 연결시 질문 드립니다.!

0

151

2

wifi 환경에서 axios 통신이 로컬서버에서 안됩니다.

0

425

2

iOS render error 질문드립니다.

0

410

2

iOS 가상머신 오류

0

164

2

npc react init 명령어 실행시 발생되는 오류

0

220

1

nom start 시 오류

0

116

1

NextJS 기반으로 만들어서 웹뷰 React Native로 배포 가능한가요?

0

996

2

안드로이드 rn75 버전에 맞게 설정 중에 android13 다운로드에 대해서 막혔습니다!

0

183

2