React Native Naver Map | MJ Studio


React Native Naver Map

NPM downloads NPM version Android SDK version iOS SDK version License

Bring Naver Map to Your React Fingertips

preview

![IMPORTANT]

2.4.x 버전뢀터 AI NAVER APIμ—μ„œ 제곡되던 지도 APIκ°€ μ•„λ‹Œ μƒˆλ‘­κ²Œ μΆœμ‹œλœ Maps 단독 μƒν’ˆμ΄ μ§€μ›λ©λ‹ˆλ‹€.

Highlights

1. New Architecture Fabric

Support Table

React Native Naver Map React Native Note
2.1.0 0.74 Drop Bridge Support & 0.74 required
2.x New Architecture Only Drop Old Architecture Support, You should turn off bridgeless if want to render http web image marker
<2.x Old Architecture + New Architecture

[!IMPORTANT] 2.x버전뢀턴 New Architectureμ—μ„œλ§Œ λ™μž‘ν•©λ‹ˆλ‹€. Fabric을 ν™œμ„±ν™”ν•˜μ§€ μ•Šμ€ ν”„λ‘œμ νŠΈμ—μ„œλŠ” 1.x 버전을 μ‚¬μš©ν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€. μžμž˜ν•œ κΈ°λŠ₯ 말고 μ°¨μ΄λ‚˜λŠ” 뢀뢄은 μ—†κ³  1.xλ²„μ „μ—μ„œλ„ μΆ©λΆ„νžˆ ν•„μš”ν•œ κΈ°λŠ₯λ“€λ‘œ 지도앱을 ꡬ좕할 수 μžˆμŠ΅λ‹ˆλ‹€.

2. Detailed API Documentation

거의 λͺ¨λ“  νƒ€μž…μ΄ μ„€λͺ…λ˜μ–΄ μžˆλŠ” API Docsλ₯Ό κ΅¬μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

μ΅œλŒ€ν•œ 가독성을 μ‚΄λ ΈμœΌλ©° component μͺ½μ—μ„œ μ›ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈμ˜ νƒ€μž…κ³Ό Prop및 Ref둜 μ‚¬μš©λ²•μ„ 확인 κ°€λŠ₯ν•©λ‹ˆλ‹€.

3. Expo Support

expo config plugin을 μ‚¬μš©ν•΄ Expoν™˜κ²½μ—μ„œλ„ μ†μ‰½κ²Œ 아킀텍쳐에 상관없이 λΉŒλ“œν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Expo Go, Snack에선 μ‚¬μš©ν•˜μ§€ λͺ»ν•˜μ§€λ§Œ development build, production ν™˜κ²½μ—μ„œ μ†μ‰½κ²Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

4. Marker Performance + Variants

[!IMPORTANT] [iOS, Android] x [new arch, old arch] x [debug, release] 총 8κ°€μ§€ μ‘°κ±΄μ—μ„œ λͺ¨λ‘ μ •μƒμ μœΌλ‘œ λ Œλ”λ§ λ˜λŠ” 것을 ν…ŒμŠ€νŠΈν–ˆμŠ΅λ‹ˆλ‹€.

  • 넀이버 λ§΅ 제곡 κΈ°λ³Έ 심볼 (symbol)
  • React Nativeν”„λ‘œμ νŠΈμ˜ 둜컬 이미지 λ¦¬μ†ŒμŠ€
  • μ„±λŠ₯ μ΅œμ ν™”λ₯Ό μœ„ν•œ λ„€μ΄ν‹°λΈŒ ν”„λ‘œμ νŠΈμ˜ 둜컬 이미지 λ¦¬μ†ŒμŠ€ - Android(Drawable), iOS(Bundle Asset)
  • HTTP λ„€νŠΈμ›Œν¬ 웹이미지
  • children으둜 μ „λ‹¬ν•˜λŠ” React Native Custom View

5. Seamless API porting from Native Naver Map SDK

μ΅œμ‹  λ²„μ „μ˜ SDKλ₯Ό μ§€μ›ν•˜λ©° Props와 Commandλ“€λ‘œ Naver Map의 μ΅œμ‹  κΈ°λŠ₯을 μ‘°μž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Install

# npm
npm install --save @mj-studio/react-native-naver-map

