React Native getting started
This guide takes you through integrating the Mapsted React Native library
(@mapsted/maps-react-native) against the native Mapsted SDK 26.7.1.
Breaking change from the 6.x wrapper
Version 26.7.2 of the wrapper is built on the 26.7.1 native SDK, which raises the minimum toolchain (below). These are breaking for apps that were on the old 6.x wrapper — treat this as a major upgrade, not a drop-in bump. See the React Native migration guide for the complete, step-by-step upgrade.
1. Install the library
npm install @mapsted/maps-react-native@26.7.2
The wrapper is a public, proprietary-licensed package on npm under the official @mapsted
scope; use of the SDK requires a valid Mapsted commercial licence (see the bundled LICENSE).
Minimum React Native: 0.76 (certified on 0.76.9). React Native 0.74 and older cannot consume the 26.7.1 Android artifacts — their Kotlin 1.9.0 toolchain cannot read the artifacts' Kotlin 2.3.20 metadata, and forcing a newer Kotlin on the 0.74 Gradle plugin breaks it outright.
2. Consumer toolchain — minimum versions
| Platform | Minimum |
|---|---|
| React Native | 0.76 (certified on 0.76.9) |
| Android | minSdkVersion 26; AGP 8.6+, Gradle 8.10+, Kotlin 1.9.25 — the defaults React Native 0.76.9 ships with; a Material Components host theme and one Kotlin compiler flag (both below) |
| iOS | deployment target 16.0 (React Native's default 15.1 cannot resolve the 26.7.1 pods) |
Two Android changes are required beyond a stock React Native 0.76.9 project — both are covered in step 4:
- Kotlin metadata flag. The 26.7.1 Android artifacts are compiled with Kotlin 2.3.20 and carry
its metadata. Keep React Native 0.76.9's default Kotlin (1.9.25) — do not force the Kotlin
Gradle plugin to 2.x, which breaks React Native 0.76's own Gradle plugin — and instead add
-Xskip-metadata-version-checkto your app module's Kotlin options so the 1.9.25 compiler reads the newer metadata. This is the standard, safe way to consume a library built with a newer Kotlin. - Material Components host theme. The SDK's fullscreen map UI inflates
com.google.android.materialwidgets, so your app theme must derive from a Material Components theme or the map screen crashes on open (InflateException … MaterialButton).
3. iOS setup
Your app must use CocoaPods. In your Podfile:
1. Add the Mapsted podspec sources (the 26.7.1 pods live in the MapstedHQ spec repo):
source 'https://cdn.cocoapods.org/'
source 'https://github.com/MapstedHQ/podspec.git'
2. Set the platform to 16.0:
platform :ios, '16.0'
Disable the New Architecture on iOS
The Mapsted bridge ships as a legacy (paper) native module. React Native 0.76 turns the
New Architecture on by default for iOS, which leaves the legacy Mapsted module unregistered —
launchMapActivity() then silently does nothing and no map appears. Disable it (parity with the
Android sample's newArchEnabled=false) by adding this to the top of your Podfile before
use_react_native!:
ruby
ENV['RCT_NEW_ARCH_ENABLED'] = '0'
(or run RCT_NEW_ARCH_ENABLED=0 pod install). Verified: the map renders only with the New
Architecture disabled.
3. Choose ONE linkage option.
Option A (recommended for a standard RN app without use_frameworks!) — force the two
prebuilt-dynamic transitive dependencies to build as dynamic frameworks, otherwise the app
crashes at launch with Library not loaded: @rpath/SDWebImage.framework:
dynamic_frameworks = ['SDWebImage', 'SSZipArchive']
pre_install do |installer|
installer.pod_targets.each do |pod|
if dynamic_frameworks.include?(pod.name)
def pod.build_type; Pod::BuildType.dynamic_framework; end
end
end
end
Option B — set use_frameworks! on your app target. Everything links dynamically, so
the hook above is unnecessary. Simpler, but it changes linkage for your whole app.
4. Run pod install (or pod update).
5. Add your licence file to Copy Bundle Resources: your_ios_license.key.
6. Add the required Info.plist usage-description keys (iOS terminates the app on location
access without them): NSLocationWhenInUseUsageDescription,
NSLocationAlwaysAndWhenInUseUsageDescription, NSBluetoothAlwaysUsageDescription,
NSMotionUsageDescription.
Licence is bound to your bundle id
Mapsted licences are issued for a specific OS and bundle id. An Android licence will
not load on iOS — use the .key issued for your iOS bundle id (or the bundle-agnostic demo
key for demo properties).
4. Android setup
Set minSdkVersion 26 in android/build.gradle (installing the package also does this for you via
its postinstall script; see the migration guide). Keep React Native 0.76.9's default Kotlin, then:
1. Add the Kotlin metadata flag to your app module (android/app/build.gradle):
android {
kotlinOptions {
freeCompilerArgs += ["-Xskip-metadata-version-check"]
}
}
2. Use a Material Components host theme (android/app/src/main/res/values/styles.xml) so the
SDK's map UI can inflate its Material widgets — the .Bridge variant keeps React Native's
AppCompat views working:
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
3. The wrapper pulls the SDK from the GitHub-Pages Maven repo
(https://mapstedhq.github.io/mapsted-android-maven) — no Artifactory or JitPack. It also injects
minSdkVersion 26 and the SDK dependency via its postinstall script; if your CI installs with
--ignore-scripts, apply those two changes manually (they are listed in the migration guide).
4. Add your licence file to the assets folder: app/src/main/assets/your_android_license.key.
A complete, working reference is the sample app —
MapstedHQ/MapstedSampleReactNative(React Native 0.76.9, certified on real Pixel 8 / Galaxy S23 / Pixel 9).
5. Usage
import { MapstedMapView, launchMapActivity } from '@mapsted/maps-react-native';
// Embedded map — auto-plots the property indoors on mount:
<MapstedMapView
propertyId={504}
pipMode="expanded"
style={{ flex: 1 }}
onMapReady={() => {}}
onMapLoadError={(e) => { /* safety-net event if a load ever fails to complete */ }}
/>
// Route + turn-by-turn navigation (destinations are entities on ONE property):
<MapstedMapView
propertyId={504}
destinations={[{ propertyId: 504, buildingId: 504, entityId: 121, floorId: 941 }]}
startNavigation={startNav}
onRouteReady={/* ... */}
onNavigationInstructionStarted={(e) => { /* e.nativeEvent.currentInstruction */ }}
/>
// Fullscreen property picker → indoor map:
await launchMapActivity();
Use the embedded MapstedMapView for production surfaces
The embedded MapstedMapView is the recommended, certified integration path — validated on real arm64 hardware, including first launch — and is the best choice for production surfaces. The fullscreen launchMapActivity() opens the native SDK's own full-screen map screen and is well suited to quick previews and simple full-screen use.
Destination entity ids are the property's own building-entity ids (the same on iOS and Android —
e.g. on Square One, property 504, entityId 121 = "Chipotle Mexican Grill" on floorId 941).
Resolve them from the property's BuildingEntities or CoreApi.PropertyManager.findEntityByName.
6. Indoor map loading (SDK 26.7.1)
Physical devices are fully supported; indoor maps, auto-plot, and navigation render correctly on
real arm64 Android, including the first launch after install. On the very first cold start the
map database initializes once, then
the property plots automatically. The embedded MapstedMapView also emits an onMapLoadError
safety-net event if a load ever fails to complete. Navigation routes from the live indoor position
(needs a mapped venue or location simulation).