Skip to content

App crashes on iOS because Turf dependency is statically linked #117

@rynop

Description

@rynop

Mapbox iOS SDK has a direct dependency on Turf:

platforms/ios/Pods/Manifest.lock:

PODS:
  - MapboxCommon (24.16.0):
    - Turf (= 4.0.0)
  - MapboxCoreMaps (11.16.0):
    - MapboxCommon (= 24.16.0)
  - MapboxMaps (11.16.0):
    - MapboxCommon (= 24.16.0)
    - MapboxCoreMaps (= 11.16.0)
    - Turf (= 4.0.0)
  - Turf (4.0.0)

DEPENDENCIES:
  - MapboxMaps (= 11.16.0)

SPEC REPOS:
  trunk:
    - MapboxCommon
    - MapboxCoreMaps
    - MapboxMaps
    - Turf

SPEC CHECKSUMS:
  MapboxCommon: 479562bceca6b10d1c3b8bca5006ef86c51d7255
  MapboxCoreMaps: b96038f97c62e0e72ebece2a3b909ca4eda8ab21
  MapboxMaps: 8c0f733a3250a03bcc4938347ca5f699b0804ce1
  Turf: c9eb11a65d96af58cac523460fd40fec5061b081

PODFILE CHECKSUM: f6674181ce436808c11898b4cfe43b4acd0b271f

COCOAPODS: 1.11.3

I run ns dev ios and app sucessfully installs on iPhone simulator:

...
Successfully transferred all files on device 80625F8F-6D98-4F85-88C7-426B8DAC4FD8.
...

The app launches and then immediately crashes. I fed the crash log into AI and it says it was because:

When you install MapboxMaps, CocoaPods automatically pulls in Turf as a dependency. The crash occurred because Turf is a statically linked framework that wasn't being properly handled by the default CocoaPods configuration. That's why we needed to use use_frameworks! :linkage => :static and add the pre-install hook to handle Turf as a static library.

Thoughts? This is over my head.

My partial crash log:

Hardware Model:      iMac20,2
Process:             nativemobile [91976]
Path:                /Users/USER/Library/Developer/CoreSimulator/Devices/80625F8F-6D98-4F85-88C7-426B8DAC4FD8/data/Containers/Bundle/Application/0A734048-D354-4562-A5F3-92814E5963EE/nativemobile.app/nativemobile
Identifier:          com.rynop.<redacted>
Version:             1.0 (1.0)
Code Type:           X86-64 (Native)
Role:                Foreground
Parent Process:      launchd_sim [53705]
Coalition:           <redacted>
Responsible Process: SimulatorTrampoline [53089]

Date/Time:           2025-11-26 21:14:33.3845 -0600
Launch Time:         2025-11-26 21:14:33.2735 -0600
OS Version:          macOS 15.6.1 (24G90)
Release Type:        User
Report Version:      104

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: DYLD 1 Library missing
Library not loaded: @rpath/Turf.framework/Turf
Referenced from: <6587096F-17E2-3E46-9CB7-0A7C10BFBC87> /Users/USER/Library/Developer/CoreSimulator/Devices/80625F8F-6D98-4F85-88C7-426B8DAC4FD8/data/Containers/Bundle/Application/0A734048-D354-4562-A5F3-92814E5963EE/nativemobile.app/nativemobile
Reason: tried: '/Library/Developer/CoreSimulator/Volumes/iOS_22F77/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS 18.5.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/Turf.framework/Turf' (no such file), '/usr/lib/swift/Turf.framework/Turf' (no such file, not in dyld cache), '/Users/rynop/Library/Developer/CoreSimulator/Devices/80625F8F-6D98-4F85-88C7-426B8DAC4FD8/data/Containers/Bundle/Application/0A734048-D354-4562-A5F3-92814E5963EE/nativemobile.app/Frameworks/Turf.framework/Turf' (no such file), '/Users/rynop/Library/Developer/CoreSimulator/Devices/80625F8F-6D98-4F85-88C7-426B8DAC4FD8/data/Containers/Bundle/Application/0A734048-D354-4562-A5F3-92814E5963EE/nativemobile.app/Frameworks/Turf.framework
(terminated at launch; ignore backtrace)

