打包 iOS 应用程序
介绍
Flet CLI 提供了flet build ipa
命令,该命令允许将 Flet 应用程序打包成 iOS 归档包和 IPA 以供分发。
该命令只能在 macOS 上运行。
先决条件
Rosetta 2
在苹果芯片上,Flutter 需要Rosetta 2。
sudo softwareupdate --install-rosetta --agree-to-license
Xcode
Xcode15 或更高版本,用于编译原生 Swift 或 Objective-C 代码。
CocoaPods
CocoaPods1.16,用于编译和启用 Flutter 插件。
iOS 二进制 Python 包的轮子
二进制 Python 包(与仅用 Python 编写的“纯”Python 包相对)是部分用 C、Rust 或其他语言编写并生成原生代码 的包。示例包有numpy
、cryptography
或pydantic-core
。
确保在你的 Flet 应用中使用的所有非纯(二进制)包都有iOS 的预构建轮子。
flet build ipa
为测试和分发(仅适用于 macOS 主机)构建 iOS 应用程序归档文件(.ipa)。
要生成用于在设备上测试或上传到 App Store Connect 进行分发的.ipa 文件,你需要:
- 具有访问 App Store Connect 权限的Apple Developer Program订阅。
- 应用程序标识符。
- 签名证书。
- 配置文件。
应用程序标识符
应用程序标识符(App ID)是一个唯一的字符串,用于在苹果生态系统中标识你的应用程序。它是签署和分发 iOS 应用程序所必需的,并用于各种服务,如推送通知、应用程序组、iCloud 和应用内购买。
App ID 由两部分组成:
- 团队 ID——苹果分配给你的开发者账户的一个唯一的 10 字符字符串。
- 捆绑包 ID——你的应用程序的反向域名风格标识符(例如,
com.example.myapp
)。
完整 App ID 的示例:
TeamID.com.example.myapp
创建新的 App ID
- 访问Apple Developer Portal。
- 使用你的Apple Developer Account登录。
- 点击“+”按钮添加新的标识符。
- 选择“App IDs”并点击“继续”。
- 输入描述——这仅用于参考(例如,“MyApp Identifier”)。
- 选择 App ID 类型:
- 对于标准的 iOS/macOS 应用程序,选择“App”。
- 如果你需要用于 Apple Pay 或 Passbook 等服务的标识符,请选择适当的选项。
- 捆绑包 ID——选择:
- 显式捆绑包 ID(
com.example.myapp
)——推荐用于大多数应用程序。 - 通配符捆绑包 ID(
com.example.*
)——允许多个应用程序使用相同的标识符(很少使用)。
- 显式捆绑包 ID(
- 启用应用程序服务——检查你的应用程序需要的任何服务的复选框(例如,推送通知、使用 Apple 登录等)。
- 点击“继续”并“注册”。
现在你有了必须用于签署 iOS 捆绑包的捆绑包 ID和团队 ID。下一步是创建证书和配置文件以安装和分发你的应用程序。
签名证书
生成证书签名请求(CSR)
在创建开发或分发证书之前,你需要一个CSR(Certificate Signing Request)。
- 在你的 Mac 上打开钥匙串访问(
Command ⌘ + Space
,然后搜索“钥匙串访问”)。 - 在顶部菜单中,转到钥匙串访问→证书助理→从证书颁发机构请求证书…
- 填写:
- 用户电子邮件地址:你的 Apple Developer 电子邮件。
- 通用名称:一个描述性名称(例如,“My App Distribution”)。
- CA 电子邮件地址:留空。
- 请求用途:选择“保存到磁盘”。
- 点击“继续”,选择一个位置保存
.certSigningRequest
文件,然后点击“保存”。
在 Apple Developer Portal 中创建证书
- 转到Apple Developer Certificates Page。
- 点击“+”按钮创建新证书。
- 选择“Apple Distribution”(用于 App Store 和 Ad Hoc)或“Apple Development”(用于开发)并点击“继续”。
- 上传你之前创建的CSR 文件并点击“继续”。
- 苹果将生成证书。点击“下载”以获取
.cer
文件。 - 双击下载的
.cer
文件将其安装到钥匙串访问中。 - 打开钥匙串访问应用程序,并确保证书安装在“login”钥匙串下。开发证书的名称通常以“Apple development:”开头,分发证书的名称以“Apple distribution:”开头。
配置文件
配置文件(Provisioning Profile)是一个文件,允许 iOS 应用程序在物理设备上运行,并通过 App Store 或内部进行分发。它链接你的App ID、开发者/分发证书和注册设备。
有不同类型的配置文件:
- 开发配置文件——用于在物理设备上进行测试。
- Ad Hoc 配置文件——用于在 App Store 之外分发给特定设备。
- App Store 配置文件——用于将应用程序提交到 App Store。
- 企业配置文件——用于在组织内部进行分发。
创建新的配置文件
步骤 1:转到 Apple Developer Portal
- 访问Apple Developer Portal。
- 使用你的Apple Developer Account登录。
步骤 2:创建新的配置文件
- 点击“+”按钮添加新的配置文件。
- 选择配置文件类型:
- 选择“iOS App Development”用于在设备上进行测试。
- 选择“Ad Hoc”用于分发给特定设备。
- 选择“App Store”用于将应用程序提交到 App Store。
- 选择“内部”(仅企业账户)用于内部分发。
- 点击“继续”。
步骤 3:选择 App ID
- 选择与你的应用程序匹配的App ID。
- 点击“继续”。
步骤 4:选择分发证书
- 选择iOS 分发证书或开发证书(取决于配置文件类型)。
- 点击“继续”。
步骤 5:选择注册设备(对于开发和 Ad Hoc)
- 如果你选择了“开发”或“Ad Hoc”,选择可以运行应用程序的设备。
- 点击“继续”。
步骤 6:命名并生成配置文件
- 输入配置文件名称(例如,“MyApp Development Profile”)。
- 点击“生成”。
- 点击“下载”以获取
.mobileprovision
文件。
安装配置文件
配置文件存储在~/Library/MobileDevice/Provisioning Profiles
目录中。
要安装下载的配置文件,只需将其复制到~/Library/MobileDevice/Provisioning\ Profiles
目录中,并使用新的{UUID}.mobileprovision
名称。
运行以下命令以获取配置文件 UUID:
profile_uuid=$(security cms -D -i ~/Downloads/{profile-name}.mobileprovision | xmllint --xpath "string(//key[.='UUID']/following-sibling::string[1])" -)
echo $profile_uuid
运行此命令将配置文件复制到~/Library/MobileDevice/Provisioning Profiles
中,并使用新名称{UUID}.mobileprovision
:
cp ~/Downloads/{profile-name}.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/${profile_uuid}.mobileprovision
如果复制的配置文件从~/Library/MobileDevice/Provisioning Profiles
目录中消失,请确保 Xcode 进程不在后台运行。
最后,你可以使用此命令列出所有已安装的配置文件及其名称和 UUID:
for profile in ~/Library/MobileDevice/Provisioning\ Profiles/*.mobileprovision; do security cms -D -i "$profile" | grep -E -A1 '<key>(Name|UUID)</key>' | sed -n 's/.*<string>\(.*\)<\/string>/\1/p' | paste -d ' | ' - -; done
配置构建
你可以通过flet build
命令行传递.ipa 构建选项,也可以在pyproject.toml
中进行配置。
命令行
要成功生成“可运行”的 IPA,你应该为以下参数提供正确的值:
--ios-export-method
——指定在导出.ipa 文件时应如何打包应用程序。默认是debugging
。可以是以下之一:debugging
(或已弃用的development
)——用于在开发设备上进行调试和测试。release-testing
(或已弃用的ad-hoc
)——用于在 App Store 之外分发给特定的已注册设备。app-store-connect
(或已弃用的app-store
)——用于将应用程序提交到 App Store。enterprise
——用于在组织内部进行分发(需要企业账户)。
--ios-provisioning-profile
——用于签署和导出 iOS 应用程序的配置文件名称或 UUID。--ios-signing-certificate
——用于签署 iOS 应用程序捆绑包的证书名称、SHA-1 哈希或自动选择器。自动选择器允许 Xcode 选择特定类型的最新安装证书。可用的自动选择器有“Apple Development”、“Apple Distribution”、“Developer ID Application”、“iOS Developer”、“iOS Distribution”、“Mac App Distribution”和“Mac Developer”。--ios-team-id
——用于导出 iOS 应用程序的开发者团队 ID。--bundle-id
——应用程序的捆绑包 ID,例如“com.mycompany.app-name”——用作 iOS、Android、macOS 和 Linux 的捆绑包 ID。--org
——以反向域名表示法表示的组织名称,例如com.mycompany
(默认为com.flet
)。该值与--project
组合使用,并用作 iOS 和 Android 的捆绑包 ID。--project
——以 C 风格标识符格式(小写字母数字和下划线)表示的项目名称,用于构建捆绑包 ID 并用作捆绑包可执行文件的名称。默认情况下,它是 Flet 应用程序目录的名称。
要为在你的开发设备上进行测试构建.ipa,你只需要提供--ios-provisioning-profile
选项。flet build
将假定debugging
作为导出方法,并自动选择你的钥匙串中最新的“Apple Development”证书。不需要团队 ID。
你可以指定--bundle-id
、--org
或两者都指定。
- 如果仅提供了
--bundle-id
而没有提供“--org”,则组织名称将从捆绑包 ID 中提取最后一个点之前的部分。 - 如果仅指定了
--org
而没有指定“--bundle-id”,则捆绑包 ID 将生成为{org}.{project_name}
。
pyproject.toml
你也可以在pyproject.toml
中配置包导出和签名设置。
项目名称和组织:
[project]
name = "my-app"
[tool.flet]
org = "com.mycompany"
或捆绑包 ID:
[tool.flet]
bundle_id = "com.mycompany.example-app"
org
和bundle_id
都可以是特定于平台的,例如:
[tool.flet.ios]
bundle_id = "com.mycompany.example-app-ios"
[tool.flet.android]
bundle_id = "com.mycompany.example-app-android"
要配置将全局应用于所有导出方法的 iOS 签名设置:
[tool.flet.ios]
provisioning_profile = "release-testing com.mycompany.example-app"
signing_certificate = "Apple Distribution"
team_id = "ABCDEFE234"
export_options = { uploadSymbols = false }
要配置每个导出方法的签名 设置:
[tool.flet.ios.export_methods."debugging"]
provisioning_profile = "debugging com.mycompany.example-app"
signing_certificate = "Apple Development"
[tool.flet.ios.export_methods."release-testing"]
provisioning_profile = "release-testing com.mycompany.example-app"
team_id = "ABCDEFE234"
signing_certificate = "Apple Distribution"
export_options = { uploadSymbols = false }
[tool.flet.ios.export_methods."app-store-connect"]
provisioning_profile = "app-store-connect com.mycompany.example-app"
team_id = "ABCDEFE234"
signing_certificate = "Apple Distribution"
export_options = { uploadSymbols = true }
使用上述设置,你可以仅提供--ios-export-method
来运行flet build
命令,例如:
flet build ipa --ios-export-method release-testing
将应用程序部署到苹果设备进行测试
适用于 macOS 的 Apple Configurator 允许你在不使用 App Store 的情况下在 iOS 设备上安装.ipa 文件。
按照以下步骤将.ipa 文件部署到你的设备:
步骤 1:安装 Apple Configurator
- 从 App Store 安装Apple Configurator。
步骤 2:连接 iOS 设备
- 使用 USB 电缆将iPhone或iPad连接到你的 Mac。
- 解锁设备,如果提示,请信任计算机。
步骤 3:打开 Apple Configurator
- 在你的 Mac 上启动Apple Configurator。
- 连接的设备应出现在主窗口中。
步骤 4:添加.ipa 文件
- 将.ipa 文件拖放到 Apple Configurator 中的连接设备上。
- 或者,点击“添加→应用程序”,然后从你的 Mac 中选择.ipa 文件。
步骤 5:安装应用程序
- 点击“准备”或“安装”开始部署。
- Apple Configurator 将在设备上安装应用程序。
步骤 6:信任开发者配置文件(对于 Ad Hoc 或企业应用程序)
如果.ipa 是从Ad Hoc 或企业配置文件安装的,你可能需要手动信任开发者:
- 在 iOS 设备上,转到设置→通用→VPN 与设备管理。
- 在“开发者应用程序”下,选择你的开发者配置文件。
- 点击“信任”并确认。
将应用程序上传到 App Store Connect 进行分发
Transporter是一个 macOS 应用程序,允许你将.ipa 文件上传到App Store Connect进行分发。
步骤 1:安装 Transporter
- 从 App Store 安装Transporter。
步骤 2:准备.ipa 文件
- 确保你的.ipa 文件是使用app-store-connect或release-testing导出方法构建的。
步骤 3:打开 Transporter 并登录
- 在你的 Mac 上启动Transporter。
- 使用你的Apple Developer Account(与用于 App Store Connect 的相同)登录。
步骤 4:上传.ipa 文件
- 将.ipa 文件拖放到 Transporter 窗口中。
- 或者,点击“添加应用程序”,然后从你的 Mac 中选择.ipa 文件。
- 点击“交付”旁边的“...”按钮并选择“验证”。
- 等待 Transporter 验证文件。
- 点击“交付”开始上传。
步骤 5:检查上传状态
- 上传完成后,Transporter 将显示一条成功消息。
- 如果有错误,请查看错误并纠正任何问题,然后重试上传。
步骤 6:在 App Store Connect 中确认
- 转到App Store Connect。
- 导航到应用程序→你的应用程序→TestFlight 或 App Store 版本。
- 上传的构建版本应出现在“处理中”(这可能需要几分钟到一小时)。
- 处理完成后,你可以提交应用程序进行审核。
权限
设置写入Info.plist
文件的 iOS 权限:
flet build --info-plist permission_1=True|False|description permission_2=True|False|description ...
例如:
flet build --info-plist NSLocationWhenInUseUsageDescription="此应用在使用时使用定位服务。"
在pyproject.toml
中配置 iOS 权限:
[tool.flet.ios.info] # --info-plist
NSCameraUsageDescription = "此应用使用相机来……"
深度链接
你可以使用以下flet build
选项为 iOS 包配置深度链接设置:
--deep-linking-scheme
- 为 iOS 和 Android 构建配置的深度链接 URL 方案,例如“https”或“myapp”。--deep-linking-host
- 深度链接 URL 主机。
同样可以在pyproject.toml
中进行配置:
[tool.flet.ios.deep_linking]
scheme = "https"
host = "mydomain.com"
有关更多信息和完整设置指南,请参阅 Flutter 文档中的深度链接部分。