Upgrade to Expo SDK 57 for Xcode 27 support

- expo 57.0.23, react-native 0.86.3, react 19.2.3
- Remove @react-navigation/* direct deps (unsupported by expo-router 56+)
- Drop newArchEnabled and android.edgeToEdgeEnabled (removed from schema)
- Enable ios.enableSceneSupport (UIScene lifecycle required by iOS 27 SDK)
- Remove deprecated expo-build-properties deploymentTarget (default 16.4)
- Add withPodsDeploymentTarget plugin: raise CocoaPods resource bundle
  targets (RNCAsyncStorage, RNSVG, SDWebImage) to the app minimum
- Replace removed StyleSheet.absoluteFillObject with absoluteFill

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-16 12:54:53 +02:00
co-authored by Claude Opus 5
parent 2653c7cad6
commit 5c66e9d5cb
5 changed files with 2096 additions and 2990 deletions
+8 -4
View File
@@ -7,7 +7,6 @@
"icon": "./assets/images/icon.png", "icon": "./assets/images/icon.png",
"scheme": "fonsiapp", "scheme": "fonsiapp",
"userInterfaceStyle": "automatic", "userInterfaceStyle": "automatic",
"newArchEnabled": true,
"ios": { "ios": {
"supportsTablet": true, "supportsTablet": true,
"bundleIdentifier": "com.pcrt.fonsi.app" "bundleIdentifier": "com.pcrt.fonsi.app"
@@ -17,7 +16,6 @@
"foregroundImage": "./assets/images/adaptive-icon.png", "foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff" "backgroundColor": "#ffffff"
}, },
"edgeToEdgeEnabled": true,
"predictiveBackGestureEnabled": false, "predictiveBackGestureEnabled": false,
"permissions": [ "permissions": [
"android.permission.CAMERA", "android.permission.CAMERA",
@@ -57,10 +55,16 @@
"expo-build-properties", "expo-build-properties",
{ {
"ios": { "ios": {
"deploymentTarget": "15.1" "enableSceneSupport": true
} }
} }
] ],
"expo-image",
"expo-secure-store",
"expo-sharing",
"expo-status-bar",
"expo-web-browser",
"./plugins/withPodsDeploymentTarget"
], ],
"experiments": { "experiments": {
"typedRoutes": true, "typedRoutes": true,
+3 -3
View File
@@ -52,7 +52,7 @@ export default function QrScanModal({ visible, onClose, onScan }: QrScanModalPro
<View className="flex-1 bg-black"> <View className="flex-1 bg-black">
{/* Camera Full Screen */} {/* Camera Full Screen */}
<CameraView <CameraView
style={StyleSheet.absoluteFillObject} style={StyleSheet.absoluteFill}
facing="back" facing="back"
onBarcodeScanned={scanned ? undefined : handleBarCodeScanned} onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
barcodeScannerSettings={{ barcodeScannerSettings={{
@@ -61,7 +61,7 @@ export default function QrScanModal({ visible, onClose, onScan }: QrScanModalPro
/> />
{/* Mask Overlay with transparent cutout */} {/* Mask Overlay with transparent cutout */}
<View style={StyleSheet.absoluteFillObject} pointerEvents="none"> <View style={StyleSheet.absoluteFill} pointerEvents="none">
<View className="flex-1 bg-black/60" /> <View className="flex-1 bg-black/60" />
<View style={{ height: squareSize }} className="flex-row"> <View style={{ height: squareSize }} className="flex-row">
<View className="flex-1 bg-black/60" /> <View className="flex-1 bg-black/60" />
@@ -85,7 +85,7 @@ export default function QrScanModal({ visible, onClose, onScan }: QrScanModalPro
</View> </View>
{/* UI Overlay */} {/* UI Overlay */}
<SafeAreaView style={StyleSheet.absoluteFillObject} pointerEvents="box-none"> <SafeAreaView style={StyleSheet.absoluteFill} pointerEvents="box-none">
<View className="flex-1 justify-between pt-8"> <View className="flex-1 justify-between pt-8">
{/* Header */} {/* Header */}
<View className="items-center"> <View className="items-center">
+2016 -2945
View File
File diff suppressed because it is too large Load Diff
+35 -38
View File
@@ -17,57 +17,54 @@
"dependencies": { "dependencies": {
"@expo/vector-icons": "^15.0.3", "@expo/vector-icons": "^15.0.3",
"@react-native-async-storage/async-storage": "2.2.0", "@react-native-async-storage/async-storage": "2.2.0",
"@react-native-community/netinfo": "11.4.1", "@react-native-community/netinfo": "12.0.1",
"@react-navigation/bottom-tabs": "^7.4.0",
"@react-navigation/elements": "^2.6.3",
"@react-navigation/native": "^7.1.8",
"@wuba/react-native-echarts": "^3.1.1", "@wuba/react-native-echarts": "^3.1.1",
"axios": "^1.13.2", "axios": "^1.13.2",
"babel-preset-expo": "~54.0.10", "babel-preset-expo": "~57.0.0",
"echarts": "^5.5.0", "echarts": "^5.5.0",
"expo": "~54.0.36", "expo": "~57.0.23",
"expo-build-properties": "~1.0.10", "expo-build-properties": "~57.0.20",
"expo-camera": "~17.0.10", "expo-camera": "~57.0.5",
"expo-constants": "~18.0.10", "expo-constants": "~57.0.18",
"expo-dev-client": "~6.0.20", "expo-dev-client": "~57.0.19",
"expo-document-picker": "~14.0.8", "expo-document-picker": "~57.0.2",
"expo-file-system": "~19.0.23", "expo-file-system": "~57.0.7",
"expo-font": "~14.0.12", "expo-font": "~57.0.4",
"expo-haptics": "~15.0.7", "expo-haptics": "~57.0.3",
"expo-image": "~3.0.10", "expo-image": "~57.0.5",
"expo-image-picker": "~17.0.11", "expo-image-picker": "~57.0.18",
"expo-linking": "~8.0.11", "expo-linking": "~57.0.10",
"expo-router": "~6.0.24", "expo-router": "~57.0.21",
"expo-secure-store": "~15.0.8", "expo-secure-store": "~57.0.4",
"expo-sharing": "~14.0.8", "expo-sharing": "~57.0.20",
"expo-splash-screen": "~31.0.11", "expo-splash-screen": "~57.0.9",
"expo-status-bar": "~3.0.8", "expo-status-bar": "~57.0.1",
"expo-symbols": "~1.0.7", "expo-symbols": "~57.0.3",
"expo-system-ui": "~6.0.8", "expo-system-ui": "~57.0.4",
"expo-web-browser": "~15.0.9", "expo-web-browser": "~57.0.3",
"lucide-react-native": "^0.563.0", "lucide-react-native": "^0.563.0",
"nativewind": "^4.2.1", "nativewind": "^4.2.1",
"prettier-plugin-tailwindcss": "^0.5.14", "prettier-plugin-tailwindcss": "^0.5.14",
"react": "19.1.0", "react": "19.2.3",
"react-dom": "19.1.0", "react-dom": "19.2.3",
"react-native": "0.81.5", "react-native": "0.86.3",
"react-native-gesture-handler": "~2.28.0", "react-native-gesture-handler": "~2.32.0",
"react-native-image-viewing": "^0.2.2", "react-native-image-viewing": "^0.2.2",
"react-native-keyboard-controller": "1.18.5", "react-native-keyboard-controller": "1.21.9",
"react-native-reanimated": "~4.1.1", "react-native-reanimated": "4.5.1",
"react-native-safe-area-context": "~5.6.0", "react-native-safe-area-context": "~5.7.0",
"react-native-screens": "~4.16.0", "react-native-screens": "~4.26.0",
"react-native-svg": "15.12.1", "react-native-svg": "15.15.4",
"react-native-ui-datepicker": "^3.1.2", "react-native-ui-datepicker": "^3.1.2",
"react-native-web": "~0.21.0", "react-native-web": "~0.21.0",
"react-native-worklets": "0.5.1", "react-native-worklets": "0.10.1",
"tailwindcss": "^3.4.18" "tailwindcss": "^3.4.18"
}, },
"devDependencies": { "devDependencies": {
"@types/react": "~19.1.0", "@types/react": "~19.2.14",
"eslint": "^9.25.0", "eslint": "^9.25.0",
"eslint-config-expo": "~10.0.0", "eslint-config-expo": "~57.0.2",
"typescript": "~5.9.2" "typescript": "~6.0.3"
}, },
"private": true "private": true
} }
+34
View File
@@ -0,0 +1,34 @@
const { withPodfile } = require('expo/config-plugins');
const MARKER = '# @generated withPodsDeploymentTarget';
// CocoaPods resource bundle targets (e.g. RNCAsyncStorage_resources, RNSVGFilters)
// keep the deployment target declared in their podspec, ignoring `platform :ios`.
// Xcode 27 rejects targets below iOS 15, so raise every pod target to the app's minimum.
const SNIPPET = `
${MARKER}
min_ios_target = podfile_properties['ios.deploymentTarget'] || '16.4'
installer.pods_project.targets.each do |target|
target.build_configurations.each do |build_config|
current = build_config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']
if current.nil? || Gem::Version.new(current) < Gem::Version.new(min_ios_target)
build_config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = min_ios_target
end
end
end
`;
module.exports = function withPodsDeploymentTarget(config) {
return withPodfile(config, (config) => {
const podfile = config.modResults;
if (podfile.contents.includes(MARKER)) {
return config;
}
const anchor = /post_install do \|installer\|\n/;
if (!anchor.test(podfile.contents)) {
throw new Error('withPodsDeploymentTarget: post_install block not found in Podfile');
}
podfile.contents = podfile.contents.replace(anchor, (match) => match + SNIPPET);
return config;
});
};