# yarn
yarn add @mj-studio/react-native-naver-map

# expo
npx expo install @mj-studio/react-native-naver-map

For ios, you should install pods

Android

더 μžμ„Έν•œ 섀정은 곡식 λ¬Έμ„œλ₯Ό μ°Έκ³ ν•΄μ£Όμ„Έμš”.

1. Maven repository import

Import Naver SDK Maven Repository to android/build.gradle.

allprojects {
repositories {
maven {
url "https://repository.map.naver.com/archive/maven"
}
}
}

2. Add Naver SDK key to AndroidManifest.xml

<manifest>
<application>
<meta-data
android:name="com.naver.maps.map.NCP_KEY_ID"
android:value="YOUR_CLIENT_ID_HERE" />
<!-- (legacy) 4μ›” 17일 이전에 AI NAVER APIλ₯Ό μ‚¬μš©ν•˜λ˜ 지도 API 고객 μ „μš© -->
<!-- https://www.ncloud.com/support/notice/all/1930?searchKeyword=map&page=1 -->
<meta-data
android:name="com.naver.maps.map.CLIENT_ID"
android:value="YOUR_CLIENT_ID_HERE" />
</application>
</manifest>

3. (Optional) Request location permission to AndroidManifest.xml

Currently, this package will request location permission for showing user's current location.

<manifest>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
# optional for background location
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
</manifest>

μžμ„Έν•œ κΆŒν•œμ— κ΄€λ ¨λœ λ‚΄μš©μ€ μ•„λž˜μ— κΈ°μž¬λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

iOS

더 μžμ„Έν•œ 섀정은 곡식 λ¬Έμ„œλ₯Ό μ°Έκ³ ν•΄μ£Όμ„Έμš”.

1. Set Naver SDK key to info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NMFNcpKeyId</key>
<string>YOUR_CLIENT_ID_HERE</string>
<!-- (legacy) 2025.04.17 이전에 AI NAVER APIλ₯Ό μ‚¬μš©ν•˜λ˜ 지도 API 고객 μ „μš© -->
<!-- https://www.ncloud.com/support/notice/all/1930?searchKeyword=map&page=1 -->
<key>NMFClientId</key>
<string>YOUR_CLIENT_ID_HERE</string>
<dict>
<plist>

2. (Optional) Set location permission usage description to info.plist

Currently, this package will request location permission for showing user's current location.

<plist version="1.0">
<dict>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>{{usage description}}</string>
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
<key>{{your purpose key}}</key>
<string>{{usage description}}</string>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>{{usage description}}</string>
</dict>
</plist>

μžμ„Έν•œ κΆŒν•œμ— κ΄€λ ¨λœ λ‚΄μš©μ€ μ•„λž˜μ— κΈ°μž¬λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

Expo

1. Add expo-build-properties package

This is for inject naver maven repository.

npx expo install expo-build-properties

2. Add Config Plugin into app.json

{
...
"plugins": [
[
"@mj-studio/react-native-naver-map",
{
"client_id": "{{Naver Map Client Key}}",
// (optional, you can set with expo-location instead of this package)
"android": {
"ACCESS_FINE_LOCATION": true,
"ACCESS_COARSE_LOCATION": true,
"ACCESS_BACKGROUND_LOCATION": true
},
// (optional, you can set with expo-location instead of this package)
"ios": {
"NSLocationAlwaysAndWhenInUseUsageDescription": "{{ your location usage description }}",
"NSLocationWhenInUseUsageDescription": "{{ your location usage description }}",
"NSLocationTemporaryUsageDescriptionDictionary": {
"purposeKey": "{{ your purpose key }}",
"usageDescription": "{{ your location usage description }}"
}
}
}
],
[
"expo-build-properties",
{
"android": {
"extraMavenRepos": ["https://repository.map.naver.com/archive/maven"]
}
}
],
...
]
}

ExpoλŠ” μœ„μ—μ„œ μ„€λͺ…λœ Android, iOS의 섀정법이 ν•„μš”ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μžμ„Έν•œ κΆŒν•œμ— κ΄€λ ¨λœ λ‚΄μš©μ€ μ•„λž˜μ— κΈ°μž¬λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

Example

const jejuRegion: Region = {
latitude: 33.20530773,
longitude: 126.14656715029,
latitudeDelta: 0.38,
longitudeDelta: 0.8,
};
...

