fastlane produce 完全指南:在 App Store Connect 与 Apple Developer Portal 自动化创建 iOS 应用
本文基于 fastlane 仓库中 produce 动作的官方文档 create_app_online.md 编写,系统讲解 fastlane produce 的完整能力:在 App Store Connect 和 Apple Developer Portal 上自动创建新应用、管理与 App ID 关联的 Application Services(HomeKit、HealthKit、iCloud、App Group 等)、创建 App Group / iCloud Container / Apple Pay Merchant 并将其与应用关联,以及 enable_services 的可用取值。读完后你能够用命令行或 Fastfile 完整跑通"从零注册一个 App ID 并配置好全部所需服务"的发布前置流程,并理解每个参数在源码中的实际行为。
一、produce 能做什么
produce 是 fastlane 中专门负责"上线前注册工作"的工具:它用最少必需信息在 App Store Connect 和 Apple Developer Portal 上同时创建新 iOS 应用。原文档列出的完整能力清单如下:
- Create:在 App Store Connect 与 Apple Developer Portal 上创建新应用
- Modify:修改 Apple Developer Portal 上的 Application Services
- Create / Associate App Groups:创建 App Group,并把应用与 App Group 关联
- Create / Associate iCloud Containers:创建 iCloud Container,并把应用与 iCloud Container 关联
- Create / Associate Merchant Identifiers:创建 Merchant Identifier(Apple Pay),并把应用与 Merchant 关联
- 支持多个 Apple 账号,凭据安全存储在 Keychain 中
在 fastlane 框架内,produce 与 create_app_online 是同一个动作:produce.rb 中的 ProduceAction 直接继承自 CreateAppOnlineAction 并标注"Alias for the create_app_online action",两者共享同一套参数定义(见下文第五节参数来源)。
二、基础用法与全部命令
2.1 创建新应用
最简用法:
fastlane produce
查看所有可用参数:
fastlane produce --help
produce 是一个带子命令的工具,--help 输出(继承自原文档)如下:
Commands: (* default)
associate_group Associate with a group, which is created if needed or simply located otherwise
associate_merchant Associate with a merchant for use with Apple Pay. Apple Pay will be enabled for this app
create * Creates a new app on App Store Connect and the Apple Developer Portal
disable_services Disable specific Application Services for a specific app on the Apple Developer Portal
enable_services Enable specific Application Services for a specific app on the Apple Developer Portal
group Ensure that a specific App Group exists
cloud_container Ensure that a specific iCloud Container exists
help Display global or [command] help documentation
merchant Ensure that a specific Merchant exists
Global Options:
--verbose
-h, --help Display help documentation
-v, --version Display version information
Options for create:
-u, --username STRING Your Apple ID Username (PRODUCE_USERNAME)
-a, --app_identifier STRING App Identifier (Bundle ID, e.g. com.krausefx.app) (PRODUCE_APP_IDENTIFIER)
-e, --bundle_identifier_suffix STRING App Identifier Suffix (Ignored if App Identifier does not ends with .*) (PRODUCE_APP_IDENTIFIER_SUFFIX)
-q, --app_name STRING App Name (PRODUCE_APP_NAME)
-z, --app_version STRING Initial version number (e.g. '1.0') (PRODUCE_VERSION)
-y, --sku STRING SKU Number (e.g. '1234') (PRODUCE_SKU)
-j, --platform STRING The platform to use (optional) (PRODUCE_PLATFORM)
-m, --language STRING Primary Language (e.g. 'English', 'German') (PRODUCE_LANGUAGE)
-c, --company_name STRING The name of your company. It's used to set company name on App Store Connect team's app pages. Only required if it's the first app you create (PRODUCE_COMPANY_NAME)
-i, --skip_itc [VALUE] Skip the creation of the app on App Store Connect (PRODUCE_SKIP_ITC)
-d, --skip_devcenter [VALUE] Skip the creation of the app on the Apple Developer Portal (PRODUCE_SKIP_DEVCENTER)
-s, --itc_users ARRAY Array of App Store Connect users. If provided, you can limit access to this newly created app for users with the App Manager, Developer, Marketer or Sales roles (ITC_USERS)
-b, --team_id STRING The ID of your Developer Portal team if you're in multiple teams (PRODUCE_TEAM_ID)
-l, --team_name STRING The name of your Developer Portal team if you're in multiple teams (PRODUCE_TEAM_NAME)
-k, --itc_team_id [VALUE] The ID of your App Store Connect team if you're in multiple teams (PRODUCE_ITC_TEAM_ID)
-p, --itc_team_name STRING The name of your App Store Connect team if you're in multiple teams (PRODUCE_ITC_TEAM_NAME)
2.2 create 参数补充说明(来自源码)
create 子命令的全部参数由 options.rb 中的 Produce::Options.available_options 定义,结合源码可以补充几点原文档未展开的细节:
-u/--username:环境变量为PRODUCE_USERNAME。源码中默认值会从Appfile的apple_dev_portal_id或apple_id字段动态读取(CredentialsManager::AppfileConfig.try_fetch_value),即在 Appfile 中配置一次后可省略该参数。-a/--app_identifier:同样支持从 Appfile 的app_identifier动态取默认值。-z/--app_version:注意其环境变量是PRODUCE_VERSION(不是PRODUCE_APP_VERSION),在 options.rb 中env_name: "PRODUCE_VERSION"明确定义。-y/--sku:若未提供,源码默认使用当前 Unix 时间戳(Time.now.to_i.to_s)自动生成,保证 SKU 唯一。-j/--platform:可选值仅ios、osx、tvos,源码中有verify_block校验,非法值会直接报错;默认ios。-i/--skip_itc与-d/--skip_devcenter:可分别跳过 App Store Connect 或 Apple Developer Portal 一侧的创建,适合只需要其中一端注册的团队。- 源码中还存在一个
-J/--platforms(数组,PRODUCE_PLATFORMS)参数,允许一次性为多个平台(如ios、osx)在 App Store Connect 上创建应用,--help输出中未展示;从源码结构看,Developer Portal 侧已平台无关,取数组第一个平台用于兼容逻辑。
三、启用 / 禁用 Application Services
对已存在的 App ID 增删 Application Services 使用 enable_services / disable_services 子命令:
# 启用 HomeKit 和 HealthKit
fastlane produce enable_services --homekit --healthkit
# 禁用 iCloud
fastlane produce disable_services --icloud
可用服务参数完整列表(继承自原文档,fastlane produce enable_services --help 输出):
--access-wifi Enable Access Wifi
--app-attest Enable App Attest
--app-group Enable App Group
--apple-pay Enable Apple Pay
--associated-domains Enable Associated Domains
--auto-fill-credential Enable Auto Fill Credential
--class-kit Enable Class Kit
--icloud STRING Enable iCloud, suitable values are "xcode5_compatible" and "xcode6_compatible"
--custom-network-protocol Enable Custom Network Protocol
--data-protection STRING Enable Data Protection, suitable values are "complete", "unlessopen" and "untilfirstauth"
--extended-virtual-address-space Enable Extended Virtual Address Space
--declared-age-range Enable Declared Age Range capability
--game-center STRING Enable Game Center, suitable values are "ios" and "macos
--health-kit Enable Health Kit
--hls-interstitial-preview Enable Hls Interstitial Preview
--home-kit Enable Home Kit
--hotspot Enable Hotspot
--in-app-purchase Enable In App Purchase
--inter-app-audio Enable Inter App Audio
--low-latency-hls Enable Low Latency Hls
--managed-associated-domains Enable Managed Associated Domains
--maps Enable Maps
--multipath Enable Multipath
--network-extension Enable Network Extension
--nfc-tag-reading Enable NFC Tag Reading
--personal-vpn Enable Personal VPN
--passbook Enable Passbook (deprecated)
--push-notification Enable Push Notification
--sign-in-with-apple Enable Sign In With Apple
--siri-kit Enable Siri Kit
--system-extension Enable System Extension
--user-management Enable User Management
--vpn-configuration Enable Vpn Configuration (deprecated)
--wallet Enable Wallet
--wireless-accessory Enable Wireless Accessory
--car-play-audio-app Enable Car Play Audio App
--car-play-messaging-app Enable Car Play Messaging App
--car-play-navigation-app Enable Car Play Navigation App
--car-play-voip-calling-app Enable Car Play Voip Calling App
--critical-alerts Enable Critical Alerts
--hotspot-helper Enable Hotspot Helper
--driver-kit Enable DriverKit
--driver-kit-endpoint-security Enable DriverKit Endpoint Security
--driver-kit-family-hid-device Enable DriverKit Family HID Device
--driver-kit-family-networking Enable DriverKit Family Networking
--driver-kit-family-serial Enable DriverKit Family Serial
--driver-kit-hid-event-service Enable DriverKit HID EventService
--driver-kit-transport-hid Enable DriverKit Transport HID
--multitasking-camera-access Enable Multitasking Camera Access
--sf-universal-link-api Enable SFUniversalLink API
--vp9-decoder Enable VP9 Decoder
--music-kit Enable MusicKit
--shazam-kit Enable ShazamKit
--communication-notifications Enable Communication Notifications
--group-activities Enable Group Activities
--health-kit-estimate-recalibration Enable HealthKit Estimate Recalibration
--time-sensitive-notifications Enable Time Sensitive Notifications
fastlane produce disable_services --help 提供同一组参数,语义相反(Disable Access Wifi、Disable Apple Pay……),不再重复罗列。
带取值的参数。绝大多数服务是布尔开关(--on/--off 语义),但有三个例外,--icloud、--data-protection、--game-center 需要显式取值:
--icloud:文档取值"xcode5_compatible"/"xcode6_compatible";--data-protection:取值"complete"、"unlessopen"、"untilfirstauth";--game-center:取值"ios"或 mac 端取值。
从当前仓库源码 developer_center.rb 中的 ALLOWED_SERVICES 定义看,icloud 的合法值常量已演化为 "legacy"(映射到 iCloud + CloudKit xcode5_compatible)与 "cloudkit"(映射到 iCloud + CloudKit cloud_kit),game_center 的取值定义为 "ios" 和 "mac",此外还支持 family_controls 等文档未列出的服务键。实际使用时请以当前安装的 fastlane 版本 --help 输出为准,并在传入 enable_services 哈希时注意源码中 verify_block 会对非法键直接报错。
四、App Group 与 iCloud Container 管理
4.1 App Group
创建(若已存在则仅定位)一个 App Group:
fastlane produce group -g group.krausefx -n "Example App Group"
把应用与 App Group 关联:
fastlane produce associate_group -a com.krausefx.app group.krausefx
4.2 iCloud Container
创建 iCloud Container:
fastlane produce cloud_container -g iCloud.com.krausefx.app -n "Example iCloud Container"
把应用与一个或多个 iCloud Container 关联:
fastlane produce associate_cloud_container -a com.krausefx.app iCloud.com.krausefx.app
fastlane produce associate_cloud_container -a com.krausefx.app iCloud.com.krausefx.app1 iCloud.com.krausefx.app2
对应的实现分别位于 group.rb 与 cloud_container.rb,均遵循"确保存在"(ensure)语义:目标对象不存在时创建,已存在时跳过,适合反复执行于 CI。
五、Apple Pay Merchant:创建与关联
创建 Merchant Identifier:
fastlane produce merchant -o merchant.com.example.production -r "Example Merchant Production"
查看所有参数:fastlane produce merchant --help。
把应用与 Merchant 关联(会同时为该 App 启用 Apple Pay 服务),支持一次关联多个:
fastlane produce associate_merchant -a com.krausefx.app merchant.com.example.production
fastlane produce associate_merchant -a com.krausefx.app merchant.com.example.production merchant.com.example.sandbox
参数说明:fastlane produce associate_merchant --help。
源码层面,merchant.rb 的 associate 方法会先通过 app.update_service(Spaceship.app_service.apple_pay.on) 打开 Apple Pay 能力,然后对传入的 identifier 列表做存在性校验(partition { |identifier| merchant_exists?(identifier) }):已存在的 Merchant 被关联,不存在的仅打印提示并跳过,不会中断整个流程——这与"确保存在"的幂等设计保持一致。
六、Fastfile 集成与 deliver 衔接
将 produce 嵌入 Fastfile 的标准写法(继承自原文档示例):
lane :release do
produce(
username: 'felix@krausefx.com',
app_identifier: 'com.krausefx.app',
app_name: 'MyApp',
language: 'English',
app_version: '1.0',
sku: '123',
team_name: 'SunApps GmbH', # only necessary when in multiple teams
# Optional
# App services can be enabled during app creation
enable_services: {
access_wifi: "on", # Valid values: "on", "off"
app_attest: "on", # Valid values: "on", "off"
app_group: "on", # Valid values: "on", "off"
apple_pay: "on", # Valid values: "on", "off"
associated_domains: "on", # Valid values: "on", "off"
auto_fill_credential: "on", # Valid values: "on", "off"
car_play_audio_app: "on", # Valid values: "on", "off"
car_play_messaging_app: "on", # Valid values: "on", "off"
car_play_navigation_app: "on", # Valid values: "on", "off"
car_play_voip_calling_app: "on", # Valid values: "on", "off"
class_kit: "on", # Valid values: "on", "off"
declared_age_range: "on", # Valid values: "on", "off"
icloud: "xcode5_compatible", # Valid values: "xcode5_compatible", "xcode6_compatible", "off"
critical_alerts: "on", # Valid values: "on", "off"
custom_network_protocol: "on", # Valid values: "on", "off"
data_protection: "complete", # Valid values: "complete", "unlessopen", "untilfirstauth", "off"
extended_virtual_address_space: "on", # Valid values: "on", "off"
file_provider_testing_mode: "on", # Valid values: "on", "off"
fonts: "on", # Valid values: "on", "off"
game_center: "ios", # Valid values: "ios", "macos", off"
health_kit: "on", # Valid values: "on", "off"
hls_interstitial_preview: "on", # Valid values: "on", "off"
home_kit: "on", # Valid values: "on", "off"
hotspot: "on", # Valid values: "on", "off"
hotspot_helper: "on", # Valid values: "on", "off"
in_app_purchase: "on", # Valid values: "on", "off"
inter_app_audio: "on", # Valid values: "on", "off"
low_latency_hls: "on", # Valid values: "on", "off"
managed_associated_domains: "on", # Valid values: "on", "off"
maps: "on", # Valid values: "on", "off"
multipath: "on", # Valid values: "on", "off"
network_extension: "on", # Valid values: "on", "off"
nfc_tag_reading: "on", # Valid values: "on", "off"
passbook: "on", # Valid values: "on", "off" (deprecated)
personal_vpn: "on", # Valid values: "on", "off"
push_notification: "on", # Valid values: "on", "off"
sign_in_with_apple: "on", # Valid values: "on", "off"
siri_kit: "on", # Valid values: "on", "off"
system_extension: "on", # Valid values: "on", "off"
user_management: "on", # Valid values: "on", "off"
vpn_configuration: "on", # Valid values: "on", "off" (deprecated)
wallet: "on", # Valid values: "on", "off"
wireless_accessory: "on", # Valid values: "on", "off"
driver_kit: "on", # Valid values: "on", "off"
driver_kit_endpoint_security: "on", # Valid values: "on", "off"
driver_kit_family_hid_device: "on", # Valid values: "on", "off"
driver_kit_family_networking: "on", # Valid values: "on", "off"
driver_kit_family_serial: "on", # Valid values: "on", "off"
driver_kit_hid_event_service: "on", # Valid values: "on", "off"
driver_kit_transport_hid: "on", # Valid values: "on", "off"
multitasking_camera_access: "on", # Valid values: "on", "off"
sf_universal_link_api: "on", # Valid values: "on", "off"
vp9_decoder: "on", # Valid values: "on", "off"
music_kit: "on", # Valid values: "on", "off"
shazam_kit: "on", # Valid values: "on", "off"
communication_notifications: "on", # Valid values: "on", "off"
group_activities: "on", # Valid values: "on", "off"
health_kit_estimate_recalibration: "on", # Valid values: "on", "off"
time_sensitive_notifications: "on", # Valid values: "on", "off"
}
)
deliver
end
要使用刚创建的应用进行 deliver 上传,需在 Deliverfile 中加入:
apple_id(ENV['PRODUCE_APPLE_ID'])
因为应用尚未上架 App Store,deliver 无法自动探测到它,必须显式告知使用哪个 App ID。其余信息(截图、描述、定价等)仍需手动补齐,可继续使用 deliver 上传元数据。
环境变量
所有参数均可通过环境变量传入(各参数的环境变量名见第二节 --help 输出,如 PRODUCE_USERNAME、PRODUCE_APP_IDENTIFIER、PRODUCE_TEAM_ID 等),运行 fastlane produce --help 可列出完整清单。团队配置(team_id、team_name、itc_team_id、itc_team_name)也可写入 Appfile 由 username、app_identifier 等参数动态读取默认值。
七、底层执行流程与源码解析
7.1 动作入口:从 Fastfile 到 produce 工具
在 fastlane 框架侧,create_app_online.rb 的 run 方法执行了如下动作:
- 仅在 iOS 平台可用(
is_supported?(platform)判断platform == :ios); - 直接以传入的
params作为Produce.config("we already have the finished config"); chdir到 fastlane 目录(即fastlane/文件夹)后调用Produce::Manager.start_producing;- 将返回值(App Store Connect 应用 ID)写入 lane 上下文
SharedValues::PRODUCE_APPLE_ID,并同时导出ENV['PRODUCE_APPLE_ID']——这正是Deliverfile里apple_id(ENV['PRODUCE_APPLE_ID'])的数据来源。
7.2 两端注册:Manager 分派
manager.rb 是整个流程的调度中心,逻辑非常清晰:
def self.start_producing
# 打印配置摘要
Produce::DeveloperCenter.new.run unless Produce.config[:skip_devcenter]
return Produce::ItunesConnect.new.run unless Produce.config[:skip_itc]
end
先注册 Developer Portal 侧(除非 skip_devcenter),再注册 App Store Connect 侧(除非 skip_itc),返回值即为 AS Connect 应用 ID。
7.3 Developer Portal 侧:幂等创建 + 服务映射
developer_center.rb 的 run 依次执行 login(Spaceship 登录 + 团队选择)与 create_new_app:
- 幂等:先
app_exists?查询 Bundle ID,已存在则提示 "already exists, nothing to do on the Dev Center" 并直接返回,不会重复创建; - 非 ASCII 应用名:若
app.name与期望不符(Apple Developer Portal 不支持非 ASCII 名称),源码会自动生成一个唯一的内部名称并打印UI.important提示,真实的 App 名称仍会正确显示在 App Store Connect 与 App Store 上; - 服务映射:
enable_services私有方法把用户传入的哈希逐项映射为 Spaceship 的 service 对象。布尔型键按"on"/"off"分别取.on/.off;data_protection按complete/unlessopen/untilfirstauth三档映射;icloud按取值同时开启 iCloud 与对应的 CloudKit 兼容模式(xcode5_compatible或cloud_kit)。
7.4 App Store Connect 侧:通配符解析与轮询等待
itunes_connect.rb 的要点:
- 通配符 Bundle ID:若
app_identifier以*结尾,会用bundle_identifier_suffix替换成完整 ID 再注册(@full_bundle_identifier.gsub!('*', suffix)); - 创建参数:调用
Spaceship::ConnectAPI::App.create,传入name、version_string(缺省"1.0")、sku、primary_locale、bundle_id、platforms与company_name; - 轮询确认:App Store Connect 创建应用后需要时间才能在列表中可见,源码会每 15 秒轮询一次(
sleep(15)),最多 200 次(约 50 分钟),超时则UI.crash!提示到官网检查; - 用户授权:若提供了
itc_users,先校验用户存在性,创建成功后application.add_users(user_ids:)批量授予访问权限; - 版本兜底:
application.ensure_version!(Produce.config[:app_version], platform:)确保初始版本号已建立。
7.5 团队选择与环境变量联动
从 options.rb 的 verify_block 看,team_id/team_name/itc_team_id/itc_team_name 在配置校验阶段会同步写入 FASTLANE_TEAM_ID、FASTLANE_TEAM_NAME、FASTLANE_ITC_TEAM_ID、FASTLANE_ITC_TEAM_NAME 环境变量,供 Spaceship 登录时做团队选择;而 module.rb 在加载时还会把 PRODUCE_TEAM_ID 回填到 FASTLANE_TEAM_ID、把 PRODUCE_USERNAME 回填到 DELIVER_USER,使同一次运行中的其他 fastlane 工具也能复用这些凭据信息。
八、密码与凭据如何存储
produce 使用 fastlane 内置的密码管理器(credentials_manager):Apple ID 凭据安全存储在系统 Keychain 中,支持多 Apple 账号。更多实现细节可查阅仓库中的 credentials_manager README。
九、小结
| 场景 | 命令 / 代码 | 关键点 |
|---|---|---|
| 全量创建应用 | fastlane produce 或 Fastfile 中 produce(...) |
先 Dev Portal 后 AS Connect,两端均幂等 |
| 只创建一端 | --skip_itc / --skip_devcenter |
见 manager.rb 分派逻辑 |
| 修改服务开关 | fastlane produce enable_services/disable_services --xxx |
带取值参数:--icloud、--data-protection、--game-center |
| App Group / iCloud Container | fastlane produce group、associate_group、cloud_container、associate_cloud_container |
支持一次关联多个容器 |
| Apple Pay | fastlane produce merchant、associate_merchant |
关联时自动开启 Apple Pay,不存在的 Merchant 跳过不报错 |
| 衔接 deliver | Deliverfile 中 apple_id(ENV['PRODUCE_APPLE_ID']) |
来源为 create_app_online.rb 写出的 SharedValue / 环境变量 |
需要注意的适用前提:该动作仅支持 iOS 平台;App Store Connect 侧创建后存在异步可见延迟(源码内以 15 秒间隔轮询);enable_services 各键的合法取值以当前 fastlane 版本的 ALLOWED_SERVICES 定义为准,建议以 --help 实际输出为最终依据。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00