当我使用
npx expo start
运行我的 Expo 应用程序并在 Expo Go 中打开它时,一切都运行良好。但是,当我将应用程序推送到 TestFlight 时,我遇到了白屏。当我通过 Expo 开发者门户中的“预览”通道构建应用程序并通过 Expo Go 启动它时,会发生同样的问题,导致白屏。
此外,当我尝试在 Xcode 中运行该应用程序时,我收到与 Hermes 相关的错误。我相信我的配置文件设置正确,因为我成功地将应用程序推送到 App Store Connect(尽管出现白屏问题)。
几个月前,我在 TestFlight 上有该应用程序的工作版本,但我不确定现在可能发生了什么变化导致白屏。
npx expo-doctor
未报告任何问题 — 一切正常。eas build -p ios --profile preview
eas build -p ios --profile production
(测试生产版本)我现在在这里提问,希望得到一些解决此问题的指导。我只需要一种方法来记录在 Expo Go 之外的物理设备或模拟器上运行应用程序时发生的情况。
如果您需要其他信息或特定诊断,请告诉我,我将使用必要的详细信息或命令更新问题。
这是我的
eas.json
文件:
{
"cli": {
"version": ">= 12.5.2",
"appVersionSource": "remote"
},
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"env": {
"APP_ENV": "development"
}
},
"preview": {
"channel": "preview",
"distribution": "internal",
"autoIncrement": true,
"env": {
"APP_ENV": "production"
}
},
"staging": {
"channel": "staging",
"distribution": "internal",
"ios": {
"credentialsSource": "remote"
},
"autoIncrement": true,
"env": {
"APP_ENV": "staging"
}
},
"production": {
"channel": "production",
"distribution": "store",
"autoIncrement": true,
"ios": {
"credentialsSource": "remote"
},
"env": {
"APP_ENV": "production"
}
}
},
"submit": {
"staging": {
"ios": {
"appleId": "***",
"ascAppId": "***"
}
},
"production": {
"ios": {
"appleId": "***",
"ascAppId": "***"
}
}
}
}
这是我的package.json(仅相关部分):
{
"name": "app-name",
"main": "expo-router/entry",
"version": "1.0.1",
"scripts": {
"start": "expo start",
"start:dev-client": "npx expo start --dev-client",
"run:ios": "expo run:ios",
"run:android": "expo run:android",
"run:web": "expo start --web",
"install-on:ios": "npx expo start --ios",
"install-on:android": "npx expo start --android"
},
"dependencies": {
"expo": "~51.0.38",
"expo-av": "~14.0.7",
"expo-build-properties": "~0.12.5",
"expo-checkbox": "~3.0.0",
"expo-constants": "~16.0.2",
"expo-dev-client": "~4.0.28",
"expo-device": "~6.0.2",
"expo-font": "~12.0.9",
"expo-image": "~1.13.0",
"expo-linear-gradient": "~13.0.2",
"expo-linking": "~6.3.1",
"expo-router": "~3.5.23",
"expo-screen-orientation": "~7.0.5",
"expo-secure-store": "~13.0.2",
"expo-splash-screen": "~0.27.5",
"expo-status-bar": "~1.12.1",
"expo-system-ui": "~3.0.7",
"expo-updates": "~0.25.25",
"expo-web-browser": "~13.0.3",
"react": "18.2.0",
"react-native": "0.74.5",
"react-native-gesture-handler": "~2.16.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "3.31.1",
"react-native-svg": "15.2.0"
},
"private": true
}
这是我的app.json(仅相关部分):
{
"orientation": "portrait",
"description": "description",
"platforms": [
"ios",
"android",
"web"
],
"web": {
"bundler": "metro",
"output": "static",
"backgroundColor": "#121212",
"splash": {
"image": "./assets/images/storyboard/production-app-splash.png",
"backgroundColor": "#121212",
"resizeMode": "contain"
},
"shortName": "Placeholder",
"favicon": "./assets/images/storyboard/production-favicon.png",
"themeColor": "#121212"
},
"assetBundlePatterns": [
"**/*",
"assets/**/*"
],
"name": "Project Name",
"owner": "placeholder",
"slug": "placeholder",
"android": {
"splash": {
"backgroundColor": "#121212",
"resizeMode": "contain",
"image": "./assets/images/storyboard/production-app-splash.png"
},
"adaptiveIcon": {
"foregroundImage": "./assets/images/storyboard/production-app-adaptive-icon.png",
"backgroundColor": "#000000"
},
"package": "com.placeholder.app_production",
"icon": "./assets/images/storyboard/production-app-icon.png",
"backgroundColor": "#121212",
"versionCode": 1
},
"ios": {
"usesIcloudStorage": false,
"usesAppleSignIn": false,
"accessesContactNotes": false,
"infoPlist": {
"CFBundleAllowMixedLocalizations": true,
"CFBundleSignature": "placeholder",
"CFBundleIdentifier": "com.placeholder.app-production",
"NSAppTransportSecurity": {
"NSExceptionDomains": {}
}
},
"backgroundColor": "#121212"
},
"plugins": [
"@logrocket/react-native",
"expo-font",
"expo-secure-store",
"expo-router",
[
"expo-screen-orientation",
{
"initialOrientation": "PORTRAIT"
}
],
[
"expo-dev-launcher",
{
"launchModeExperimental": "most-recent"
}
]
],
"extra": {
"APP_VARIANT": "production",
"eas": {
"projectId": "placeholder"
},
"env": {}
},
"scheme": "production",
"icon": "./assets/images/storyboard/production-app-icon.png",
"version": "1.0.3"
}
这是我的 app.config.ts:
import { envVariables } from "./assets/created-env-variables";
import { ExpoConfig } from "expo/config";
export const isEmpty = (value: unknown) =>
value === undefined ||
value === null ||
(typeof value === "object" && Object.keys(value).length === 0) ||
(typeof value === "string" && value.trim().length === 0);
const appConfig = ({ config }): ExpoConfig => {
let NSAppTransportSecurity = {
NSAllowsArbitraryLoads: true,
NSExceptionDomains: {
"placeholder.com": {
NSExceptionAllowsInsecureHTTPLoads: true,
},
"placeholder.com": {
NSExceptionAllowsInsecureHTTPLoads: true,
},
},
};
let updates = {};
if (envVariables.environment === "development" || envVariables.environment === "local") {
NSAppTransportSecurity.NSExceptionDomains["placeholder.com"] = {
NSExceptionAllowsInsecureHTTPLoads: true,
};
} else {
updates = {
url: "https://u.expo.dev/placeholder",
};
}
const iosConfig = config.ios || {};
const getBundleIdentifier = (envType) => {
switch(envType){
case "production": {
return "com.placeholder.app-production";
}
case "staging": {
return "com.placeholder.app-staging";
}
case "development": {
return "com.placeholder.app-development";
}
case "local": {
return "com.placeholder.app-local";
}
default: {
return "com.placeholder.app-production";
}
}
};
const supportsTablet = (envType) => {
switch(envType){
case "production": {
return false;
}
case "staging": {
return true;
}
case "development": {
return true;
}
case "local": {
return true;
}
default: {
return false;
}
}
};
let modifiedConfig: ExpoConfig = {
...config,
name: config.name || "app",
slug: config.slug || "app",
owner: "placeholder",
extra: {
"eas": {
projectId: "placeholder",
},
...config.extra,
env: {
...envVariables
}
},
ios: {
...iosConfig,
bundleIdentifier: getBundleIdentifier(process.env.APP_ENV),
supportsTablet: supportsTablet(process.env.APP_ENV),
infoPlist: {
...iosConfig.infoPlist,
NSAppTransportSecurity,
NSFaceIDUsageDescription: "Will be used for authentication",
NSMicrophoneUsageDescription: "Used for expo device package and Siri to play TV shows",
}
},
plugins: [
"@logrocket/react-native",
"expo-font",
"expo-secure-store",
"expo-router",
["expo-screen-orientation", { initialOrientation: "PORTRAIT" }],
"expo-asset",
[
"expo-build-properties",
{
ios: {
useFrameworks: "static",
},
android: {
minSdkVersion: 21,
},
}
]
]
};
if (!isEmpty(updates)) {
modifiedConfig.updates = updates;
}
const runtimeVersion = process.env.EXPO_RUNTIME_VERSION || "1.0.0";
modifiedConfig.runtimeVersion = runtimeVersion;
return modifiedConfig;
};
export default appConfig;
如何在模拟器或物理设备(Expo Go 之外)上运行构建来捕获日志并识别导致白屏的问题?
解决此问题的最佳步骤是什么?
使用 npx expo start 运行时该应用程序工作正常,但在使用 EAS 构建或在 Xcode 中本地运行时遇到问题(Xcode 中的 Hermes 错误和 TestFlight 上的白屏)。
白屏可能意味着实际应用程序中存在崩溃问题,而Expo Go中没有重现。
您可以尝试在模拟器中运行实际的应用程序构建来找出答案:
npx expo prebuild --clean
npx expo run:ios