我正在使用Expo Router v3。版本 51,无论出于何种原因,我都会出现白屏

问题描述 投票:0回答:1

问题:

当我使用

npx expo start
运行我的 Expo 应用程序并在 Expo Go 中打开它时,一切都运行良好。但是,当我将应用程序推送到 TestFlight 时,我遇到了白屏。当我通过 Expo 开发者门户中的“预览”通道构建应用程序并通过 Expo Go 启动它时,会发生同样的问题,导致白屏。

此外,当我尝试在 Xcode 中运行该应用程序时,我收到与 Hermes 相关的错误。我相信我的配置文件设置正确,因为我成功地将应用程序推送到 App Store Connect(尽管出现白屏问题)。

几个月前,我在 TestFlight 上有该应用程序的工作版本,但我不确定现在可能发生了什么变化导致白屏。

我尝试过的:

  • npx expo-doctor
    未报告任何问题 — 一切正常。
  • EAS 构建过程中没有错误。
  • 我尝试过各种命令和构建,但我不记得我使用过的每一个命令和构建。我记得的包括:
    • 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 上的白屏)。

react-native expo testflight eas expo-router
1个回答
0
投票

白屏可能意味着实际应用程序中存在崩溃问题,而Expo Go中没有重现。

您可以尝试在模拟器中运行实际的应用程序构建来找出答案:

npx expo prebuild --clean
npx expo run:ios
© www.soinside.com 2019 - 2024. All rights reserved.