Skip to content
Developers Docs

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:

  1. 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-check to 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.
  2. Material Components host theme. The SDK's fullscreen map UI inflates com.google.android.material widgets, 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).