<NaverMapView
ref={ref}
style={{ flex: 1 }}
mapType={mapType}
layerGroups={{
BUILDING: true,
BICYCLE: false,
CADASTRAL: false,
MOUNTAIN: false,
TRAFFIC: false,
TRANSIT: false,
}}
initialRegion={jejuRegion}
isIndoorEnabled={indoor}
symbolScale={symbolScale}
lightness={lightness}
isNightModeEnabled={nightMode}
isShowCompass={compass}
isShowIndoorLevelPicker={indoorLevelPicker}
isShowScaleBar={scaleBar}
isShowZoomControls={zoomControls}
isShowLocationButton={myLocation}
isExtentBoundedInKorea
logoAlign={'TopRight'}
locale={'ja'}
onInitialized={() => console.log('initialized!')}
onOptionChanged={() => console.log('Option Changed!')}
onCameraChanged={(args) => console.log(`Camera Changed: ${formatJson(args)}`)}
onTapMap={(args) => console.log(`Map Tapped: ${formatJson(args)}`)}
>
<NaverMapMarkerOverlay
latitude={33.3565607356}
longitude={126.48599018}
onTap={() => console.log(1)}
anchor={{ x: 0.5, y: 1 }}
caption={{
key: '1',
text: 'hello',
}}
subCaption={{
key: '1234',
text: '123',
}}
width={100}
height={100}
/>
{/* Not Working in iOS Old Architecture Yet */}
<NaverMapMarkerOverlay*
latitude={33.4165607356}
longitude={126.48599018}
onTap={() => console.log(1)}
anchor={{ x: 0.5, y: 1 }}
caption={{
key: '1',
text: 'hello',
}}
subCaption={{
key: '1234',
text: '123',
}}
width={100}
height={100}
>
<View style={{ width: 100, height: 100, backgroundColor: 'red' }} />
</NaverMapMarkerOverlay>
<NaverMapMarkerOverlay
latitude={33.2565607356}
longitude={127.8599018}
onTap={() => console.log(1)}
anchor={{ x: 0.5, y: 1 }}
caption={{
key: '1',
text: 'hello',
}}
subCaption={{
key: '1234',
text: '123',
}}
width={100}
height={100}
image={{ uri: 'https://picsum.photos/100/100' }}
/>
<NaverMapCircleOverlay
latitude={33.17827398}
longitude={126.349895729}
radius={50000}
color={'#f2f1'}
outlineColor={'#aaa'}
outlineWidth={2}
onTap={() => console.log('hi')}
/>
<NaverMapPolygonOverlay
outlineWidth={5}
outlineColor={'#f2f2'}
color={'#0068'}
coords={[
{ latitude: 33.2249594, longitude: 126.54180047 },
{ latitude: 33.25683311547, longitude: 126.18193 },
{ latitude: 33.3332807, longitude: 126.838389399 },
]}
/>
<NaverMapPathOverlay
coords={[
{ latitude: 33.5249594, longitude: 126.24180047 },
{ latitude: 33.25683311547, longitude: 126.18193 },
{ latitude: 33.3332807, longitude: 126.838389399 },
]}
width={8}
color={'red'}
progress={-0.6}
passedColor={'green'}
/>
</NaverMapView>

Usage

API Documentation

Documentation

λͺ¨λ“  μ½”λ“œμ—” JSDoc으둜 주석이 μ‚½μž…λ˜μ–΄μžˆμœΌλ―€λ‘œ Documentation없이도 κ°œλ°œμ„ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

ν•˜μ§€λ§Œ μ •ν™•νžˆ μ–΄λ–€ νƒ€μž…λ“€μ΄ 있고 μ–΄λ–€ 속성을 μ˜λ―Έν•˜λŠ”μ§€ μ›Ήμ‚¬μ΄νŠΈμ—μ„œ ν™•μΈν•˜μ‹œλ €λ©΄ Documentationλ₯Ό μ°Έκ³ ν•΄μ£Όμ„Έμš”.

Permission

기본적으둜 μ•±μ—μ„œ κΆŒν•œμ€ 직접 관리가 λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

