首页
/ fastlane produce 完全指南:在 App Store Connect 与 Apple Developer Portal 自动化创建 iOS 应用

fastlane produce 完全指南:在 App Store Connect 与 Apple Developer Portal 自动化创建 iOS 应用

2026-09-05 23:13:00作者:温艾琴Wonderful

本文基于 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 框架内,producecreate_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。源码中默认值会从 Appfileapple_dev_portal_idapple_id 字段动态读取(CredentialsManager::AppfileConfig.try_fetch_value),即在 Appfile 中配置一次后可省略该参数。
  • -a/--app_identifier:同样支持从 Appfile 的 app_identifier 动态取默认值。
  • -z/--app_version:注意其环境变量是 PRODUCE_VERSION(不是 PRODUCE_APP_VERSION),在 options.rbenv_name: "PRODUCE_VERSION" 明确定义。
  • -y/--sku:若未提供,源码默认使用当前 Unix 时间戳(Time.now.to_i.to_s)自动生成,保证 SKU 唯一。
  • -j/--platform:可选值仅 iososxtvos,源码中有 verify_block 校验,非法值会直接报错;默认 ios
  • -i/--skip_itc-d/--skip_devcenter:可分别跳过 App Store Connect 或 Apple Developer Portal 一侧的创建,适合只需要其中一端注册的团队。
  • 源码中还存在一个 -J/--platforms(数组,PRODUCE_PLATFORMS)参数,允许一次性为多个平台(如 iososx)在 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.rbcloud_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.rbassociate 方法会先通过 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_USERNAMEPRODUCE_APP_IDENTIFIERPRODUCE_TEAM_ID 等),运行 fastlane produce --help 可列出完整清单。团队配置(team_id、team_name、itc_team_id、itc_team_name)也可写入 Appfileusernameapp_identifier 等参数动态读取默认值。

七、底层执行流程与源码解析

7.1 动作入口:从 Fastfile 到 produce 工具

在 fastlane 框架侧,create_app_online.rbrun 方法执行了如下动作:

  1. 仅在 iOS 平台可用(is_supported?(platform) 判断 platform == :ios);
  2. 直接以传入的 params 作为 Produce.config("we already have the finished config");
  3. chdir 到 fastlane 目录(即 fastlane/ 文件夹)后调用 Produce::Manager.start_producing
  4. 将返回值(App Store Connect 应用 ID)写入 lane 上下文 SharedValues::PRODUCE_APPLE_ID,并同时导出 ENV['PRODUCE_APPLE_ID']——这正是 Deliverfileapple_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.rbrun 依次执行 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/.offdata_protectioncomplete/unlessopen/untilfirstauth 三档映射;icloud 按取值同时开启 iCloud 与对应的 CloudKit 兼容模式(xcode5_compatiblecloud_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,传入 nameversion_string(缺省 "1.0")、skuprimary_localebundle_idplatformscompany_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.rbverify_block 看,team_id/team_name/itc_team_id/itc_team_name 在配置校验阶段会同步写入 FASTLANE_TEAM_IDFASTLANE_TEAM_NAMEFASTLANE_ITC_TEAM_IDFASTLANE_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 groupassociate_groupcloud_containerassociate_cloud_container 支持一次关联多个容器
Apple Pay fastlane produce merchantassociate_merchant 关联时自动开启 Apple Pay,不存在的 Merchant 跳过不报错
衔接 deliver Deliverfileapple_id(ENV['PRODUCE_APPLE_ID']) 来源为 create_app_online.rb 写出的 SharedValue / 环境变量

需要注意的适用前提:该动作仅支持 iOS 平台;App Store Connect 侧创建后存在异步可见延迟(源码内以 15 秒间隔轮询);enable_services 各键的合法取值以当前 fastlane 版本的 ALLOWED_SERVICES 定义为准,建议以 --help 实际输出为最终依据。

登录后查看全文
热门项目推荐
相关项目推荐