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

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.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>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