이λ₯Ό κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄ react-native-permissions라이브러리λ₯Ό μ‚¬μš©ν•˜λŠ” μ˜ˆμ‹œλ₯Ό μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

[!TIP] Expo μ‚¬μš©μžλΌλ©΄ expo-locationλ₯Ό μ°Έκ³ ν•΄μ„œ κΆŒν•œμ„ μ‚¬μš©ν•  μ˜ˆμ •μ΄λ‹€ 라고 λͺ…μ‹œν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ μ•„λž˜ λ‚΄μš©λ“€ 쀑 λŒ€λΆ€λΆ„μ€ ν•„μš”ν•˜μ§€ μ•Šκ³ , ν•„μš”ν•œ κΆŒν•œμ΄ 무엇인지, μ–΄λ–»κ²Œ λͺ…μ‹œν•΄μ•Ό ν•˜λŠ”μ§€λ₯Ό μ‚΄νŽ΄λ³΄μ‹  λ‹€μŒ expo-locationμ—μ„œμ˜ μ‚¬μš©λ²•μ„ λ”°λ₯΄μ…”μ•Ό ν•©λ‹ˆλ‹€.

μš°μ„  νŒ¨ν‚€μ§€λ₯Ό μ„€μΉ˜ν•˜κ³  μ„€μ •ν•©λ‹ˆλ‹€.

yarn add react-native-permissions

react-native-permission의 각 ν”Œλž«νΌλ³„ μ„€μ • 방법은 μ‚¬μš©λ²•μ„ 직접 μ°Έκ³ ν•΄ Podfile(iOS), AndroidManifest.xml(Android) λ₯Ό 적절히 λ³€κ²½ν•΄μ£Όμ‹œκΈΈ λ°”λžλ‹ˆλ‹€.

iOS

iOSλŠ” λ‹€μŒκ³Ό 같은 μ„Έ κ°€μ§€μ˜ κΆŒν•œμ΄ μ—°κ΄€λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.

  • NSLocationAlwaysAndWhenInUseUsageDescription(>= iOS 11)
    • 앱이 foreground와 background λͺ¨λ‘μ—μ„œ μœ„μΉ˜ 정보에 μ•‘μ„ΈμŠ€ν•˜λŠ” 것을 ν—ˆμš©ν•©λ‹ˆλ‹€.
    • iOS 11 μ΄μƒμ—μ„œλŠ” ο»ΏNSLocationAlwaysUsageDescription λŒ€μ‹  이 ν‚€λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • NSLocationWhenInUseUsageDescription
    • 앱이 foreground에 μžˆμ„ λ•Œ (즉, μ‚¬μš©μžκ°€ activelyν•˜κ²Œ 앱을 μ‚¬μš© 쀑일 λ•Œ) μœ„μΉ˜ 정보에 μ•‘μ„ΈμŠ€ν•˜λŠ” 것을 ν—ˆμš©ν•©λ‹ˆλ‹€.
  • NSLocationTemporaryUsageDescriptionDictionary(>= iOS 14)
    • 앱이 μž„μ‹œλ‘œ μ •ν™•ν•œ μœ„μΉ˜ 정보에 μ•‘μ„ΈμŠ€ν•  수 μžˆλ„λ‘ ν—ˆμš©ν•©λ‹ˆλ‹€. μ΄λŠ” 앱이 νŠΉμ • μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” λ™μ•ˆμ—λ§Œ μ •ν™•ν•œ μœ„μΉ˜κ°€ ν•„μš”ν•œ 경우 μ‚¬μš©λ©λ‹ˆλ‹€.

[!TIP] 앱이 iOS 11미만의 κΈ°κΈ°λ₯Ό μ§€μ›ν•˜κ³  μžˆμ§€ μ•Šλ‹€λ©΄ NSLocationAlwaysUsageDescription을 κΈ°μž¬ν•˜μ§€ μ•Šμ•„λ„ λ©λ‹ˆλ‹€. λ§Œμ•½ μ§€μ›ν•œλ‹€λ©΄ 같이 μ„€μ •ν•΄μ£Όμ…”μ•Ό ν•©λ‹ˆλ‹€.

그럼 Podfileμ—μ„œ λ‹€μŒκ³Ό 같은 μ„Έ κ°€μ§€μ˜ κΆŒν•œμ„ ν—ˆμš©ν•΄μ€λ‹ˆλ‹€.

