怎么把 Python 写的 Flet 应用打包成 iOS App 并上架 App Store?

用 Python 写手机应用这件事,Flet 算是目前体验最顺的一条路------底层是 Flutter,你只写 Python。但发 iOS 版的时候有个绕不开的前提:flet build ipa 底层还是走 Flutter 那套,最终要调 Xcode,所以必须在 macOS 上构建,而且要装 Xcode 15 或更新的版本。Windows 上跑这条命令是不行的。

我的分工是:Python 代码在 Windows 上写,出包丢给 macOS 机器;证书、描述文件、IPA 上传这些用开心上架(AppUploader)在 Windows 上处理。下面把签名那部分怎么配讲清楚,这是 Flet 出 iOS 包时最容易卡住的地方。

先说结论:哪一步真绕不开 Mac

环节 我实际怎么做的
注册 Bundle ID、签发证书、生成描述文件 Windows 上做完
flet build ipa 要 macOS + Xcode 15 或更新版本
提交 App Store Windows 上传
装到 iPhone 测试 扫码注册 UDID,再扫码装

说明一下:我用的签证书工具本身在 macOS 上也能用(网页版不挑系统,桌面客户端有 macOS 版)。表里"不需要 Mac"是指这一步不再需要 Xcode、钥匙串访问或 Transporter。

第一步:定好 Bundle ID

Flet 的 iOS 包标识可以在 pyproject.toml 里配,也可以用 flet build ipa 的命令行参数传。定成反向域名,比如 com.yourcompany.appname

后面注册的 Bundle ID 和描述文件绑定的 App ID 都要和它完全一致。

第二步:在 Windows 上签出证书和描述文件

注册 Bundle ID :开心上架的「Bundle ID」页面点「新建 Bundle ID」,Identifier 填上一步那个值。创建后改不了 。用到推送、相册这些能力的,在这个 Bundle ID 的「权限」页面勾上再保存。

签发证书 :「证书」页面点「新建证书」,上架一定要选发布签名证书 。这点值得强调------Flet 的官方文档专门提醒过,上架要用 distribution 证书签,用开发证书或者 ad hoc 签出来的包传上去会被判签名无效。绑定上面的 Bundle ID,填名称邮箱,设一个 .p12 保护密码,服务器不保存它,忘了只能吊销重签。

勾上「使用开心上架服务同步证书」的话,构建机上能直接下载同一张证书,不用拿 U 盘拷。

生成描述文件 :「描述文件」页面点「新建描述文件」,上架选 App Store 类型,内测选 Ad Hoc 并勾上测试设备,关联上面的 Bundle ID 和证书,提交后下载 .mobileprovision

第三步:在 macOS 构建机上导入

bash 复制代码
security import dist.p12 -k ~/Library/Keychains/login.keychain-db -P "你的p12密码" -T /usr/bin/codesign

mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp AppStore.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/

第四步:配签名参数并构建

Flet 的签名配置有两种写法。一种写在 pyproject.toml 里:

toml 复制代码
[tool.flet.ios]
team_id = "你的TeamID"
signing_certificate = "Apple Distribution: Your Company (TEAMID)"
provisioning_profile = "你的描述文件名称"

另一种直接作为参数传给命令:

bash 复制代码
flet build ipa \
  --team <你的TeamID> \
  --ios-signing-certificate "Apple Distribution: Your Company (TEAMID)" \
  --ios-provisioning-profile "你的描述文件名称"

具体参数名在不同 Flet 版本里有过调整,以你装的那个版本 flet build ipa --help 输出的为准。

几个值从哪来:

  • Team ID 就是开发者账号那串 10 位字符,在开心上架的账号概览里能直接看到;
  • signing certificate 填证书的通用名称,也就是钥匙串里显示的那一整串;
  • provisioning profile 填描述文件的名称------你在开心上架创建时填的那个名字,不是文件名也不是 UUID。

Flet 社区里报过一批上传时报签名无效的问题,大部分最后查出来是这三个值有一个对不上,或者用错了证书类型。构建完先别急着传,下一步会讲怎么先自查。

第五步:把 IPA 传上去

拿到 IPA 之后我不直接传,先在开心上架的「文件&提交」页面把包打开看一眼------Bundle ID 对不对、用的是不是 App Store 类型的描述文件、证书是不是发布类型、有没有过期。上面说的那类签名问题,在这一步基本就能看出来,比传上去等 Apple 退回来快多了。

确认没问题再点「提交 App Store」,日志实时滚。

命令行版本,Runner 是 Windows 或 Linux 也能跑:

bash 复制代码
appuploader-cli upload -f build/ipa/app.ipa -u dev@example.com -p abcd-efgh-ijkl-mnop

-p 是 Apple 生成的 App 专用密码(xxxx-xxxx-xxxx-xxxx),不是 Apple ID 登录密码。也可以用 API 密钥:

bash 复制代码
appuploader-cli upload -f build/ipa/app.ipa --api-key <KeyID> --api-issuer <IssuerID> --private-key Auth_Key.p8

密钥方式只收 .ipa,且 App 要先在 App Store Connect 里建好。

第六步:发内测包

「设备」页面点「注册设备」,二维码发出去让人扫上报 UDID(一年 100 台,免费账号 3 台)。回描述文件那边点「重建」,生成一份包含这些设备的 Ad Hoc 描述文件。

把签名配置里的描述文件换成新的重新构建,然后在「文件&提交」页面生成二维码让人扫码装。

写在最后

Flet 让 Python 开发者不用学 Dart 也能出移动端应用,代价是 iOS 那次构建得借 macOS。但真正折腾人的从来不是那条命令,而是签名配置里那三个值------把它们的来源搞清楚,后面就是重复劳动了。

相关推荐
Geek_Vison2 小时前
小程序容器如何抹平系统差异,让一个小程序运行在 iOS、安卓、鸿蒙和电脑端
小程序·uni-app·harmonyos·mpaas
邪修king3 小时前
Re:Linux系统篇(二十六):文件系统(二):Ext 文件系统底层详解:从 inode、块组到软硬链接,结合 Windows 讲透文件管理本质
android·java·linux
PedroQue993 小时前
0.5.0重磅发布:动画插件+H5体验全面优化
前端·uni-app
李游Leo3 小时前
HarmonyOS 7 实战开发 04:适配手机、折叠屏与大屏布局
ios·harmonyos
又见情义3 小时前
RK3568 Android 13 版本号管理实战:基于 ROCKCHIP_BUILD_NUMBER 的定制化方案
android
终端安全笔记3 小时前
iOS 27 强制 TLS 1.2:租赁设备的注册链路会在哪一环断
android·网络·安全·ios·智能手机
mmsx4 小时前
MapLibre 实战 11|用户说"我的地块丢了":一个 sealed class 图层模型,和四个让我重构三版的坑
android·前端·开源
黑科技iOS上架4 小时前
iOS深度混淆flutter应用的最佳实践
flutter·ios·混淆·审核·深度混淆
Anthony_2315 小时前
Nginx基础
服务器·nginx·http·https·edge浏览器·web