如果你跟我一样用 React Native 配合 Expo 做过 iOS 应用,应该对这一幕不陌生:模拟器里跑得行云流水,功能、动画、接口全部正常,结果一换真机,扫码后要么白屏,要么一直转圈,要么死活连不上 Metro。我第一次接触 Expo 项目时,差点被这套 iOS 特有的链路劝退——后来才发现,问题往往不在业务代码,而在几个非常具体的原生环节上。
这篇文章不是什么入门教程,而是我在 React Native + Expo 这条路上实打实攒下来的 iOS 开发经验。内容会覆盖环境版本、调试链路、真机网络、白屏问题、交互细节、上架签名和合规弹窗这些环节。适合正在开发 iOS 端、准备做真机调试或即将提审的朋友参考,尤其适合那些“模拟器正常但真机出问题”的典型场景。
1. Xcode版本、Node与Expo SDK之间的“三角关系”
很多项目的坑,其实在写第一行业务代码之前就埋下了。Expo 项目看起来好像只是依赖 Node,但当你要跑 iOS 时,背后还拖着 Xcode、CocoaPods、React Native 版本和原生编译链。这四者的版本一旦不匹配,报错会千奇百怪。
1.1 先确认版本组合,再新建项目
如果你刚开始接触 Expo,建议直接用官方脚手架新建项目,不要自己手工折腾版本:
bash复制npx create-expo-app@latest MyApp
cd MyApp
npx expo start
这套命令会帮你选好当前最新的稳定版 Expo SDK,而 SDK 又锁定了对应的 React Native 版本。Expo SDK 的版本迭代是整体推进的,例如 SDK 51 对应 React Native 0.74,SDK 52 切到 0.76,SDK 53 则对应 0.79。不同 SDK 对 Xcode 的最低版本和 iOS 部署目标也有要求,越新的 SDK 通常要求越高,比如部分新版本只支持 Xcode 15 以上。
这里的教训是:不要用 npm install react-native@latest 这种思路去“升级”Expo 项目里的 React Native 版本,想换版本就直接升级 Expo SDK。手工改 React Native 版本后,很容易出现原生模块编译不过、Xcode 里一堆红字的情况。
安装依赖时也要养成一个习惯:
bash复制npx expo install 包名
而不是随手 npm install 包名。expo install 会去匹配当前 SDK 对应的原生模块版本,很多第三方库的 iOS 原生代码是跟着 Expo SDK 走的,版本不匹配在 JS 层不一定看得到,一旦进入 Xcode 编译阶段就会原形毕露。
已经掉进版本坑的项目,可以试试:
bash复制npx expo install --fix
这个命令会尽量把所有依赖修复成与当前 SDK 兼容的版本,但前提是你别乱改原生目录。
1.2 模拟器、真机和开发者模式的环境准备
macOS 端装好 Xcode 后,我第一次跑模拟器就遇到“Could not locate device support files”的错误,原因是 Xcode 版本太老,连新 iOS 系统的 Device Support 文件都没有。这种问题基本只有升 Xcode 一条路。
在真正开始 iOS 开发前,建议先确认这几点:
- Xcode 已启动过一次,且接受过许可协议。命令行环境里可以执行
sudo xcodebuild -license accept避免后续权限报错。 - Xcode 命令行工具指向正确,执行
xcode-select -p,如果路径不对,用sudo xcode-select -s /Applications/Xcode.app切换。 - Node 不要用系统自带的旧版本,推荐通过 nvm 管理,遇到 CocoaPods 或 RN 编译奇怪的报错时,换 Node 版本也是一种排查手段。
如果你要在 iPhone 真机上跑,请务必记得开启“开发者模式”。iOS 16 之后,新装开发包 App 的真机,都需要在“设置 -> 隐私与安全性 -> 开发者模式”里手动开启,否则手机连上 Xcode / Expo 后根本不会帮你安装应用,也不会弹出信任弹窗。这一步很容易被忽略,因为模拟器根本不需要开开发者模式。
另外要注意免费 Apple ID 签名的问题。免费账号确实能在真机上调试,但证书有效期只有 7 天,App 过几天就会打不开,需要重新连上 Xcode 或跑一次 expo run:ios 重装。如果你只是短期验证,免费账号完全够用;如果项目周期较长,还是尽早注册 Apple Developer Program,不然每 7 天重新签一次会非常消磨耐心。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 不要一直待在Expo Go的舒适区里
Expo Go 是测试 Expo 项目最方便的工具,扫码即用,不需要经历 Xcode 编译,非常适合验证 UI 和纯 JS 功能。但很多人在项目中期开始掉坑,是因为一直留在 Expo Go 里不愿意切出来。
2.1 Expo Go和development build的本质差异
先理清概念。Expo Go 是一个通用壳 App,它内置了一堆常用的 Expo 原生模块。你用 expo start 启动 Metro 后,Expo Go 会去加载你项目里的 JS bundle。这种模式好处是省去原生编译,坏处是壳是固定的,你只能使用内置的原生能力。
一旦你的项目接入了自定义原生代码,或者用了某些需要修改 Info.plist、引入原生 SDK 的第三方库,Expo Go