setup_permissions([
'LocationAccuracy',
'LocationAlways',
'LocationWhenInUse',
...
])

Xcodeμ—μ„œ μ•± νƒ€κ²Ÿμ˜ Signing & Capabilities νƒ­μ—μ„œ Background Modesλ₯Ό ν™œμ„±ν™”ν•˜κ³  Location updatesμ˜΅μ…˜μ„ μ„ νƒν•©λ‹ˆλ‹€.

μ΄λŠ” λ°±κ·ΈλΌμš΄λ“œμ—μ„œ μœ„μΉ˜λ₯Ό λ°›μ•„μ˜€κΈ° μœ„ν•΄ ν•„μš”ν•˜λ―€λ‘œ ν•„μš”μ—†λ‹€λ©΄ μ„€μ •ν•˜μ§€ μ•Šμ•„λ„ λ©λ‹ˆλ‹€.

Xcode config result

Android

Naver Map SDKμ—μ„œ λ‚΄λΆ€μ μœΌλ‘œ μ΄μš©ν•˜λŠ” FusedLocationSourceλŠ” μ‚¬μš©μžκ°€ isShowLocationButton prop을 true둜 μ„€μ •ν•˜λŠ” μˆœκ°„ μžλ™μœΌλ‘œ κΆŒν•œ μš”μ²­μ„ μ‹œν–‰ν•©λ‹ˆλ‹€.

AndroidλŠ” 비ꡐ적 κ°„λ‹¨ν•˜κ²Œ κΆŒν•œμ„ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ•„λž˜ κΆŒν•œλ“€λ§Œ AndroidManifest.xml에 μ‚¬μš©ν•œλ‹€κ³  λͺ…μ‹œν•˜λ©΄ λ©λ‹ˆλ‹€.

  • android.permission.ACCESS_FINE_LOCATION
    • μ •ν™•ν•œ μœ„μΉ˜ 정보 κΆŒν•œ
  • android.permission.ACCESS_COARSE_LOCATION
    • λŒ€λž΅μ μΈ μœ„μΉ˜ 정보 κΆŒν•œ
  • android.permission.ACCESS_BACKGROUND_LOCATION
    • λ°±κ·ΈλΌμš΄λ“œ μƒνƒœμ—μ„œ μœ„μΉ˜ 정보 κΆŒν•œ

μ½”λ“œμ—μ„œμ˜ κΆŒν•œ μš”μ²­

μ—¬κΈ°κΉŒμ§€μ˜ 섀정이 끝났닀면 지도가 ν•„μš”ν•œ ν™”λ©΄μ—μ„œ λ‹€μŒκ³Ό 같이 μ½”λ“œλ‘œ κΆŒν•œμ„ μš”μ²­ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

For Bare RN Project or ejected Expo (react-native-permissions)

// useEffectλŠ” λ‹¨μˆœνžˆ μ»΄ν¬λ„ŒνŠΈκ°€ mount될 λ•Œ ν˜ΈμΆœν•΄μ£ΌκΈ° μœ„ν•΄μ„œ μ‚¬μš©λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
useEffect(() => {
if (Platform.OS === 'ios') {
request(PERMISSIONS.IOS.LOCATION_ALWAYS).then((status) => {
console.log(`Location request status: ${status}`);
if (status === 'granted') {
requestLocationAccuracy({
purposeKey: 'common-purpose', // replace your purposeKey of Info.plist
})
.then((accuracy) => {
console.log(`Location accuracy is: ${accuracy}`);
})
.catch((e) => {
console.error(`Location accuracy request has been failed: ${e}`);
});
}
});
}
if (Platform.OS === 'android') {
requestMultiple([
PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION,
PERMISSIONS.ANDROID.ACCESS_BACKGROUND_LOCATION,
])
.then((status) => {
console.log(`Location request status: ${status}`);
})
.catch((e) => {
console.error(`Location request has been failed: ${e}`);
});
}
}, []);

For Expo (expo-location)

import * as Location from 'expo-location'

...
useEffect(() => {
(async () => {
try {
const {granted} = await Location.requestForegroundPermissionsAsync();
/**
* Note: Foreground permissions should be granted before asking for the background permissions
* (your app can't obtain background permission without foreground permission).
*/
if(granted) {
await Location.requestBackgroundPermissionsAsync();
}
} catch(e) {
console.error(`Location request has been failed: ${e}`);
}
})();
}, []);

