├── .gitattributes
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── ReactNativeKakaoMaps.podspec
├── TROUBLESHOOTING.md
├── android
├── build.gradle
├── gradlew
├── gradlew.bat
├── libs
│ └── libDaumMapAndroid.jar
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── jiggag
│ │ └── rnkakaomaps
│ │ ├── Constants.java
│ │ ├── KakaoMapFragment.java
│ │ ├── KakaoMapManager.java
│ │ └── KakaoMapPackage.java
│ ├── jniLibs
│ ├── arm64-v8a
│ │ └── libDaumMapEngineApi.so
│ ├── armeabi-v7a
│ │ └── libDaumMapEngineApi.so
│ └── armeabi
│ │ └── libDaumMapEngineApi.so
│ └── res
│ ├── layout
│ └── kakao_map_view.xml
│ └── values
│ └── strings.xml
├── example.png
├── example
├── .buckconfig
├── .eslintrc.js
├── .flowconfig
├── .gitignore
├── .prettierrc.js
├── .watchmanconfig
├── App.js
├── Gemfile
├── __tests__
│ └── App-test.js
├── _bundle
│ └── config
├── _node-version
├── _ruby-version
├── android
│ ├── app
│ │ ├── _BUCK
│ │ ├── build.gradle
│ │ ├── build_defs.bzl
│ │ ├── debug.keystore
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ ├── debug
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ │ └── com
│ │ │ │ └── jiggag
│ │ │ │ └── example
│ │ │ │ └── ReactNativeFlipper.java
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── jiggag
│ │ │ │ └── example
│ │ │ │ ├── MainActivity.java
│ │ │ │ ├── MainApplication.java
│ │ │ │ └── newarchitecture
│ │ │ │ ├── MainApplicationReactNativeHost.java
│ │ │ │ ├── components
│ │ │ │ └── MainComponentsRegistry.java
│ │ │ │ └── modules
│ │ │ │ └── MainApplicationTurboModuleManagerDelegate.java
│ │ │ ├── jni
│ │ │ ├── CMakeLists.txt
│ │ │ ├── MainApplicationModuleProvider.cpp
│ │ │ ├── MainApplicationModuleProvider.h
│ │ │ ├── MainApplicationTurboModuleManagerDelegate.cpp
│ │ │ ├── MainApplicationTurboModuleManagerDelegate.h
│ │ │ ├── MainComponentsRegistry.cpp
│ │ │ ├── MainComponentsRegistry.h
│ │ │ └── OnLoad.cpp
│ │ │ └── res
│ │ │ ├── drawable
│ │ │ └── rn_edit_text_material.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── app.json
├── babel.config.js
├── custom_image.png
├── index.js
├── ios
│ ├── Podfile
│ ├── Podfile.lock
│ ├── RNStarter.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── _xcode.env
│ ├── custom_image.png
│ ├── example.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── example.xcscheme
│ ├── example.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── example
│ │ ├── AppDelegate.h
│ │ ├── AppDelegate.mm
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ ├── LaunchScreen.storyboard
│ │ └── main.m
│ └── exampleTests
│ │ ├── Info.plist
│ │ └── exampleTests.m
├── metro.config.js
├── package.json
└── yarn.lock
├── index.d.ts
├── index.js
├── ios
├── DaumMap.embeddedframework
│ ├── DaumMap.framework
│ │ ├── DaumMap
│ │ ├── Headers
│ │ │ ├── MTMapCameraUpdate.h
│ │ │ ├── MTMapCircle.h
│ │ │ ├── MTMapGeometry.h
│ │ │ ├── MTMapLocationMarkerItem.h
│ │ │ ├── MTMapPOIItem.h
│ │ │ ├── MTMapPolyline.h
│ │ │ ├── MTMapReverseGeoCoder.h
│ │ │ └── MTMapView.h
│ │ ├── Info.plist
│ │ ├── copyright.png
│ │ ├── daum_copyright.png
│ │ ├── daum_th_line.png
│ │ ├── detail_button.png
│ │ ├── info_box.png
│ │ ├── info_box_tail.png
│ │ ├── map_pin.png
│ │ ├── map_pin@3x.png
│ │ ├── map_pin_custom.png
│ │ ├── map_pin_custom@3x.png
│ │ ├── map_pin_red.png
│ │ ├── map_pin_red@3x.png
│ │ ├── map_pin_shadow.png
│ │ ├── map_pin_shadow@3x.png
│ │ ├── map_pinup.png
│ │ ├── map_pinup@3x.png
│ │ ├── map_pinup_custom.png
│ │ ├── map_pinup_custom@3x.png
│ │ ├── map_present.png
│ │ ├── map_present_background_update.png
│ │ ├── map_present_direction.png
│ │ ├── map_present_tracking.png
│ │ ├── noimage.png
│ │ ├── noimage256.png
│ │ ├── point_sprite.png
│ │ ├── shadow_balloon.png
│ │ └── th_line.png
│ └── Resources
│ │ ├── Headers
│ │ ├── copyright.png
│ │ ├── daum_copyright.png
│ │ ├── daum_th_line.png
│ │ ├── detail_button.png
│ │ ├── info_box.png
│ │ ├── info_box_tail.png
│ │ ├── map_pin.png
│ │ ├── map_pin@3x.png
│ │ ├── map_pin_custom.png
│ │ ├── map_pin_custom@3x.png
│ │ ├── map_pin_red.png
│ │ ├── map_pin_red@3x.png
│ │ ├── map_pin_shadow.png
│ │ ├── map_pin_shadow@3x.png
│ │ ├── map_pinup.png
│ │ ├── map_pinup@3x.png
│ │ ├── map_pinup_custom.png
│ │ ├── map_pinup_custom@3x.png
│ │ ├── map_present.png
│ │ ├── map_present_background_update.png
│ │ ├── map_present_direction.png
│ │ ├── map_present_tracking.png
│ │ ├── noimage.png
│ │ ├── noimage256.png
│ │ ├── point_sprite.png
│ │ ├── shadow_balloon.png
│ │ └── th_line.png
├── KakaoMapManager.m
├── MapViewController.h
├── MapViewController.m
└── RnKakaoMaps.xcodeproj
│ └── project.pbxproj
└── package.json
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # OSX
3 | #
4 | .DS_Store
5 |
6 | # node.js
7 | #
8 | node_modules/
9 | npm-debug.log
10 | yarn-error.log
11 |
12 |
13 | # Xcode
14 | #
15 | build/
16 | *.pbxuser
17 | !default.pbxuser
18 | *.mode1v3
19 | !default.mode1v3
20 | *.mode2v3
21 | !default.mode2v3
22 | *.perspectivev3
23 | !default.perspectivev3
24 | xcuserdata
25 | *.xccheckout
26 | *.moved-aside
27 | DerivedData
28 | *.hmap
29 | *.ipa
30 | *.xcuserstate
31 | project.xcworkspace
32 |
33 |
34 | # Android/IntelliJ
35 | #
36 | build/
37 | .idea
38 | .gradle
39 | local.properties
40 | *.iml
41 |
42 | # BUCK
43 | buck-out/
44 | \.buckd/
45 | *.keystore
46 |
47 | android/.settings/org.eclipse.buildship.core.prefs
48 | android/.project
49 | .env
50 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | example/
2 | .env
3 | .gitattributes
4 | .project
5 | .idea
6 | .gradle
7 | .settings
8 | local.properties
9 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 jiggag
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## @jiggag/react-native-kakao-maps
2 |
3 |
4 | ```tsx
5 | import { KakakoMapView } from '@jiggag/react-native-kakao-maps';
6 |
7 | return (
8 | {
30 | // event.nativeEvent
31 | }}
32 | />
33 | );
34 | ```
35 |
36 | ## 시작하기
37 | ### 설치
38 | `yarn add @jiggag/react-native-kakao-maps`
39 |
40 | ### 카카오 앱 키 설정
41 | #### 안드로이드
42 | - `./android/app/src/main/res/values/strings.xml`
43 | -
44 | ```sh
45 |
46 | ...
47 | KAKAO_APP_KEY
48 |
49 | ```
50 | #### iOS
51 | - `./Info.plist`
52 | -
53 | ```xml
54 | KAKAO_APP_KEY
55 | KAKAO_APP_KEY
56 | ```
57 |
58 | ### 커스텀 마커 이미지 등록
59 | 1. 마커 이미지 URL `markerImageUrl` 옵션으로 설정하여 사용
60 | 2. 마커 이미지 등록 후 `markerImageName` 옵션으로 `{이미지}` 호출하여 사용
61 | ```
62 | - 안드로이드: ./android/app/src/main/res/drawable/{이미지}.png
63 | - iOS: xcode 프로젝트 폴더에 {이미지}.png 추가 + Copy items if needed
64 | ```
65 |
66 | ## [갑자기 문제가 생겼습니다](./TROUBLESHOOTING.md)
67 |
--------------------------------------------------------------------------------
/ReactNativeKakaoMaps.podspec:
--------------------------------------------------------------------------------
1 | require 'json'
2 |
3 | # Returns the version number for a package.json file
4 | pkg_version = lambda do |dir_from_root = '', version = 'version'|
5 | path = File.join(__dir__, dir_from_root, 'package.json')
6 | JSON.parse(File.read(path))[version]
7 | end
8 |
9 | # Let the main package.json decide the version number for the pod
10 | package_version = pkg_version.call
11 |
12 | Pod::Spec.new do |s|
13 | s.name = "ReactNativeKakaoMaps"
14 | s.version = package_version
15 | s.summary = "A react native module kakao maps"
16 | s.description = <<-DESC
17 | A react native module kakao maps
18 | DESC
19 | s.homepage = "https://github.com/jiggag/react-native-kakao-maps"
20 | s.license = "MIT"
21 | s.author = { "Atul R" => "jiggag90@gmail.com" }
22 | s.platform = :ios, "9.0"
23 | s.source = { :git => "https://github.com/jiggag/react-native-kakao-maps.git", :tag => s.version.to_s }
24 | s.source_files = "ios/*.{h,m}"
25 |
26 | s.vendored_frameworks = 'ios/DaumMap.embeddedframework/DaumMap.framework'
27 | s.resources = ['ios/DaumMap.embeddedframework/Resources/*.png']
28 | s.dependency "React"
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/TROUBLESHOOTING.md:
--------------------------------------------------------------------------------
1 | ## 갑자기 문제가 생겼습니다
2 | ### iOS 빌드가 되지 않아요
3 | ```shell
4 | ❌ ld: symbol(s) not found for architecture x86_64
5 | ❌ clang: error: linker command failed with exit code 1 (use -v to see invocation)
6 | ```
7 |
8 |
9 | 에러 메세지 자세히 보기
10 |
11 | ```shell
12 | Undefined symbols for architecture x86_64:
13 | "_sqlite3_bind_blob", referenced from:
14 | mapEngine::ResourceCacheDao::_updateCacheData(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
15 | mapEngine::ResourceCacheDao::_insertCacheData(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
16 | "_sqlite3_bind_double", referenced from:
17 | mapCore::DiskCacheDao::insertEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
18 | mapCore::DiskCacheDao::updateEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
19 | mapCore::DiskCacheDao::updateAccessTime(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
20 | mapEngine::ResourceCacheDao::_updateCacheEntity(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
21 | mapEngine::ResourceCacheDao::_insertCacheEntity(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
22 | mapEngine::ResourceCacheDao::updateAccessTime(mobileToolkit::BasicString const*) in DaumMap(ResourceCacheDao.o)
23 | "_sqlite3_bind_int", referenced from:
24 | mapCore::DiskCacheDao::selectByType(int, bool) in DaumMap(DiskCacheDao.o)
25 | mapCore::DiskCacheDao::selectCleaningList(int, int) in DaumMap(DiskCacheDao.o)
26 | mapCore::DiskCacheDao::insertEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
27 | mapCore::DiskCacheDao::updateEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
28 | mapCore::DiskCacheDao::deleteEntitiesByType(int) in DaumMap(DiskCacheDao.o)
29 | mapCore::DiskCacheDao::invalidateAllEntries() in DaumMap(DiskCacheDao.o)
30 | mapEngine::ResourceCacheDao::selectCleaningList(int, int) in DaumMap(ResourceCacheDao.o)
31 | ...
32 | "_sqlite3_bind_text", referenced from:
33 | mapCore::DiskCacheDao::selectByKey(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
34 | mapCore::DiskCacheDao::insertEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
35 | mapCore::DiskCacheDao::updateEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
36 | mapCore::DiskCacheDao::updateAccessTime(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
37 | mapCore::DiskCacheDao::deleteEntity(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
38 | mapEngine::ResourceCacheDao::selectCacheEntity(mobileToolkit::BasicString const*) in DaumMap(ResourceCacheDao.o)
39 | mapEngine::ResourceCacheDao::selectCacheData(mobileToolkit::BasicString const*, mobileToolkit::BasicString*) in DaumMap(ResourceCacheDao.o)
40 | ...
41 | "_sqlite3_close", referenced from:
42 | mapCore::DiskCacheDao::_openOrCreateDB() in DaumMap(DiskCacheDao.o)
43 | mapCore::BaseSqliteDao::~BaseSqliteDao() in DaumMap(BaseSqliteDao.o)
44 | mapCore::BaseSqliteDao::open() in DaumMap(BaseSqliteDao.o)
45 | mapCore::BaseSqliteDao::close() in DaumMap(BaseSqliteDao.o)
46 | "_sqlite3_column_blob", referenced from:
47 | mapEngine::ResourceCacheDao::selectCacheData(mobileToolkit::BasicString const*, mobileToolkit::BasicString*) in DaumMap(ResourceCacheDao.o)
48 | "_sqlite3_column_bytes", referenced from:
49 | mapEngine::ResourceCacheDao::selectCacheData(mobileToolkit::BasicString const*, mobileToolkit::BasicString*) in DaumMap(ResourceCacheDao.o)
50 | "_sqlite3_column_double", referenced from:
51 | mapCore::DiskCacheDao::selectByKey(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
52 | mapCore::DiskCacheDao::selectByType(int, bool) in DaumMap(DiskCacheDao.o)
53 | mapCore::DiskCacheDao::selectCleaningList(int, int) in DaumMap(DiskCacheDao.o)
54 | mapEngine::ResourceCacheDao::selectCacheEntity(mobileToolkit::BasicString const*) in DaumMap(ResourceCacheDao.o)
55 | mapEngine::ResourceCacheDao::selectCleaningList(int, int) in DaumMap(ResourceCacheDao.o)
56 | "_sqlite3_column_int", referenced from:
57 | mapCore::DiskCacheDao::selectByKey(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
58 | mapCore::DiskCacheDao::selectByType(int, bool) in DaumMap(DiskCacheDao.o)
59 | mapCore::DiskCacheDao::selectCleaningList(int, int) in DaumMap(DiskCacheDao.o)
60 | mapEngine::ResourceCacheDao::selectCacheEntity(mobileToolkit::BasicString const*) in DaumMap(ResourceCacheDao.o)
61 | "_sqlite3_column_text", referenced from:
62 | mapCore::DiskCacheDao::selectByKey(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
63 | mapCore::DiskCacheDao::selectByType(int, bool) in DaumMap(DiskCacheDao.o)
64 | mapCore::DiskCacheDao::selectCleaningList(int, int) in DaumMap(DiskCacheDao.o)
65 | mapEngine::ResourceCacheDao::selectCacheEntity(mobileToolkit::BasicString const*) in DaumMap(ResourceCacheDao.o)
66 | mapEngine::ResourceCacheDao::selectCleaningList(int, int) in DaumMap(ResourceCacheDao.o)
67 | mapEngine::ResourceCacheDao::selectDanglingList(mobileToolkit::BasicString*) in DaumMap(ResourceCacheDao.o)
68 | "_sqlite3_errmsg", referenced from:
69 | mapCore::BaseSqliteDao::~BaseSqliteDao() in DaumMap(BaseSqliteDao.o)
70 | mapCore::BaseSqliteDao::open() in DaumMap(BaseSqliteDao.o)
71 | mapCore::BaseSqliteDao::_logError(char const*) in DaumMap(BaseSqliteDao.o)
72 | mapCore::BaseSqliteDao::close() in DaumMap(BaseSqliteDao.o)
73 | mapCore::BaseSqliteDao::_logErrorOnPrepareStatement() in DaumMap(BaseSqliteDao.o)
74 | "_sqlite3_exec", referenced from:
75 | mapCore::DiskCacheDao::_openOrCreateDB() in DaumMap(DiskCacheDao.o)
76 | mapEngine::ResourceCacheDao::_attachDatabase(mobileToolkit::BasicString const*, mobileToolkit::BasicString const*) in DaumMap(ResourceCacheDao.o)
77 | mapEngine::ResourceCacheDao::updateEntity(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
78 | mapEngine::ResourceCacheDao::insertEntity(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
79 | mapEngine::ResourceCacheDao::deleteEntity(mapEngine::ResourceCacheEntity const*) in DaumMap(ResourceCacheDao.o)
80 | "_sqlite3_finalize", referenced from:
81 | mapCore::DiskCacheDao::onAfterInitializeDb() in DaumMap(DiskCacheDao.o)
82 | mapCore::DiskCacheDao::selectByKey(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
83 | mapCore::DiskCacheDao::selectByType(int, bool) in DaumMap(DiskCacheDao.o)
84 | mapCore::DiskCacheDao::selectCleaningList(int, int) in DaumMap(DiskCacheDao.o)
85 | mapCore::DiskCacheDao::insertEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
86 | mapCore::DiskCacheDao::updateEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
87 | mapCore::DiskCacheDao::updateAccessTime(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
88 | ...
89 | "_sqlite3_free", referenced from:
90 | mapCore::DiskCacheDao::_openOrCreateDB() in DaumMap(DiskCacheDao.o)
91 | "_sqlite3_last_insert_rowid", referenced from:
92 | mapCore::DiskCacheDao::insertEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
93 | mapEngine::ResourceCacheDao::insertEntity(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
94 | "_sqlite3_open", referenced from:
95 | mapCore::DiskCacheDao::_openOrCreateDB() in DaumMap(DiskCacheDao.o)
96 | mapCore::BaseSqliteDao::open() in DaumMap(BaseSqliteDao.o)
97 | "_sqlite3_prepare_v2", referenced from:
98 | mapCore::DiskCacheDao::onAfterInitializeDb() in DaumMap(DiskCacheDao.o)
99 | mapCore::DiskCacheDao::selectByKey(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
100 | mapCore::DiskCacheDao::selectByType(int, bool) in DaumMap(DiskCacheDao.o)
101 | mapCore::DiskCacheDao::selectCleaningList(int, int) in DaumMap(DiskCacheDao.o)
102 | mapCore::DiskCacheDao::insertEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
103 | mapCore::DiskCacheDao::updateEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
104 | mapCore::DiskCacheDao::updateAccessTime(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
105 | ...
106 | "_sqlite3_reset", referenced from:
107 | mapEngine::ResourceCacheDao::_insertCacheEntity(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
108 | mapEngine::ResourceCacheDao::_insertCacheData(mapEngine::ResourceCacheEntity*) in DaumMap(ResourceCacheDao.o)
109 | "_sqlite3_step", referenced from:
110 | mapCore::DiskCacheDao::selectByKey(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
111 | mapCore::DiskCacheDao::selectByType(int, bool) in DaumMap(DiskCacheDao.o)
112 | mapCore::DiskCacheDao::selectCleaningList(int, int) in DaumMap(DiskCacheDao.o)
113 | mapCore::DiskCacheDao::insertEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
114 | mapCore::DiskCacheDao::updateEntity(mapCore::DiskCacheEntity*) in DaumMap(DiskCacheDao.o)
115 | mapCore::DiskCacheDao::updateAccessTime(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
116 | mapCore::DiskCacheDao::deleteEntity(mobileToolkit::BasicString const*) in DaumMap(DiskCacheDao.o)
117 | ...
118 | ld: symbol(s) not found for architecture x86_64
119 | clang: error: linker command failed with exit code 1 (use -v to see invocation)
120 |
121 | Undefined symbol: _sqlite3_bind_blob
122 |
123 | Undefined symbol: _sqlite3_bind_double
124 |
125 | Undefined symbol: _sqlite3_bind_int
126 |
127 | Undefined symbol: _sqlite3_bind_text
128 |
129 | Undefined symbol: _sqlite3_close
130 |
131 | Undefined symbol: _sqlite3_column_blob
132 |
133 | Undefined symbol: _sqlite3_column_bytes
134 |
135 | Undefined symbol: _sqlite3_column_double
136 |
137 | Undefined symbol: _sqlite3_column_int
138 |
139 | Undefined symbol: _sqlite3_column_text
140 |
141 | Undefined symbol: _sqlite3_errmsg
142 |
143 | Undefined symbol: _sqlite3_exec
144 |
145 | Undefined symbol: _sqlite3_finalize
146 |
147 | Undefined symbol: _sqlite3_free
148 |
149 | Undefined symbol: _sqlite3_last_insert_rowid
150 |
151 | Undefined symbol: _sqlite3_open
152 |
153 | Undefined symbol: _sqlite3_prepare_v2
154 |
155 | Undefined symbol: _sqlite3_reset
156 |
157 | Undefined symbol: _sqlite3_step
158 | ```
159 |
160 |
161 | #### 해결방법
162 | `Build Phases > Link Binary With Libraries > libsqlite3.tbd 추가`
163 |
164 | ------
165 | ### iOS 빌드가 되지 않아요
166 | ```shell
167 | ❌ ld: in /Users/jiggag/react-native-kakao-maps/example/node_modules/@jiggag/react-native-kakao-maps/ios/DaumMap.embeddedframework/DaumMap.framework/DaumMap(HashUtils.o), building for iOS Simulator, but linking in object file built for iOS, file '/Users/jiggag/react-native-kakao-maps/example/node_modules/@jiggag/react-native-kakao-maps/ios/DaumMap.embeddedframework/DaumMap.framework/DaumMap' for architecture arm64
168 | ❌ clang: error: linker command failed with exit code 1 (use -v to see invocation)
169 | ```
170 |
171 | #### 해결방법
172 | `xcode > example.xcworkspace` 열어서 빌드
173 |
174 | ------
175 | ### 지도가 보이지 않아요
176 | [카카오 지도 개발자 문서](https://apis.map.kakao.com/android/guide/#step2)를 참고하여 앱 키 발급 및 키 해시를 등록해주세요
177 |
178 |
179 | 안드로이드 키 해시 추출하기
180 |
181 | ```shell
182 | keytool -exportcert -alias {key_alias} -keystore {keystore_path} -storepass {store_password} -keypass {key_password} | openssl sha1 -binary | openssl base64
183 | keytool -exportcert -alias androiddebugkey -keystore ./android/app/debug.keystore -storepass android -keypass android | openssl sha1 -binary | openssl base64
184 | ```
185 |
186 |
187 | #### 해결방법
188 | 발급 받은 앱 키 `strings.xml > kakao_app_key` 교체 및 `앱 설정 > 플랫폼` 키 해시 등록
189 |
190 | ------
191 | ### 안드로이드 에뮬레이터에서 지도를 열면 앱이 크래시 발생해요
192 | ```shell
193 | java.lang.UnsatisfiedLinkError
194 | at net.daum.mf.map.n.api.NativeMapLibraryLoader.loadLibrary(NativeMapLibraryLoader.java:39)
195 | ...
196 | ```
197 | #### 해결방법
198 | - 안드로이드 에뮬레이터(x86, x86_64)에서는 카카오 맵을 지원하지 않고 있습니다. ([관련 이슈 #31](https://github.com/jiggag/react-native-kakao-maps/issues/31#issuecomment-1435983575))
199 | - 실기기를 이용해주세요.
200 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 |
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | }
6 |
7 | dependencies {
8 |
9 | }
10 | }
11 |
12 | apply plugin: 'com.android.library'
13 |
14 | def getExtValue(rootProject,key,defaultValue ) {
15 | if (rootProject.hasProperty('ext')) {
16 | if (rootProject.ext.has(key)) {
17 | return rootProject.ext[key]
18 | }
19 | }
20 | return defaultValue
21 | }
22 |
23 | android {
24 | compileSdkVersion getExtValue(rootProject,'compileSdkVersion',23)
25 | buildToolsVersion getExtValue(rootProject,'buildToolsVersion', "23.0.1")
26 |
27 | defaultConfig {
28 | minSdkVersion getExtValue(rootProject,'minSdkVersion', 16)
29 | targetSdkVersion getExtValue(rootProject,'targetSdkVersion', 22)
30 | versionCode 1
31 | versionName "1.0"
32 | }
33 | lintOptions {
34 | abortOnError false
35 | }
36 | }
37 |
38 | repositories {
39 | mavenCentral()
40 | }
41 |
42 | dependencies {
43 | implementation 'com.facebook.react:react-native:+'
44 | implementation files('libs/libDaumMapAndroid.jar')
45 | }
46 |
--------------------------------------------------------------------------------
/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/android/libs/libDaumMapAndroid.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiggag/react-native-kakao-maps/bdd5782775c7cd229c2f824073ef6d7a90f23da8/android/libs/libDaumMapAndroid.jar
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/android/src/main/java/com/jiggag/rnkakaomaps/Constants.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.rnkakaomaps;
2 |
3 | public class Constants {
4 | public static final String LOG_TAG = "KakaoMapView";
5 | public static final Double INIT_LAT = 37.537229;
6 | public static final Double INIT_LNG = 127.005515;
7 | public static final String PARAM_MARKER_NAME = "markerName";
8 | public static final String PARAM_MARKER_IMAGE_URL = "markerImageUrl";
9 | public static final String PARAM_MARKER_LIST = "markerList";
10 | public static final String PARAM_LAT = "lat";
11 | public static final String PARAM_LNG = "lng";
12 | }
13 |
--------------------------------------------------------------------------------
/android/src/main/java/com/jiggag/rnkakaomaps/KakaoMapFragment.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.rnkakaomaps;
2 |
3 | import android.os.Bundle;
4 | import android.util.Log;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.ViewGroup;
8 | import android.graphics.Bitmap;
9 | import android.graphics.BitmapFactory;
10 |
11 | import net.daum.mf.map.api.MapLayout;
12 | import net.daum.mf.map.api.MapPoint;
13 | import net.daum.mf.map.api.MapPOIItem;
14 | import net.daum.mf.map.api.MapView;
15 |
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 | import java.net.HttpURLConnection;
19 | import java.net.URL;
20 | import java.util.ArrayList;
21 | import java.util.HashMap;
22 | import java.util.Map;
23 |
24 | import androidx.fragment.app.Fragment;
25 |
26 | import com.facebook.react.bridge.Arguments;
27 | import com.facebook.react.bridge.ReactContext;
28 | import com.facebook.react.bridge.WritableMap;
29 | import com.facebook.react.common.MapBuilder;
30 | import com.facebook.react.uimanager.events.RCTEventEmitter;
31 |
32 | public class KakaoMapFragment extends Fragment implements MapView.OpenAPIKeyAuthenticationResultListener, MapView.MapViewEventListener {
33 | ReactContext reactContext;
34 | ViewGroup mapViewContainer;
35 | private MapView mMapView;
36 | private MapPOIItem mDefaultMarker;
37 | private Bitmap markerImage = null;
38 | private MapPoint.GeoCoordinate mapCenterPoint;
39 | MapLayout mapLayout;
40 |
41 | private void createMapView() {
42 | if (mMapView == null) {
43 | mMapView = mapLayout.getMapView();
44 | mMapView.setDaumMapApiKey(this.getString(R.string.kakao_app_key));
45 | mMapView.setOpenAPIKeyAuthenticationResultListener(this);
46 | mMapView.setMapViewEventListener(this);
47 | mMapView.setMapType(MapView.MapType.Standard);
48 | }
49 |
50 | mMapView.removeAllPOIItems();
51 |
52 | if (mapCenterPoint == null) {
53 | Double lat = getArguments().getDouble(Constants.PARAM_LAT);
54 | Double lng = getArguments().getDouble(Constants.PARAM_LNG);
55 | mMapView.setMapCenterPoint(MapPoint.mapPointWithGeoCoord(lat, lng), true);
56 | } else {
57 | mMapView.setMapCenterPoint(MapPoint.mapPointWithGeoCoord(mapCenterPoint.latitude, mapCenterPoint.longitude), true);
58 | }
59 |
60 | ArrayList> markerList = (ArrayList>) getArguments().get(Constants.PARAM_MARKER_LIST);
61 | String markerImageUrl = getArguments().getString(Constants.PARAM_MARKER_IMAGE_URL);
62 | String markerImageName = getArguments().getString(Constants.PARAM_MARKER_NAME);
63 | int markerImageResourceId = markerImageName != null ? this.getResources().getIdentifier(markerImageName, "drawable", getActivity().getPackageName()) : 0;
64 |
65 | new Thread(() -> {
66 | getBitmapFromUrl(markerImageUrl);
67 | createMarker(markerList, markerImage, markerImageResourceId);
68 | }).start();
69 | }
70 |
71 | @Override
72 | public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
73 | super.onCreateView(inflater, parent, savedInstanceState);
74 |
75 | mapLayout = new MapLayout(getActivity());
76 | View rootView = inflater.inflate(R.layout.kakao_map_view, parent, false);
77 |
78 | createMapView();
79 |
80 | mapViewContainer = rootView.findViewById(R.id.kakao_map_view);
81 | mapViewContainer.addView(mapLayout);
82 |
83 | return rootView;
84 | }
85 |
86 | @Override
87 | public void onResume() {
88 | super.onResume();
89 | createMapView();
90 | }
91 |
92 | // /////////////////////////////////////////////////////////////////////////////////////////////////
93 | // net.daum.mf.map.api.MapView.OpenAPIKeyAuthenticationResultListener
94 |
95 | @Override
96 | public void onDaumMapOpenAPIKeyAuthenticationResult(MapView mapView, int resultCode, String resultMessage) {
97 | Log.i(Constants.LOG_TAG, String.format("Open API Key Authentication Result : code=%d, message=%s", resultCode, resultMessage));
98 | }
99 |
100 | /////////////////////////////////////////////////////////////////////////////////////////////////
101 | // net.daum.mf.map.api.MapView.MapViewEventListener
102 |
103 | public void onMapViewInitialized(MapView mapView) {
104 | Log.i(Constants.LOG_TAG, "MapView had loaded. Now, MapView APIs could be called safely");
105 | }
106 |
107 | @Override
108 | public void onMapViewCenterPointMoved(MapView mapView, MapPoint mapCenterPoint) {
109 | MapPoint.GeoCoordinate mapPointGeo = mapCenterPoint.getMapPointGeoCoord();
110 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewCenterPointMoved (%f,%f)", mapPointGeo.latitude, mapPointGeo.longitude));
111 | }
112 |
113 | @Override
114 | public void onMapViewDoubleTapped(MapView mapView, MapPoint mapPoint) {
115 | MapPoint.GeoCoordinate mapPointGeo = mapPoint.getMapPointGeoCoord();
116 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewDoubleTapped (%f,%f)", mapPointGeo.latitude, mapPointGeo.longitude));
117 | }
118 |
119 | @Override
120 | public void onMapViewLongPressed(MapView mapView, MapPoint mapPoint) {
121 | MapPoint.GeoCoordinate mapPointGeo = mapPoint.getMapPointGeoCoord();
122 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewLongPressed (%f,%f)", mapPointGeo.latitude, mapPointGeo.longitude));
123 | }
124 |
125 | @Override
126 | public void onMapViewSingleTapped(MapView mapView, MapPoint mapPoint) {
127 | MapPoint.GeoCoordinate mapPointGeo = mapPoint.getMapPointGeoCoord();
128 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewSingleTapped (%f,%f)", mapPointGeo.latitude, mapPointGeo.longitude));
129 | }
130 |
131 | @Override
132 | public void onMapViewDragStarted(MapView mapView, MapPoint mapPoint) {
133 | MapPoint.GeoCoordinate mapPointGeo = mapPoint.getMapPointGeoCoord();
134 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewDragStarted (%f,%f)", mapPointGeo.latitude, mapPointGeo.longitude));
135 | }
136 |
137 | @Override
138 | public void onMapViewDragEnded(MapView mapView, MapPoint mapPoint) {
139 | MapPoint.GeoCoordinate mapPointGeo = mapPoint.getMapPointGeoCoord();
140 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewDragEnded (%f,%f)", mapPointGeo.latitude, mapPointGeo.longitude));
141 | }
142 |
143 | @Override
144 | public void onMapViewMoveFinished(MapView mapView, MapPoint mapPoint) {
145 | MapPoint.GeoCoordinate mapPointGeo = mapPoint.getMapPointGeoCoord();
146 | mapCenterPoint = mapPointGeo;
147 | WritableMap event = Arguments.createMap();
148 | event.putDouble("lat", mapPointGeo.latitude);
149 | event.putDouble("lng", mapPointGeo.longitude);
150 | event.putDouble("zoomLevel", mapView.getZoomLevel());
151 | onReceiveNativeEvent(event);
152 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewMoveFinished (%f,%f)", mapPointGeo.latitude, mapPointGeo.longitude));
153 | }
154 |
155 | @Override
156 | public void onMapViewZoomLevelChanged(MapView mapView, int zoomLevel) {
157 | Log.i(Constants.LOG_TAG, String.format("MapView onMapViewZoomLevelChanged (%d)", zoomLevel));
158 | }
159 |
160 | private void onReceiveNativeEvent(WritableMap event) {
161 | reactContext
162 | .getJSModule(RCTEventEmitter.class)
163 | .receiveEvent(getId(), "topChange", event);
164 | }
165 |
166 | private Map getExportedCustomBubblingEventTypeConstants() {
167 | return MapBuilder.builder().put(
168 | "topChange",
169 | MapBuilder.of(
170 | "phasedRegistrationNames",
171 | MapBuilder.of("bubbled", "onChange")
172 | )
173 | ).build();
174 | }
175 |
176 | private void getBitmapFromUrl(String imageUrl) {
177 | if (imageUrl == null) {
178 | return;
179 | }
180 |
181 | try {
182 | URL url = new URL(imageUrl);
183 | HttpURLConnection connection = (HttpURLConnection) url.openConnection();
184 | connection.setDoInput(true);
185 | connection.connect();
186 | InputStream input = connection.getInputStream();
187 |
188 | markerImage = BitmapFactory.decodeStream(input);
189 | } catch (IOException e) {
190 | Log.e("getBitmapFromUrl", e.getMessage());
191 | }
192 | }
193 |
194 | private void createMarker(ArrayList> markerList, Bitmap markerImage, int markerResourceId) {
195 | mMapView.removeAllPOIItems();
196 | if ((markerList != null ? markerList.size() : 0) > 0) {
197 | for (int i = 0; i < markerList.size(); i++) {
198 | String markerName = (String) markerList.get(i).get(Constants.PARAM_MARKER_NAME);
199 | Double lat = (Double) markerList.get(i).get(Constants.PARAM_LAT);
200 | Double lng = (Double) markerList.get(i).get(Constants.PARAM_LNG);
201 | addMarker(mMapView, markerName, lat, lng, i, markerImage, markerResourceId);
202 | }
203 | }
204 | }
205 |
206 | private void addMarker(MapView mapView, String markName, Double lat, Double lng, int tag, Bitmap markerImage, int markerResourceId) {
207 | mDefaultMarker = new MapPOIItem();
208 | mDefaultMarker.setItemName(markName);
209 | mDefaultMarker.setTag(tag);
210 | mDefaultMarker.setMapPoint(MapPoint.mapPointWithGeoCoord(lat, lng));
211 | mDefaultMarker.setMarkerType(MapPOIItem.MarkerType.BluePin);
212 | mDefaultMarker.setSelectedMarkerType(MapPOIItem.MarkerType.RedPin);
213 |
214 | if (markerImage != null) {
215 | mDefaultMarker.setMarkerType(MapPOIItem.MarkerType.CustomImage);
216 | mDefaultMarker.setCustomImageBitmap(markerImage);
217 | }
218 |
219 | if (markerResourceId > 0) {
220 | mDefaultMarker.setMarkerType(MapPOIItem.MarkerType.CustomImage);
221 | mDefaultMarker.setCustomImageResourceId(markerResourceId);
222 | }
223 |
224 | mapView.addPOIItem(mDefaultMarker);
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/android/src/main/java/com/jiggag/rnkakaomaps/KakaoMapManager.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.rnkakaomaps;
2 |
3 | import android.os.Bundle;
4 | import android.view.Choreographer;
5 | import android.view.View;
6 | import android.widget.FrameLayout;
7 | import android.view.ViewGroup;
8 |
9 | import androidx.annotation.NonNull;
10 | import androidx.annotation.Nullable;
11 | import androidx.fragment.app.FragmentActivity;
12 |
13 | import com.facebook.react.bridge.ReactApplicationContext;
14 | import com.facebook.react.bridge.ReadableArray;
15 | import com.facebook.react.bridge.ReadableMap;
16 | import com.facebook.react.common.MapBuilder;
17 | import com.facebook.react.uimanager.annotations.ReactProp;
18 | import com.facebook.react.uimanager.ViewGroupManager;
19 | import com.facebook.react.uimanager.ThemedReactContext;
20 |
21 | import java.util.ArrayList;
22 | import java.util.Map;
23 |
24 | public class KakaoMapManager extends ViewGroupManager {
25 |
26 | public static final String REACT_CLASS = "KakaoMapView";
27 | public final int COMMAND_CREATE = 1;
28 |
29 | private ReactApplicationContext reactContext;
30 | private KakaoMapFragment fragment;
31 | private int containerViewId;
32 | private ArrayList markerList;
33 | private double paramLat = Constants.INIT_LAT;
34 | private double paramLng = Constants.INIT_LNG;
35 | private String markerImageName;
36 | private String markerImageUrl;
37 |
38 | public KakaoMapManager(ReactApplicationContext reactContext) {
39 | this.reactContext = reactContext;
40 | }
41 |
42 | @Override
43 | public String getName() {
44 | return REACT_CLASS;
45 | }
46 |
47 | @Override
48 | public FrameLayout createViewInstance(ThemedReactContext reactContext) {
49 | return new FrameLayout(reactContext);
50 | }
51 |
52 | @Nullable
53 | @Override
54 | public Map getCommandsMap() {
55 | return MapBuilder.of("create", COMMAND_CREATE);
56 | }
57 |
58 | @Override
59 | public void receiveCommand(
60 | @NonNull FrameLayout root,
61 | String commandId,
62 | @Nullable ReadableArray args
63 | ) {
64 | super.receiveCommand(root, commandId, args);
65 | containerViewId = args.getInt(0);
66 | int commandIdInt = Integer.parseInt(commandId);
67 | if (commandIdInt == COMMAND_CREATE) {
68 | createFragment(root);
69 | }
70 | }
71 |
72 | @ReactProp(name = "markerList")
73 | public void setMarkerList(FrameLayout view, @Nullable ReadableArray _markerList) {
74 | if (_markerList != null) {
75 | markerList = _markerList.toArrayList();
76 | }
77 | bundleFragment();
78 | }
79 |
80 | @ReactProp(name = "centerPoint")
81 | public void setCenterPoint(FrameLayout view, @Nullable ReadableMap centerPoint) {
82 | if (centerPoint != null) {
83 | paramLat = centerPoint.getDouble(Constants.PARAM_LAT);
84 | paramLng = centerPoint.getDouble(Constants.PARAM_LNG);
85 | }
86 | bundleFragment();
87 | }
88 |
89 | @ReactProp(name = "markerImageName")
90 | public void setMarkerImageName(FrameLayout view, @Nullable String _markerImageName) {
91 | markerImageName = _markerImageName;
92 | bundleFragment();
93 | }
94 |
95 | @ReactProp(name = "markerImageUrl")
96 | public void setMarkerImageUrl(FrameLayout view, @Nullable String _markerImageUrl) {
97 | markerImageUrl = _markerImageUrl;
98 | bundleFragment();
99 | }
100 |
101 | private void createFragment(FrameLayout root) {
102 | ViewGroup parentView = (ViewGroup) root.findViewById(containerViewId);
103 | setupLayout(parentView);
104 | fragment = new KakaoMapFragment();
105 | bundleFragment();
106 | }
107 |
108 | private void bundleFragment() {
109 | if (fragment == null) {
110 | return;
111 | }
112 | FragmentActivity activity = (FragmentActivity) reactContext.getCurrentActivity();
113 | Bundle bundle = new Bundle();
114 | bundle.putDouble(Constants.PARAM_LAT, paramLat);
115 | bundle.putDouble(Constants.PARAM_LNG, paramLng);
116 | bundle.putString(Constants.PARAM_MARKER_NAME, markerImageName);
117 | bundle.putString(Constants.PARAM_MARKER_IMAGE_URL, markerImageUrl);
118 | bundle.putParcelableArrayList(Constants.PARAM_MARKER_LIST, markerList);
119 |
120 | fragment.reactContext = reactContext;
121 | fragment.setArguments(bundle);
122 | activity.getSupportFragmentManager()
123 | .beginTransaction()
124 | .addToBackStack(null)
125 | .replace(containerViewId, fragment, String.valueOf(containerViewId))
126 | .commitAllowingStateLoss();
127 | fragment.onResume();
128 | }
129 |
130 | private void setupLayout(View view) {
131 | Choreographer.getInstance().postFrameCallback(new Choreographer.FrameCallback() {
132 | @Override
133 | public void doFrame(long frameTimeNanos) {
134 | manuallyLayoutChildren(view);
135 | view.getViewTreeObserver().dispatchOnGlobalLayout();
136 | Choreographer.getInstance().postFrameCallback(this);
137 | }
138 | });
139 | }
140 |
141 | private void manuallyLayoutChildren(View view) {
142 | view.measure(
143 | View.MeasureSpec.makeMeasureSpec(view.getMeasuredWidth(), View.MeasureSpec.EXACTLY),
144 | View.MeasureSpec.makeMeasureSpec(view.getMeasuredHeight(), View.MeasureSpec.EXACTLY));
145 |
146 | view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/android/src/main/java/com/jiggag/rnkakaomaps/KakaoMapPackage.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.rnkakaomaps;
2 |
3 | import java.util.List;
4 | import java.util.ArrayList;
5 |
6 | import com.facebook.react.ReactPackage;
7 | import com.facebook.react.bridge.NativeModule;
8 | import com.facebook.react.bridge.ReactApplicationContext;
9 | import com.facebook.react.uimanager.ViewManager;
10 |
11 | public class KakaoMapPackage implements ReactPackage {
12 | @Override
13 | public List createNativeModules(ReactApplicationContext reactContext) {
14 | List modules = new ArrayList<>();
15 | return modules;
16 | }
17 |
18 | @Override
19 | public List createViewManagers(ReactApplicationContext reactContext) {
20 | List managers = new ArrayList<>();
21 | managers.add(new KakaoMapManager(reactContext));
22 | return managers;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/android/src/main/jniLibs/arm64-v8a/libDaumMapEngineApi.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiggag/react-native-kakao-maps/bdd5782775c7cd229c2f824073ef6d7a90f23da8/android/src/main/jniLibs/arm64-v8a/libDaumMapEngineApi.so
--------------------------------------------------------------------------------
/android/src/main/jniLibs/armeabi-v7a/libDaumMapEngineApi.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiggag/react-native-kakao-maps/bdd5782775c7cd229c2f824073ef6d7a90f23da8/android/src/main/jniLibs/armeabi-v7a/libDaumMapEngineApi.so
--------------------------------------------------------------------------------
/android/src/main/jniLibs/armeabi/libDaumMapEngineApi.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiggag/react-native-kakao-maps/bdd5782775c7cd229c2f824073ef6d7a90f23da8/android/src/main/jniLibs/armeabi/libDaumMapEngineApi.so
--------------------------------------------------------------------------------
/android/src/main/res/layout/kakao_map_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
--------------------------------------------------------------------------------
/android/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | xxxxxx
3 |
4 |
--------------------------------------------------------------------------------
/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiggag/react-native-kakao-maps/bdd5782775c7cd229c2f824073ef6d7a90f23da8/example.png
--------------------------------------------------------------------------------
/example/.buckconfig:
--------------------------------------------------------------------------------
1 |
2 | [android]
3 | target = Google Inc.:Google APIs:23
4 |
5 | [maven_repositories]
6 | central = https://repo1.maven.org/maven2
7 |
--------------------------------------------------------------------------------
/example/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: '@react-native-community',
4 | };
5 |
--------------------------------------------------------------------------------
/example/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 | ; We fork some components by platform
3 | .*/*[.]android.js
4 |
5 | ; Ignore "BUCK" generated dirs
6 | /\.buckd/
7 |
8 | ; Ignore polyfills
9 | node_modules/react-native/Libraries/polyfills/.*
10 |
11 | ; Flow doesn't support platforms
12 | .*/Libraries/Utilities/LoadingView.js
13 |
14 | .*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
15 |
16 | [untyped]
17 | .*/node_modules/@react-native-community/cli/.*/.*
18 |
19 | [include]
20 |
21 | [libs]
22 | node_modules/react-native/interface.js
23 | node_modules/react-native/flow/
24 |
25 | [options]
26 | emoji=true
27 |
28 | exact_by_default=true
29 |
30 | format.bracket_spacing=false
31 |
32 | module.file_ext=.js
33 | module.file_ext=.json
34 | module.file_ext=.ios.js
35 |
36 | munge_underscores=true
37 |
38 | module.name_mapper='^react-native/\(.*\)$' -> '/node_modules/react-native/\1'
39 | module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/node_modules/react-native/Libraries/Image/RelativeImageStub'
40 |
41 | suppress_type=$FlowIssue
42 | suppress_type=$FlowFixMe
43 | suppress_type=$FlowFixMeProps
44 | suppress_type=$FlowFixMeState
45 |
46 | [lints]
47 | sketchy-null-number=warn
48 | sketchy-null-mixed=warn
49 | sketchy-number=warn
50 | untyped-type-import=warn
51 | nonstrict-import=warn
52 | deprecated-type=warn
53 | unsafe-getters-setters=warn
54 | unnecessary-invariant=warn
55 |
56 | [strict]
57 | deprecated-type
58 | nonstrict-import
59 | sketchy-null
60 | unclear-type
61 | unsafe-getters-setters
62 | untyped-import
63 | untyped-type-import
64 |
65 | [version]
66 | ^0.182.0
67 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | !default.perspectivev3
16 | xcuserdata
17 | *.xccheckout
18 | *.moved-aside
19 | DerivedData
20 | *.hmap
21 | *.ipa
22 | *.xcuserstate
23 | ios/.xcode.env.local
24 |
25 | # Android/IntelliJ
26 | #
27 | build/
28 | .idea
29 | .gradle
30 | local.properties
31 | *.iml
32 | *.hprof
33 | .cxx/
34 |
35 | # node.js
36 | #
37 | node_modules/
38 | npm-debug.log
39 | yarn-error.log
40 |
41 | # BUCK
42 | buck-out/
43 | \.buckd/
44 | *.keystore
45 | !debug.keystore
46 |
47 | # fastlane
48 | #
49 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
50 | # screenshots whenever they are needed.
51 | # For more information about the recommended setup visit:
52 | # https://docs.fastlane.tools/best-practices/source-control/
53 |
54 | **/fastlane/report.xml
55 | **/fastlane/Preview.html
56 | **/fastlane/screenshots
57 | **/fastlane/test_output
58 |
59 | # Bundle artifact
60 | *.jsbundle
61 |
62 | # Ruby / CocoaPods
63 | /ios/Pods/
64 | /vendor/bundle/
65 |
--------------------------------------------------------------------------------
/example/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | arrowParens: 'avoid',
3 | bracketSameLine: true,
4 | bracketSpacing: true,
5 | singleQuote: true,
6 | trailingComma: 'all',
7 | };
8 |
--------------------------------------------------------------------------------
/example/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/example/App.js:
--------------------------------------------------------------------------------
1 | import React, { useCallback } from 'react';
2 | import { SafeAreaView } from 'react-native';
3 | import { KakaoMapView } from '@jiggag/react-native-kakao-maps';
4 |
5 | const Constants = {
6 | CENTER_POINT: {
7 | lat: 37.59523,
8 | lng: 127.086,
9 | },
10 | MARKER_LIST: [
11 | {
12 | lat: 37.59523,
13 | lng: 127.086,
14 | markerName: 'marker',
15 | },
16 | {
17 | lat: 37.59523,
18 | lng: 127.08705,
19 | markerName: 'marker2',
20 | },
21 | ],
22 | };
23 |
24 | const App = () => {
25 | const onChange = useCallback(event => {
26 | console.log('[onChange]', event.nativeEvent);
27 | }, []);
28 |
29 | return (
30 |
31 |
39 |
40 | );
41 | };
42 |
43 | export default App;
44 |
--------------------------------------------------------------------------------
/example/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby '2.7.5'
5 |
6 | gem 'cocoapods', '~> 1.11', '>= 1.11.2'
7 |
--------------------------------------------------------------------------------
/example/__tests__/App-test.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @format
3 | */
4 |
5 | import 'react-native';
6 | import React from 'react';
7 | import App from '../App';
8 |
9 | // Note: test renderer must be required after react-native.
10 | import renderer from 'react-test-renderer';
11 |
12 | it('renders correctly', () => {
13 | renderer.create();
14 | });
15 |
--------------------------------------------------------------------------------
/example/_bundle/config:
--------------------------------------------------------------------------------
1 | BUNDLE_PATH: "vendor/bundle"
2 | BUNDLE_FORCE_RUBY_PLATFORM: 1
3 |
--------------------------------------------------------------------------------
/example/_node-version:
--------------------------------------------------------------------------------
1 | 16
2 |
--------------------------------------------------------------------------------
/example/_ruby-version:
--------------------------------------------------------------------------------
1 | 2.7.5
2 |
--------------------------------------------------------------------------------
/example/android/app/_BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
12 |
13 | lib_deps = []
14 |
15 | create_aar_targets(glob(["libs/*.aar"]))
16 |
17 | create_jar_targets(glob(["libs/*.jar"]))
18 |
19 | android_library(
20 | name = "all-libs",
21 | exported_deps = lib_deps,
22 | )
23 |
24 | android_library(
25 | name = "app-code",
26 | srcs = glob([
27 | "src/main/java/**/*.java",
28 | ]),
29 | deps = [
30 | ":all-libs",
31 | ":build_config",
32 | ":res",
33 | ],
34 | )
35 |
36 | android_build_config(
37 | name = "build_config",
38 | package = "com.jiggag.example",
39 | )
40 |
41 | android_resource(
42 | name = "res",
43 | package = "com.jiggag.example",
44 | res = "src/main/res",
45 | )
46 |
47 | android_binary(
48 | name = "app",
49 | keystore = "//android/keystores:debug",
50 | manifest = "src/main/AndroidManifest.xml",
51 | package_type = "debug",
52 | deps = [
53 | ":app-code",
54 | ],
55 | )
56 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 |
3 | import com.android.build.OutputFile
4 | import org.apache.tools.ant.taskdefs.condition.Os
5 |
6 | /**
7 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
8 | * and bundleReleaseJsAndAssets).
9 | * These basically call `react-native bundle` with the correct arguments during the Android build
10 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
11 | * bundle directly from the development server. Below you can see all the possible configurations
12 | * and their defaults. If you decide to add a configuration block, make sure to add it before the
13 | * `apply from: "../../node_modules/react-native/react.gradle"` line.
14 | *
15 | * project.ext.react = [
16 | * // the name of the generated asset file containing your JS bundle
17 | * bundleAssetName: "index.android.bundle",
18 | *
19 | * // the entry file for bundle generation. If none specified and
20 | * // "index.android.js" exists, it will be used. Otherwise "index.js" is
21 | * // default. Can be overridden with ENTRY_FILE environment variable.
22 | * entryFile: "index.android.js",
23 | *
24 | * // https://reactnative.dev/docs/performance#enable-the-ram-format
25 | * bundleCommand: "ram-bundle",
26 | *
27 | * // whether to bundle JS and assets in debug mode
28 | * bundleInDebug: false,
29 | *
30 | * // whether to bundle JS and assets in release mode
31 | * bundleInRelease: true,
32 | *
33 | * // whether to bundle JS and assets in another build variant (if configured).
34 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
35 | * // The configuration property can be in the following formats
36 | * // 'bundleIn${productFlavor}${buildType}'
37 | * // 'bundleIn${buildType}'
38 | * // bundleInFreeDebug: true,
39 | * // bundleInPaidRelease: true,
40 | * // bundleInBeta: true,
41 | *
42 | * // whether to disable dev mode in custom build variants (by default only disabled in release)
43 | * // for example: to disable dev mode in the staging build type (if configured)
44 | * devDisabledInStaging: true,
45 | * // The configuration property can be in the following formats
46 | * // 'devDisabledIn${productFlavor}${buildType}'
47 | * // 'devDisabledIn${buildType}'
48 | *
49 | * // the root of your project, i.e. where "package.json" lives
50 | * root: "../../",
51 | *
52 | * // where to put the JS bundle asset in debug mode
53 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
54 | *
55 | * // where to put the JS bundle asset in release mode
56 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
57 | *
58 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
59 | * // require('./image.png')), in debug mode
60 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
61 | *
62 | * // where to put drawable resources / React Native assets, e.g. the ones you use via
63 | * // require('./image.png')), in release mode
64 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
65 | *
66 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
67 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
68 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle
69 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
70 | * // for example, you might want to remove it from here.
71 | * inputExcludes: ["android/**", "ios/**"],
72 | *
73 | * // override which node gets called and with what additional arguments
74 | * nodeExecutableAndArgs: ["node"],
75 | *
76 | * // supply additional arguments to the packager
77 | * extraPackagerArgs: []
78 | * ]
79 | */
80 |
81 | project.ext.react = [
82 | enableHermes: true, // clean and rebuild if changing
83 | ]
84 |
85 | apply from: "../../node_modules/react-native/react.gradle"
86 |
87 | /**
88 | * Set this to true to create two separate APKs instead of one:
89 | * - An APK that only works on ARM devices
90 | * - An APK that only works on x86 devices
91 | * The advantage is the size of the APK is reduced by about 4MB.
92 | * Upload all the APKs to the Play Store and people will download
93 | * the correct one based on the CPU architecture of their device.
94 | */
95 | def enableSeparateBuildPerCPUArchitecture = false
96 |
97 | /**
98 | * Run Proguard to shrink the Java bytecode in release builds.
99 | */
100 | def enableProguardInReleaseBuilds = false
101 |
102 | /**
103 | * The preferred build flavor of JavaScriptCore.
104 | *
105 | * For example, to use the international variant, you can use:
106 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
107 | *
108 | * The international variant includes ICU i18n library and necessary data
109 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
110 | * give correct results when using with locales other than en-US. Note that
111 | * this variant is about 6MiB larger per architecture than default.
112 | */
113 | def jscFlavor = 'org.webkit:android-jsc:+'
114 |
115 | /**
116 | * Whether to enable the Hermes VM.
117 | *
118 | * This should be set on project.ext.react and that value will be read here. If it is not set
119 | * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
120 | * and the benefits of using Hermes will therefore be sharply reduced.
121 | */
122 | def enableHermes = project.ext.react.get("enableHermes", false);
123 |
124 | /**
125 | * Architectures to build native code for.
126 | */
127 | def reactNativeArchitectures() {
128 | def value = project.getProperties().get("reactNativeArchitectures")
129 | return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
130 | }
131 |
132 | android {
133 | ndkVersion rootProject.ext.ndkVersion
134 |
135 | compileSdkVersion rootProject.ext.compileSdkVersion
136 |
137 | defaultConfig {
138 | applicationId "com.jiggag.example"
139 | minSdkVersion rootProject.ext.minSdkVersion
140 | targetSdkVersion rootProject.ext.targetSdkVersion
141 | versionCode 1
142 | versionName "1.0"
143 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
144 |
145 | if (isNewArchitectureEnabled()) {
146 | // We configure the CMake build only if you decide to opt-in for the New Architecture.
147 | externalNativeBuild {
148 | cmake {
149 | arguments "-DPROJECT_BUILD_DIR=$buildDir",
150 | "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
151 | "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
152 | "-DNODE_MODULES_DIR=$rootDir/../node_modules",
153 | "-DANDROID_STL=c++_shared"
154 | }
155 | }
156 | if (!enableSeparateBuildPerCPUArchitecture) {
157 | ndk {
158 | abiFilters (*reactNativeArchitectures())
159 | }
160 | }
161 | }
162 | }
163 |
164 | if (isNewArchitectureEnabled()) {
165 | // We configure the NDK build only if you decide to opt-in for the New Architecture.
166 | externalNativeBuild {
167 | cmake {
168 | path "$projectDir/src/main/jni/CMakeLists.txt"
169 | }
170 | }
171 | def reactAndroidProjectDir = project(':ReactAndroid').projectDir
172 | def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
173 | dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
174 | from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
175 | into("$buildDir/react-ndk/exported")
176 | }
177 | def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
178 | dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
179 | from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
180 | into("$buildDir/react-ndk/exported")
181 | }
182 | afterEvaluate {
183 | // If you wish to add a custom TurboModule or component locally,
184 | // you should uncomment this line.
185 | // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
186 | preDebugBuild.dependsOn(packageReactNdkDebugLibs)
187 | preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
188 |
189 | // Due to a bug inside AGP, we have to explicitly set a dependency
190 | // between configureCMakeDebug* tasks and the preBuild tasks.
191 | // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
192 | configureCMakeRelWithDebInfo.dependsOn(preReleaseBuild)
193 | configureCMakeDebug.dependsOn(preDebugBuild)
194 | reactNativeArchitectures().each { architecture ->
195 | tasks.findByName("configureCMakeDebug[${architecture}]")?.configure {
196 | dependsOn("preDebugBuild")
197 | }
198 | tasks.findByName("configureCMakeRelWithDebInfo[${architecture}]")?.configure {
199 | dependsOn("preReleaseBuild")
200 | }
201 | }
202 | }
203 | }
204 |
205 | splits {
206 | abi {
207 | reset()
208 | enable enableSeparateBuildPerCPUArchitecture
209 | universalApk false // If true, also generate a universal APK
210 | include (*reactNativeArchitectures())
211 | }
212 | }
213 | signingConfigs {
214 | debug {
215 | storeFile file('debug.keystore')
216 | storePassword 'android'
217 | keyAlias 'androiddebugkey'
218 | keyPassword 'android'
219 | }
220 | }
221 | buildTypes {
222 | debug {
223 | signingConfig signingConfigs.debug
224 | }
225 | release {
226 | // Caution! In production, you need to generate your own keystore file.
227 | // see https://reactnative.dev/docs/signed-apk-android.
228 | signingConfig signingConfigs.debug
229 | minifyEnabled enableProguardInReleaseBuilds
230 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
231 | }
232 | }
233 |
234 | // applicationVariants are e.g. debug, release
235 | applicationVariants.all { variant ->
236 | variant.outputs.each { output ->
237 | // For each separate APK per architecture, set a unique version code as described here:
238 | // https://developer.android.com/studio/build/configure-apk-splits.html
239 | // Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
240 | def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
241 | def abi = output.getFilter(OutputFile.ABI)
242 | if (abi != null) { // null for the universal-debug, universal-release variants
243 | output.versionCodeOverride =
244 | defaultConfig.versionCode * 1000 + versionCodes.get(abi)
245 | }
246 |
247 | }
248 | }
249 | }
250 |
251 | dependencies {
252 | implementation fileTree(dir: "libs", include: ["*.jar"])
253 |
254 | //noinspection GradleDynamicVersion
255 | implementation "com.facebook.react:react-native:+" // From node_modules
256 |
257 | implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
258 |
259 | debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
260 | exclude group:'com.facebook.fbjni'
261 | }
262 |
263 | debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
264 | exclude group:'com.facebook.flipper'
265 | exclude group:'com.squareup.okhttp3', module:'okhttp'
266 | }
267 |
268 | debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
269 | exclude group:'com.facebook.flipper'
270 | }
271 |
272 | if (enableHermes) {
273 | //noinspection GradleDynamicVersion
274 | implementation("com.facebook.react:hermes-engine:+") { // From node_modules
275 | exclude group:'com.facebook.fbjni'
276 | }
277 | } else {
278 | implementation jscFlavor
279 | }
280 | }
281 |
282 | if (isNewArchitectureEnabled()) {
283 | // If new architecture is enabled, we let you build RN from source
284 | // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
285 | // This will be applied to all the imported transtitive dependency.
286 | configurations.all {
287 | resolutionStrategy.dependencySubstitution {
288 | substitute(module("com.facebook.react:react-native"))
289 | .using(project(":ReactAndroid"))
290 | .because("On New Architecture we're building React Native from source")
291 | substitute(module("com.facebook.react:hermes-engine"))
292 | .using(project(":ReactAndroid:hermes-engine"))
293 | .because("On New Architecture we're building Hermes from source")
294 | }
295 | }
296 | }
297 |
298 | // Run this once to be able to run the application with BUCK
299 | // puts all compile dependencies into folder libs for BUCK to use
300 | task copyDownloadableDepsToLibs(type: Copy) {
301 | from configurations.implementation
302 | into 'libs'
303 | }
304 |
305 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
306 |
307 | def isNewArchitectureEnabled() {
308 | // To opt-in for the New Architecture, you can either:
309 | // - Set `newArchEnabled` to true inside the `gradle.properties` file
310 | // - Invoke gradle with `-newArchEnabled=true`
311 | // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
312 | return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
313 | }
314 |
--------------------------------------------------------------------------------
/example/android/app/build_defs.bzl:
--------------------------------------------------------------------------------
1 | """Helper definitions to glob .aar and .jar targets"""
2 |
3 | def create_aar_targets(aarfiles):
4 | for aarfile in aarfiles:
5 | name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
6 | lib_deps.append(":" + name)
7 | android_prebuilt_aar(
8 | name = name,
9 | aar = aarfile,
10 | )
11 |
12 | def create_jar_targets(jarfiles):
13 | for jarfile in jarfiles:
14 | name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
15 | lib_deps.append(":" + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
20 |
--------------------------------------------------------------------------------
/example/android/app/debug.keystore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiggag/react-native-kakao-maps/bdd5782775c7cd229c2f824073ef6d7a90f23da8/example/android/app/debug.keystore
--------------------------------------------------------------------------------
/example/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/java/com/jiggag/example/ReactNativeFlipper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) Meta Platforms, Inc. and affiliates.
3 | *
4 | *
This source code is licensed under the MIT license found in the LICENSE file in the root
5 | * directory of this source tree.
6 | */
7 | package com.jiggag.example;
8 |
9 | import android.content.Context;
10 | import com.facebook.flipper.android.AndroidFlipperClient;
11 | import com.facebook.flipper.android.utils.FlipperUtils;
12 | import com.facebook.flipper.core.FlipperClient;
13 | import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
14 | import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
15 | import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
16 | import com.facebook.flipper.plugins.inspector.DescriptorMapping;
17 | import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
18 | import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
19 | import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
20 | import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
21 | import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
22 | import com.facebook.react.ReactInstanceEventListener;
23 | import com.facebook.react.ReactInstanceManager;
24 | import com.facebook.react.bridge.ReactContext;
25 | import com.facebook.react.modules.network.NetworkingModule;
26 | import okhttp3.OkHttpClient;
27 |
28 | public class ReactNativeFlipper {
29 | public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
30 | if (FlipperUtils.shouldEnableFlipper(context)) {
31 | final FlipperClient client = AndroidFlipperClient.getInstance(context);
32 |
33 | client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
34 | client.addPlugin(new ReactFlipperPlugin());
35 | client.addPlugin(new DatabasesFlipperPlugin(context));
36 | client.addPlugin(new SharedPreferencesFlipperPlugin(context));
37 | client.addPlugin(CrashReporterPlugin.getInstance());
38 |
39 | NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
40 | NetworkingModule.setCustomClientBuilder(
41 | new NetworkingModule.CustomClientBuilder() {
42 | @Override
43 | public void apply(OkHttpClient.Builder builder) {
44 | builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
45 | }
46 | });
47 | client.addPlugin(networkFlipperPlugin);
48 | client.start();
49 |
50 | // Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
51 | // Hence we run if after all native modules have been initialized
52 | ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
53 | if (reactContext == null) {
54 | reactInstanceManager.addReactInstanceEventListener(
55 | new ReactInstanceEventListener() {
56 | @Override
57 | public void onReactContextInitialized(ReactContext reactContext) {
58 | reactInstanceManager.removeReactInstanceEventListener(this);
59 | reactContext.runOnNativeModulesQueueThread(
60 | new Runnable() {
61 | @Override
62 | public void run() {
63 | client.addPlugin(new FrescoFlipperPlugin());
64 | }
65 | });
66 | }
67 | });
68 | } else {
69 | client.addPlugin(new FrescoFlipperPlugin());
70 | }
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
13 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/jiggag/example/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.example;
2 |
3 | import com.jiggag.example.BuildConfig;
4 | import com.facebook.react.ReactActivity;
5 | import com.facebook.react.ReactActivityDelegate;
6 | import com.facebook.react.ReactRootView;
7 |
8 | public class MainActivity extends ReactActivity {
9 |
10 | /**
11 | * Returns the name of the main component registered from JavaScript. This is used to schedule
12 | * rendering of the component.
13 | */
14 | @Override
15 | protected String getMainComponentName() {
16 | return "example";
17 | }
18 |
19 | /**
20 | * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
21 | * you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
22 | * (Paper).
23 | */
24 | @Override
25 | protected ReactActivityDelegate createReactActivityDelegate() {
26 | return new MainActivityDelegate(this, getMainComponentName());
27 | }
28 |
29 | public static class MainActivityDelegate extends ReactActivityDelegate {
30 | public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
31 | super(activity, mainComponentName);
32 | }
33 |
34 | @Override
35 | protected ReactRootView createRootView() {
36 | ReactRootView reactRootView = new ReactRootView(getContext());
37 | // If you opted-in for the New Architecture, we enable the Fabric Renderer.
38 | reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
39 | return reactRootView;
40 | }
41 |
42 | @Override
43 | protected boolean isConcurrentRootEnabled() {
44 | // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
45 | // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
46 | return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/jiggag/example/MainApplication.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.example;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 |
6 | import com.jiggag.example.BuildConfig;
7 | import com.facebook.react.PackageList;
8 | import com.facebook.react.ReactApplication;
9 | import com.facebook.react.ReactInstanceManager;
10 | import com.facebook.react.ReactNativeHost;
11 | import com.facebook.react.ReactPackage;
12 | import com.facebook.react.config.ReactFeatureFlags;
13 | import com.facebook.soloader.SoLoader;
14 | import com.jiggag.example.newarchitecture.MainApplicationReactNativeHost;
15 | import java.lang.reflect.InvocationTargetException;
16 | import java.util.List;
17 |
18 | public class MainApplication extends Application implements ReactApplication {
19 |
20 | private final ReactNativeHost mReactNativeHost =
21 | new ReactNativeHost(this) {
22 | @Override
23 | public boolean getUseDeveloperSupport() {
24 | return BuildConfig.DEBUG;
25 | }
26 |
27 | @Override
28 | protected List getPackages() {
29 | @SuppressWarnings("UnnecessaryLocalVariable")
30 | List packages = new PackageList(this).getPackages();
31 | // Packages that cannot be autolinked yet can be added manually here, for example:
32 | // packages.add(new MyReactNativePackage());
33 | return packages;
34 | }
35 |
36 | @Override
37 | protected String getJSMainModuleName() {
38 | return "index";
39 | }
40 | };
41 |
42 | private final ReactNativeHost mNewArchitectureNativeHost =
43 | new MainApplicationReactNativeHost(this);
44 |
45 | @Override
46 | public ReactNativeHost getReactNativeHost() {
47 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
48 | return mNewArchitectureNativeHost;
49 | } else {
50 | return mReactNativeHost;
51 | }
52 | }
53 |
54 | @Override
55 | public void onCreate() {
56 | super.onCreate();
57 | // If you opted-in for the New Architecture, we enable the TurboModule system
58 | ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
59 | SoLoader.init(this, /* native exopackage */ false);
60 | initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
61 | }
62 |
63 | /**
64 | * Loads Flipper in React Native templates. Call this in the onCreate method with something like
65 | * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
66 | *
67 | * @param context
68 | * @param reactInstanceManager
69 | */
70 | private static void initializeFlipper(
71 | Context context, ReactInstanceManager reactInstanceManager) {
72 | if (BuildConfig.DEBUG) {
73 | try {
74 | /*
75 | We use reflection here to pick up the class that initializes Flipper,
76 | since Flipper library is not available in release mode
77 | */
78 | Class> aClass = Class.forName("com.jiggag.example.ReactNativeFlipper");
79 | aClass
80 | .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
81 | .invoke(null, context, reactInstanceManager);
82 | } catch (ClassNotFoundException e) {
83 | e.printStackTrace();
84 | } catch (NoSuchMethodException e) {
85 | e.printStackTrace();
86 | } catch (IllegalAccessException e) {
87 | e.printStackTrace();
88 | } catch (InvocationTargetException e) {
89 | e.printStackTrace();
90 | }
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/jiggag/example/newarchitecture/MainApplicationReactNativeHost.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.example.newarchitecture;
2 |
3 | import android.app.Application;
4 | import androidx.annotation.NonNull;
5 | import com.facebook.react.PackageList;
6 | import com.facebook.react.ReactInstanceManager;
7 | import com.facebook.react.ReactNativeHost;
8 | import com.facebook.react.ReactPackage;
9 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
10 | import com.facebook.react.bridge.JSIModulePackage;
11 | import com.facebook.react.bridge.JSIModuleProvider;
12 | import com.facebook.react.bridge.JSIModuleSpec;
13 | import com.facebook.react.bridge.JSIModuleType;
14 | import com.facebook.react.bridge.JavaScriptContextHolder;
15 | import com.facebook.react.bridge.ReactApplicationContext;
16 | import com.facebook.react.bridge.UIManager;
17 | import com.facebook.react.fabric.ComponentFactory;
18 | import com.facebook.react.fabric.CoreComponentsRegistry;
19 | import com.facebook.react.fabric.FabricJSIModuleProvider;
20 | import com.facebook.react.fabric.ReactNativeConfig;
21 | import com.facebook.react.uimanager.ViewManagerRegistry;
22 | import com.jiggag.example.BuildConfig;
23 | import com.jiggag.example.newarchitecture.components.MainComponentsRegistry;
24 | import com.jiggag.example.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
25 | import java.util.ArrayList;
26 | import java.util.List;
27 |
28 | /**
29 | * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
30 | * TurboModule delegates and the Fabric Renderer.
31 | *
32 | *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
33 | * `newArchEnabled` property). Is ignored otherwise.
34 | */
35 | public class MainApplicationReactNativeHost extends ReactNativeHost {
36 | public MainApplicationReactNativeHost(Application application) {
37 | super(application);
38 | }
39 |
40 | @Override
41 | public boolean getUseDeveloperSupport() {
42 | return BuildConfig.DEBUG;
43 | }
44 |
45 | @Override
46 | protected List getPackages() {
47 | List packages = new PackageList(this).getPackages();
48 | // Packages that cannot be autolinked yet can be added manually here, for example:
49 | // packages.add(new MyReactNativePackage());
50 | // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
51 | // packages.add(new TurboReactPackage() { ... });
52 | // If you have custom Fabric Components, their ViewManagers should also be loaded here
53 | // inside a ReactPackage.
54 | return packages;
55 | }
56 |
57 | @Override
58 | protected String getJSMainModuleName() {
59 | return "index";
60 | }
61 |
62 | @NonNull
63 | @Override
64 | protected ReactPackageTurboModuleManagerDelegate.Builder
65 | getReactPackageTurboModuleManagerDelegateBuilder() {
66 | // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
67 | // for the new architecture and to use TurboModules correctly.
68 | return new MainApplicationTurboModuleManagerDelegate.Builder();
69 | }
70 |
71 | @Override
72 | protected JSIModulePackage getJSIModulePackage() {
73 | return new JSIModulePackage() {
74 | @Override
75 | public List getJSIModules(
76 | final ReactApplicationContext reactApplicationContext,
77 | final JavaScriptContextHolder jsContext) {
78 | final List specs = new ArrayList<>();
79 |
80 | // Here we provide a new JSIModuleSpec that will be responsible of providing the
81 | // custom Fabric Components.
82 | specs.add(
83 | new JSIModuleSpec() {
84 | @Override
85 | public JSIModuleType getJSIModuleType() {
86 | return JSIModuleType.UIManager;
87 | }
88 |
89 | @Override
90 | public JSIModuleProvider getJSIModuleProvider() {
91 | final ComponentFactory componentFactory = new ComponentFactory();
92 | CoreComponentsRegistry.register(componentFactory);
93 |
94 | // Here we register a Components Registry.
95 | // The one that is generated with the template contains no components
96 | // and just provides you the one from React Native core.
97 | MainComponentsRegistry.register(componentFactory);
98 |
99 | final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
100 |
101 | ViewManagerRegistry viewManagerRegistry =
102 | new ViewManagerRegistry(
103 | reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
104 |
105 | return new FabricJSIModuleProvider(
106 | reactApplicationContext,
107 | componentFactory,
108 | ReactNativeConfig.DEFAULT_CONFIG,
109 | viewManagerRegistry);
110 | }
111 | });
112 | return specs;
113 | }
114 | };
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/jiggag/example/newarchitecture/components/MainComponentsRegistry.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.example.newarchitecture.components;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.proguard.annotations.DoNotStrip;
5 | import com.facebook.react.fabric.ComponentFactory;
6 | import com.facebook.soloader.SoLoader;
7 |
8 | /**
9 | * Class responsible to load the custom Fabric Components. This class has native methods and needs a
10 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
11 | * folder for you).
12 | *
13 | *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
14 | * `newArchEnabled` property). Is ignored otherwise.
15 | */
16 | @DoNotStrip
17 | public class MainComponentsRegistry {
18 | static {
19 | SoLoader.loadLibrary("fabricjni");
20 | }
21 |
22 | @DoNotStrip private final HybridData mHybridData;
23 |
24 | @DoNotStrip
25 | private native HybridData initHybrid(ComponentFactory componentFactory);
26 |
27 | @DoNotStrip
28 | private MainComponentsRegistry(ComponentFactory componentFactory) {
29 | mHybridData = initHybrid(componentFactory);
30 | }
31 |
32 | @DoNotStrip
33 | public static MainComponentsRegistry register(ComponentFactory componentFactory) {
34 | return new MainComponentsRegistry(componentFactory);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/example/android/app/src/main/java/com/jiggag/example/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java:
--------------------------------------------------------------------------------
1 | package com.jiggag.example.newarchitecture.modules;
2 |
3 | import com.facebook.jni.HybridData;
4 | import com.facebook.react.ReactPackage;
5 | import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
6 | import com.facebook.react.bridge.ReactApplicationContext;
7 | import com.facebook.soloader.SoLoader;
8 | import java.util.List;
9 |
10 | /**
11 | * Class responsible to load the TurboModules. This class has native methods and needs a
12 | * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
13 | * folder for you).
14 | *
15 | *