stadiamaps / stadiamaps/ferrostar

Expo SDK 57: CocoaPods notes from wrapping FerrostarCore (no SPM)

Open
#947 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
419
Forks
81
Avg merge
6d 1h
Merged PRs (30d)
7

Description

We wired Ferrostar 0.53 into an Expo SDK 57 / React Native 0.86 iOS app by wrapping FerrostarCore as a local Expo module and vendoring the release XCFramework as CocoaPods. MapLibre React Native draws the map; we did not use FerrostarMapLibreUI.

This is the path #116 described. A few things we hit may save the next Expo integrator some time, and a couple look worth documenting (or shipping as official podspecs).

spm_dependency still does not work on Expo 57

RN's SPM-via-CocoaPods support landed, but it is not enough here:

  • RN only links SPM products cleanly with USE_FRAMEWORKS=dynamic
  • That is also what lets the linker see UniFFI's static libferrostar.a
  • Expo SDK 57's precompiled React and Expo pods are static
  • pod install rejects the mix

Vendoring libferrostar-rs.xcframework as vendored_frameworks sidesteps all of that. No USE_FRAMEWORKS override.

spmPackages in a local module's expo-module.config.json is the wrong hook. That field is for precompiled third-party XCFrameworks, not a local Expo module.

Do not name a CocoaPod Ferrostar

A pod named Ferrostar builds libFerrostar.a. The Rust core is libferrostar.a. macOS filesystems are case-insensitive, and the pod's search path is listed first, so -lferrostar resolves to the wrapper.

The linker reports no error. Every _uniffi_ferrostar_* symbol comes back undefined.

We named the wrapper pod ExpoFerrostar and kept the JS module name Ferrostar. @stadiamaps/ferrostar-uniffi-react-native already uses FerrostarUniffiReactNative, so the official RN package avoids this — but anyone wrapping FerrostarCore via CocoaPods will hit it.

Official FerrostarCore + FerrostarCoreFFI podspecs would unblock Expo

We had to invent these. They have to be separate pods: a single pod is a single Swift module, and the Expo module imports both by name.

Pod What it is
FerrostarCoreFFI libferrostar-rs.xcframework + generated UniFFI Swift
FerrostarCore apple/Sources/FerrostarCore only
wrapper thin Expo / RN module

Pin s.swift_version = '5.0' on the vendored pods. Ferrostar's Package.swift is swift-tools-version: 5.9; Expo's own pods build at 6.0, and leaving this unset compiles Ferrostar under Swift 6 concurrency checks it was never written against.

iOS 16+ is already satisfied by Expo SDK 57 (16.4).

Fetch / packaging

  • Pin a tag, not a branch. Generated UniFFI bindings are checked into source control.
  • Take the zip checksum from releaseChecksum in Package.swift.
  • Unpack the release zip with ditto -x -k. Other unzippers can mangle the XCFramework.
  • Fail at pod install if the payload is missing. An empty source_files glob becomes hundreds of unresolved Swift symbols and says nothing about the cause.

Small 0.53 API notes

  • RouteDeviation is .noDeviation or .deviation(kind:), not .offRoute
  • stepAdvanceDistanceEntryAndExit argument order is distanceToEndOfStep, distanceAfterEndOfStep, minimumHorizontalAccuracy
  • If the host app has its own TTS, mute Ferrostar's (spokenInstructionObserver: .initAVSpeechSynthesizer(isMuted: true)) or the driver hears every turn twice
  • We let Ferrostar fetch its own Valhalla route rather than re-encoding a host Route. One extra request, much less version coupling

Happy to share the podspecs if useful. We are not asking you to take the Expo wrapper — just flagging the CocoaPods / Expo 57 path that actually linked.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the referenced integration points: expo-module.config.json, apple/Sources/FerrostarCore, and Package.swift, including its releaseChecksum and packaging path. Determine whether the project wants documentation, official podspecs, or both. Done means capturing the working Expo SDK 57 CocoaPods path and the stated pod, packaging, Swift-version, and API requirements without expanding the scope beyond this report.

Written by the indexing model from the issue text.

Assessment

Tech stack
ios, react-native, rust, swift
Domain
build-system, documentation, mobile
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.