Version info:

node -v
v22.12.0

ns -version
9.0.1

xcodebuild -version
Xcode 16.4
Build version 16F6

package.json:

{
  "name": "REDACTED",
  "main": "./src/main.ts",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev:ios": "ns debug ios --env.replace=./src/environments/environment.ts:./src/environments/environment.dev.ts",
    "dev:android": "ns debug android --env.replace=./src/environments/environment.ts:./src/environments/environment.dev.ts",
    "build:ios": "ns build ios --env.replace=./src/environments/environment.ts:./src/environments/environment.prod.ts",
    "build:android": "ns build --env.replace=./src/environments/environment.ts:./src/environments/environment.prod.ts",
    "build:staging:ios": "ns build ios --env.replace=./src/environments/environment.ts:./src/environments/environment.staging.ts",
    "build:staging:android": "ns build android --env.replace=./src/environments/environment.ts:./src/environments/environment.staging.ts",
    "postinstall": "node scripts/fix-podfile.js"
  },
  "dependencies": {
    "@angular/animations": "~20.2.0",
    "@angular/common": "~20.2.0",
    "@angular/compiler": "~20.2.0",
    "@angular/core": "~20.2.0",
    "@angular/forms": "~20.2.0",
    "@angular/platform-browser": "~20.2.0",
    "@angular/platform-browser-dynamic": "~20.2.0",
    "@angular/router": "~20.2.0",
    "@nativescript-community/ui-mapbox": "~7.0.12",
    "@nativescript/angular": "~20.0.0",
    "@nativescript/core": "~9.0.0",
    "rxjs": "~7.8.0",
    "zone.js": "~0.15.0"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~20.2.0",
    "@angular/compiler-cli": "~20.2.0",
    "@nativescript/ios": "~9.0.0",
    "@nativescript/tailwind": "~4.0.5",
    "@nativescript/types": "~9.0.0",
    "@nativescript/webpack": "~5.0.25",
    "@ngtools/webpack": "~20.2.0",
    "tailwindcss": "~4.1.0",
    "typescript": "~5.8.0"
  }
}

FWIW AI said to add the following - this did NOT work (same crash)

package.json::scripts:

"postinstall": "node scripts/fix-podfile.js"

node scripts/fix-podfile.js:

const fs = require('fs');
const path = require('path');

// Path to the generated Podfile
const podfilePath = path.join(__dirname, '..', 'platforms', 'ios', 'Podfile');

if (fs.existsSync(podfilePath)) {
  let podfileContent = fs.readFileSync(podfilePath, 'utf8');

  // Replace use_frameworks! with use_frameworks! :linkage => :static and add Turf handling
  const targetMatch = /target "nativemobile" do/;
  if (podfileContent.includes('use_frameworks!') && targetMatch.test(podfileContent)) {
    podfileContent = podfileContent.replace(
      /use_frameworks!/,
      `use_frameworks! :linkage => :static`
    );

    // Add pre_install hook if not already present
    if (!podfileContent.includes('pre_install do |installer|')) {
      podfileContent = podfileContent.replace(
        /(pod 'MapboxMaps', '11\.16\.0'\n# End Podfile\nend)/,
        `pod 'MapboxMaps', '11.16.0'
# End Podfile

  # Pre-install hook to handle static frameworks
  pre_install do |installer|
    installer.pod_targets.each do |pod|
      if pod.name.eql?('Turf')
        def pod.build_type
          Pod::BuildType.static_library
        end
      end
    end
  end
end`
      );
    }

    fs.writeFileSync(podfilePath, podfileContent, 'utf8');
    console.log('Fixed Podfile: Added static linkage and Turf handling');
  } else {
    console.log('Podfile already configured correctly');
  }
} else {
  console.log('Podfile not found, skipping fix.');
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions