Flutter 在 Windows 上真机调试 iOS,Dart 断点与热重载实战
这篇带你在 Windows 上把一个 Flutter App 装到 iPhone 上调试,Dart 断点、热重载都能用,再接入相机和相册插件,最后打出可以上架的 ipa。适合在 Windows 上开发 Flutter 的开发者。你需要准备 Apple 开发者账号、一台 iPhone 和数据线,并且已经安装 KXBuild。
flutter build ios 为什么在 Windows 上用不了
Flutter 官方工具里 iOS 相关的命令只能在 macOS 上运行,在 Windows 上执行 flutter build ios 会提示只支持 macOS,flutter run 也列不出 iPhone。
用 KXBuild 之后,iOS 端的构建和运行交给 KXBuild,其他 flutter 命令照常使用。flutter create、flutter pub add、flutter test 这些不受影响,Android 端也照旧用 flutter run。
准备 Flutter 开发环境
按 Flutter 官网的说明安装 Flutter SDK,把 flutter 命令加入 PATH,新开一个终端能看到版本号即可。
1flutter --version
在 VS Code 扩展市场安装 Flutter 扩展,Dart 扩展会一起装上。Dart 断点和热重载靠 Dart 扩展,没装的话第一次调试时 KXBuild 也会提示一键安装。
新建工程
已有工程在 VS Code 中「文件 → 打开文件夹」打开 Flutter 工程根目录(pubspec.yaml 所在的目录),或者把工程目录拖进 VS Code 即可。没有现成工程的,可以用 Flutter 自己的命令新建。
1cd D:\work
2flutter create --org com.example myflutterapp
–org 决定 iOS 端的 Bundle ID,上面的命令生成 com.example.myflutterapp。改成你自己的域名反写,之后在 Apple 开发者后台注册 App ID 时用同一个。
也可以用 KXBuild 的模板新建,以下两种做法任选其一。
- VS Code 插件。命令面板运行 KXBuild: 新建项目,模板选「Flutter 应用」。
- 命令行。运行
kxbuild project create -t flutter_app -n myflutterapp -o D:\work。
体检
第一次打开工程必须先做这一步。 它会检查 Flutter 环境,并准备好 iOS 端的工程,没做的话编译会失败。以下两种做法任选其一。
- VS Code 插件。在 KXBuild 视图标题栏「···」中运行「体检并修复开发环境」。
- 命令行。运行下面的命令。
1kxbuild doctor D:\work\myflutterapp
刚 create 出来的工程没有需要 CocoaPods 的插件,体检完就可以直接调试。后面加了带原生代码的插件时,还要多做一步,见接入相机和相册插件。
连接 iPhone
真机调试需要签名。先在 Apple 开发者后台准备 Apple Development 证书和包含这台 iPhone 的 Development 描述文件,放进证书目录,做法见证书与签名。
用数据线连上 iPhone,按下面的顺序完成一次,以后插上就能用。
- KXBuild 视图的设备节点提示「点击配置」时点一下,安装 Apple 设备驱动,过程中要确认一次管理员权限。
- 手机解锁,在弹窗里点「信任此电脑」。
- 手机上打开「设置 → 隐私与安全性 → 开发者模式」,手机会重启一次。这个开关在手机连过电脑之后才会出现。
- 在 KXBuild 视图的「设备」节点下点一下这台 iPhone,选为当前设备。
更多情况见设备准备。
启动调试
在 lib\main.dart 里打一个断点,比如 _incrementCounter 方法里,然后按 F5。KXBuild 会构建、签名、安装、启动 App,先接上原生调试器,App 启动后自动接上 Dart 调试。调试工具栏会出现两个会话,一个是原生部分,一个是「Flutter (Dart)」。
在手机上点一下加号按钮,VS Code 就停在 Dart 断点上,变量、调用栈、监视都在标准的调试视图里。ios\Runner 下的 Swift 或 Objective-C 代码也可以同时打断点。

第一次调试某个 iOS 版本时会自动下载符号库,有几个 GB,大约十多分钟,只需要一次,进度显示在通知里。
热重载与热重启
Dart 调试会话接上之后,热重载和在 Android 上的用法一样。
- 改完 Dart 代码按 Ctrl+S 保存,自动热重载,页面状态保留。
- 调试工具栏上的闪电按钮也可以手动触发热重载。
- 改了 main() 或全局状态的初始化,热重载不生效时,用命令面板里 Dart 扩展提供的 Flutter: Hot Restart 做热重启。
写 MethodChannel 这类 Dart 和原生互相调用的代码时,可以在 Dart 一侧的 invokeMethod 和 ios\Runner\AppDelegate.swift 里的处理函数上同时打断点,一次运行就能看清参数从 Dart 传到 Swift、结果再传回来的全过程。App 的原生日志输出在「输出 → KXBuild Console」。
热重载只更新 Dart 代码。改了 ios\ 下的原生代码、Info.plist,或者加了新插件,要停止调试后重新按 F5 完整构建。调试工具栏上的「重启」不会重新编译。
接入相机和相册插件
camera、image_picker 这类插件带有 iOS 原生代码,接入时除了 Dart 代码,还要做三件事。下面以 image_picker 为例。
添加依赖并重新体检
1flutter pub add image_picker
添加完依赖后重新运行一次体检,让 iOS 端的工程认到新插件。
安装 pods
插件需要 CocoaPods 时,体检之后在 ios 目录安装依赖。体检不会替你执行这一步。
1cd ios
2pod install
之后构建用 ios\Runner.xcworkspace,不要再用 Runner.xcodeproj。CocoaPods 的更多用法见 CocoaPods。
在 Info.plist 里写权限描述
iOS 要求访问相机、相册、麦克风前在 Info.plist 里写明用途,缺了的话 App 一调用就闪退,审核也会被拒。按 image_picker 的官方说明,需要下面三项,camera 插件需要其中的相机和麦克风两项。
| 键 | 什么时候需要 |
|---|---|
| NSPhotoLibraryUsageDescription | 从相册选图 |
| NSCameraUsageDescription | 拍照或录像 |
| NSMicrophoneUsageDescription | 录制带声音的视频 |
在 VS Code 里双击 ios\Runner\Info.plist,KXBuild 的属性列表编辑器会以表格打开。在任意一行右键「添加行」,键名填上表中的名字,类型选 String,值写一句给用户看的说明,例如「用于拍摄头像」,Ctrl+S 保存。

三件事做完后停止调试,重新按 F5。第一次调用相机或相册时,手机会弹出权限请求,文字就是你刚才写的说明。
改 App 名称和图标
主屏幕上显示的名字是 ios\Runner\Info.plist 里的 CFBundleDisplayName,用属性列表编辑器直接改值即可。Bundle ID 要改的话,在 KXBuild 视图里右键 Runner 这个 target,选择「KXBuild: 编辑目标设置」,在 General 页的 Bundle Identifier 里改,详见工程设置编辑器。
iOS 图标在 ios\Runner\Assets.xcassets 的 AppIcon 里。在资源管理器中右键 Assets.xcassets,选择「KXBuild: 打开资源目录」,选中 AppIcon 后用「用一张 1024×1024 图生成全部尺寸…」选一张不小于 1024 的正方形 PNG,所有尺寸会一次生成。App Store 用的 1024 图不能带透明通道,编辑器会标出来,详见资源目录编辑器。
打包 Release ipa
改版本号
Flutter 工程的版本号在 pubspec.yaml 的 version 字段,例如 1.0.1+2,加号前是商店里显示的版本,加号后是构建号。每次上传 App Store Connect,构建号都要比上一次大。改完后重新运行一次体检,让 iOS 端用上新版本号。
用 Release 配置构建
证书目录里要有 Apple Distribution 证书和 App Store 类型的描述文件。以下两种做法任选其一。
- VS Code 插件。在 KXBuild 视图的「构建配置」节点切到 Release,命令面板运行 KXBuild: 构建。
- 命令行。在工程根目录运行下面的命令。
1kxbuild build .\ios\Runner.xcworkspace -c Release
构建完成后 ios\build\Runner.ipa 就是可以上传的包,Release 包里的 Dart 代码是预编译的,从主屏幕点开能正常运行。
上传与提审
App Store Connect 里先新建好 App,Bundle ID 和工程里的一致。在 Windows 上用 Appuploader 登录开发者账号上传 ipa,处理完成后在 TestFlight 里装到手机上验证,再提交审核。完整步骤见发布与上架。
常见问题
Dart 断点不停,只有原生断点能用
没有安装 Dart 扩展。在扩展市场安装 Dart 扩展(Dart-Code.dart-code)后,重新按 F5。
从主屏幕点开 Debug 包,App 闪退或白屏
这是 Flutter 在 iOS 上的已知限制。Debug 模式的 Flutter App 只能由调试工具启动,不能在没有调试器的情况下从主屏幕打开。要装给别人用,打 Release 包。
编译时报找不到某个插件的头文件或模块
用到了需要 CocoaPods 的插件,但没有 pod install,或者构建的是 Runner.xcodeproj。在 ios 目录运行 pod install,之后构建 Runner.xcworkspace。
编译在 Run Script 阶段报错
Flutter 环境没准备好,常见于刚换了 Flutter 版本或刚拉下工程。带上工程路径重新运行体检。
断点停在汇编上,或者位置对不上
用了 Release 配置调试,优化后断点位置会跳。调试时在「构建配置」节点切回 Debug。符号库还没下载完时也会这样,等通知里的下载完成即可。
其他错误见排错与 FAQ。