From e67cd642d6633a3b3f8db5f51176232dab205913 Mon Sep 17 00:00:00 2001 From: Jakub Kasprzyk Date: Tue, 28 Jul 2026 16:15:35 +0200 Subject: [PATCH 1/3] fix: resolve iOS startup crash on React Native 0.80+ by updating folly configuration --- CHANGELOG.md | 8 ++++++++ docs/docs/troubleshooting.md | 13 +++++++++++++ package/NitroPay.podspec | 19 +++++++++++++++---- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc3afb..49211d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to this project are documented in this file. +## Unreleased + +### Fixed + +- **iOS startup crash on React Native 0.80+ (`folly dynamic.cpp:378 Check failed: 0`).** + `NitroPay.podspec` no longer defines `FOLLY_NO_CONFIG` on React Native ≥ 0.80 + (mismatched folly config vs React Native core). Flags remain for React Native < 0.80. + ## 0.0.16 — 2026-07-07 ### Breaking changes diff --git a/docs/docs/troubleshooting.md b/docs/docs/troubleshooting.md index 2c21b14..da90be2 100644 --- a/docs/docs/troubleshooting.md +++ b/docs/docs/troubleshooting.md @@ -14,6 +14,19 @@ npx expo prebuild --clean ## iOS (Apple Pay) +### App crashes at launch with `folly dynamic.cpp:378 Check failed: 0` + +On React Native 0.80+ (e.g. Expo SDK 57), the app can abort at startup with a stack +ending in `folly::dynamic::get()` / `BaseViewProps`. Linking the library is +enough; no pay button needs to be on screen. + +Cause: `NitroPay.podspec` defined `FOLLY_NO_CONFIG`, mismatching React Native core's +folly config. **Fixed after 0.0.16** — upgrade, then rebuild: + +```bash +npx expo prebuild --clean +``` + ### Apple Pay button not showing - **Merchant ID mismatch:** The Expo plugin `merchantIdentifier` must exactly match your Apple Developer Merchant ID. diff --git a/package/NitroPay.podspec b/package/NitroPay.podspec index 7c4d1b1..7f9b8f1 100644 --- a/package/NitroPay.podspec +++ b/package/NitroPay.podspec @@ -22,10 +22,21 @@ Pod::Spec.new do |s| "cpp/**/*.{hpp,cpp}", ] - s.pod_target_xcconfig = { - # C++ compiler flags, mainly for folly. - "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES" - } + # FOLLY_NO_CONFIG conflicts with RN >= 0.80's generated folly-config.h. + react_native_below_80 = begin + pod_root = Pod::Config.instance.installation_root.to_s + rn_package_path = `cd "#{pod_root}" && node --print "require.resolve('react-native/package.json')"`.strip + File.exist?(rn_package_path) && JSON.parse(File.read(rn_package_path))["version"].split(".")[1].to_i < 80 + rescue StandardError + false + end + + if react_native_below_80 + s.pod_target_xcconfig = { + # C++ compiler flags, mainly for folly. + "GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES" + } + end load 'nitrogen/generated/ios/NitroPay+autolinking.rb' add_nitrogen_files(s) From 88f2ab583829bdf136d92e0764ddfb3ce9495f1b Mon Sep 17 00:00:00 2001 From: Jakub Kasprzyk Date: Wed, 16 Sep 2026 13:29:26 +0200 Subject: [PATCH 2/3] fix(ios): fail hard when React Native version detection fails Silent rescue-to-false could skip Folly flags on RN < 0.80 or hide a broken install. Raise during pod install instead, and compare versions with Gem::Version. Co-authored-by: Cursor --- package/NitroPay.podspec | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/package/NitroPay.podspec b/package/NitroPay.podspec index 7f9b8f1..fc0f498 100644 --- a/package/NitroPay.podspec +++ b/package/NitroPay.podspec @@ -23,12 +23,24 @@ Pod::Spec.new do |s| ] # FOLLY_NO_CONFIG conflicts with RN >= 0.80's generated folly-config.h. - react_native_below_80 = begin - pod_root = Pod::Config.instance.installation_root.to_s - rn_package_path = `cd "#{pod_root}" && node --print "require.resolve('react-native/package.json')"`.strip - File.exist?(rn_package_path) && JSON.parse(File.read(rn_package_path))["version"].split(".")[1].to_i < 80 - rescue StandardError - false + # Fail hard if React Native cannot be resolved — a silent fallback would apply + # the wrong Folly flags and either crash modern RN or break older installs. + pod_root = Pod::Config.instance.installation_root.to_s + rn_package_path = `cd "#{pod_root}" && node --print "require.resolve('react-native/package.json')"`.strip + unless $?.success? && !rn_package_path.empty? && File.exist?(rn_package_path) + raise "NitroPay: unable to resolve react-native/package.json from #{pod_root}. " \ + "Install React Native before running `pod install`." + end + + rn_version = JSON.parse(File.read(rn_package_path))["version"] + if rn_version.nil? || rn_version.to_s.strip.empty? + raise "NitroPay: react-native package.json is missing a version field (#{rn_package_path})." + end + + begin + react_native_below_80 = Gem::Version.new(rn_version) < Gem::Version.new("0.80.0") + rescue ArgumentError + raise "NitroPay: unable to parse React Native version #{rn_version.inspect} from #{rn_package_path}." end if react_native_below_80 From 2825be4b89a29161418ae394e3f9ee68a6b2f5d2 Mon Sep 17 00:00:00 2001 From: Jakub Kasprzyk Date: Wed, 16 Sep 2026 13:41:40 +0200 Subject: [PATCH 3/3] fix(ios): resolve React Native path without shell interpolation Use Open3.capture3 with chdir so installation_root is not interpolated into a shell command during pod install. Co-authored-by: Cursor --- package/NitroPay.podspec | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/package/NitroPay.podspec b/package/NitroPay.podspec index fc0f498..a828736 100644 --- a/package/NitroPay.podspec +++ b/package/NitroPay.podspec @@ -1,4 +1,5 @@ require "json" +require "open3" package = JSON.parse(File.read(File.join(__dir__, "package.json"))) @@ -26,8 +27,14 @@ Pod::Spec.new do |s| # Fail hard if React Native cannot be resolved — a silent fallback would apply # the wrong Folly flags and either crash modern RN or break older installs. pod_root = Pod::Config.instance.installation_root.to_s - rn_package_path = `cd "#{pod_root}" && node --print "require.resolve('react-native/package.json')"`.strip - unless $?.success? && !rn_package_path.empty? && File.exist?(rn_package_path) + rn_package_path, _stderr, status = Open3.capture3( + "node", + "--print", + "require.resolve('react-native/package.json')", + chdir: pod_root + ) + rn_package_path = rn_package_path.strip + unless status.success? && !rn_package_path.empty? && File.exist?(rn_package_path) raise "NitroPay: unable to resolve react-native/package.json from #{pod_root}. " \ "Install React Native before running `pod install`." end