permission-result-1 permission-result-2

Components

[!NOTE] λŒ€λΆ€λΆ„μ˜ Typeλ“€κ³Ό Propλ“€μ˜ μ„€λͺ…은 μ½”λ“œμ˜ 주석에도 μ ν˜€μžˆκ³  이 ν”„λ‘œμ νŠΈλŠ” TypeScriptλ₯Ό μ§€μ›ν•˜λ‹ˆ μ½”λ“œμ—μ„œλ§Œ 확인해도 μ‚¬μš©μ— 무리가 없을 κ²ƒμž…λ‹ˆλ‹€.

  • βœ… Fully Supported
  • ⚠️ Developing, lack of features yet
  • πŸ“¦ Planned
Component iOS Android Description
NaverMapView βœ… βœ… 지도
NaverMapMarkerOverlay βœ… βœ… 마컀 μ˜€λ²„λ ˆμ΄
Info Window πŸ“¦ πŸ“¦ μ˜€λ²„λ ˆμ΄μ˜ μ½œμ˜€λ²„, 툴팁
NaverMapCircleOverlay βœ… βœ… 원 μ˜€λ²„λ ˆμ΄
NaverMapPolylineOverlay βœ… βœ… 폴리라인 μ˜€λ²„λ ˆμ΄
NaverMapPolygonOverlay βœ… βœ… 폴리곀
NaverMapGroundOverlay βœ… βœ… 지상 μ˜€λ²„λ ˆμ΄
NaverMapPathOverlay βœ… βœ… 경둜 μ˜€λ²„λ ˆμ΄
NaverMapMultipartPathOverlay πŸ“¦ πŸ“¦ μ—¬λŸ¬κ°œμ˜ 경둜 μ˜€λ²„λ ˆμ΄
NaverMapArrowPathOverlay βœ… βœ… ν™”μ‚΄ν‘œ 경둜 μ˜€λ²„λ ˆμ΄

마컀 μ΄λ―Έμ§€μ˜ μ’…λ₯˜μ™€ μ„±λŠ₯

마컀의 μ’…λ₯˜λŠ” 총 5κ°€μ§€μž…λ‹ˆλ‹€.

[!IMPORTANT] [iOS, Android] x [new arch, old arch] x [debug, release] 총 8κ°€μ§€ μ‘°κ±΄μ—μ„œ λͺ¨λ‘ μ •μƒμ μœΌλ‘œ λ Œλ”λ§ λ˜λŠ” 것을 ν…ŒμŠ€νŠΈν–ˆμŠ΅λ‹ˆλ‹€.

[!TIP] reuseIdentifierλŠ” μ „λ‹¬ν•˜μ§€ μ•Šμ•„λ„ λͺ¨λ‘ μžλ™μœΌλ‘œ 캐싱이 λ©λ‹ˆλ‹€.

λ˜λ„λ‘μ΄λ©΄ λ§ˆμ»€λŠ” λͺ¨λ‘ width, height prop을 μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€. 2번 νƒ€μž…μ˜ 경우 ν˜„μž¬ debug/release λΉŒλ“œμ˜ 크기가 width, height없이 λ‹€λ₯΄κ²Œ λ‚˜μ˜€λŠ” ν˜„μƒμ΄ μžˆμŠ΅λ‹ˆλ‹€. releaseμ—μ„œλŠ” μ œλŒ€λ‘œ λ‚˜μ˜΅λ‹ˆλ‹€.

  1. Naver Map Basic Symbol (green, red, gray, ...) (caching βœ…)
image={{symbol: 'green'}}
  1. Local Resource (require react native image file) (caching βœ…)
image={require('./marker.png')}
  1. Local Native Resource
image={{assetName: 'asset_image'}}
  • iOS: main bundle의 image asset 이름
  • Android: resources의 drawable 이름
  1. Network Image (caching βœ…)
image={{httpUri: 'https://example.com/image.png'}}

[!WARNING] ν˜„μž¬ header같은 속성은 μ§€μ›λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

  1. Custom React View (caching ❌)

iOS(new arch)에선 ν˜„μž¬ View듀에 collapsable=falseλ₯Ό μ„€μ •ν•΄μ•Ό λ™μž‘ν•©λ‹ˆλ‹€.

[!TIP] 마컀의 μƒκΉ€μƒˆλ₯Ό λ°”κΏ”μ•Ό ν•œλ‹€λ©΄ 그것에 λŒ€ν•œ μ˜μ‘΄μ„±λ“€μ„ 제일 μƒμœ„ μžμ‹μ˜ key둜 μ „λ‹¬ν•΄μ•Όν•©λ‹ˆλ‹€.

<NaverMapMarkerOverlay width={width} height={height} ...>
<View key={`${text}/${width}/${height}`} collapsable={false} style={{width, height}}>
<Text>{text}</Text>
</View>
</NaverMapMarkerOverlay>

[!IMPORTANT] 이 νƒ€μž…μ€ 많이 생성될 μ‹œ μ„±λŠ₯에 ꡉμž₯히 영ν–₯을 λ―ΈμΉ  수 μžˆμŠ΅λ‹ˆλ‹€. 아직은 λ‹¨μˆœν•˜κ²Œλ§Œ μ‚¬μš©ν•˜μ‹œκ±°λ‚˜ λ˜λ„λ‘μ΄λ©΄ 이미지λ₯Ό μ‚¬μš©ν•˜λŠ” 것을 μΆ”μ²œλ“œλ¦½λ‹ˆλ‹€.

ν˜„μž¬ 이 νƒ€μž…μ€ Android에선 react-native-map의 κ΅¬ν˜„μ²΄λ₯Ό λΉ„μŠ·ν•˜κ²Œ 가져와 React Native의 Shadow Nodeλ₯Ό 쑰금 μ»€μŠ€ν…€ν•΄μ„œ μžμ‹μ˜ μœ„μΉ˜λ₯Ό μΆ”μ ν•œλ‹€μŒ μ‹€μ œ Android의 Viewλ₯Ό μ‚½μž…ν•΄μ€λ‹ˆλ‹€.

iOS에선 λ‹¨μˆœνžˆ UIViewλ₯Ό UIImage둜 μΊ”λ²„μŠ€μ— κ·Έλ € ν‘œμ‹œν•΄μ€λ‹ˆλ‹€.

두 방법 λͺ¨λ‘κ°€ 이미지 캐싱이 아직 μ§€μ›λ˜μ§€ μ•Šκ³ (좔후에 reuseableIdentifier같은 μ†μ„±μœΌλ‘œ 지원이 κ°€λŠ₯ν•  κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€), 마컀 ν•˜λ‚˜λ‹Ή λ§Žμ€ λ¦¬μ†ŒμŠ€λ₯Ό μ°¨μ§€ν•˜κ²Œ λ©λ‹ˆλ‹€.

TODO - Props & Commands

  • βœ… Done
  • πŸ“¦ Planned
  • ❓ Maybe Planned
  • ❌ Not Planned

NaverMapView

Props

Prop iOS Android
isLogoInteractionEnabled ❌ ❌
gestureFrictions πŸ“¦ πŸ“¦

Events

Event iOS Android
onTapSymbol πŸ“¦ πŸ“¦
onAuthFailed ❌ ❌
onLocationChange πŸ“¦ πŸ“¦

Marker Common

Events

iOS Android
onLongTap ❌ πŸ“¦

NaverMapMarkerOverlay

Props

Prop iOS Android
caption-fontFamily ❓ ❓
subcaption-fontFamily ❓ ❓

Milestone

  • Project Started (23.04.01)
  • Project Setup & Component Structure (23.04.03)
  • General Props & Commands (23.04.05)
  • Camera, Region, Commands, Events (23.04.07)
  • Implement Basic Overlays (23.04.10)
  • Location Service (23.04.10)
  • Support Paper(Old Arch) (23.04.11)
  • Release (23.04.11)
  • Support Expo with config plugin (23.04.12)
  • Docs
  • Implement Clustering (23.04.24)
  • Implement ArrowheadPath Overlay (23.05.01)
  • Implement Ground Overlay (23.05.01)
  • Implement Location Overlay Commands <- πŸ”₯
  • Implement MutlPath Overlay <- πŸ”₯

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT