Highlight
App Store Connect API 在 2020 年新增 200 多个端点,把 App 版本元数据、截图和预览上传、审核提交,以及 Xcode Power and Performance 指标开放给自动化流程,但手动发布、内购和 Game Center 仍需在网页配置。
核心内容
App Store Connect API 最早解决的是重复性后台工作:管理团队用户、创建 provisioning profile、增删 beta tester、下载销售和财务报告。团队把这些步骤写进脚本后,发版准备会少很多手工操作。但还有一块重要流程留在网页里:创建新版本、维护 App Store 元数据、上传截图和预览、把版本送审。(00:35)
2020 年的变化就是把这段发版链路补进 API。Apple 新增了 200 多个端点,数量超过原有 API 的一倍。App Metadata API 覆盖 App 分类、全球可用地区、主语言、许可协议、版本创建、平台添加、截图和 app preview 上传,以及名称、描述、关键词等本地化信息。完整范围从创建新版本一直到提交 App Review。(01:02)
演示里的 Forest Explorer 是一个具体发版例子。它走了一次真实发版流程:先创建新版本,再改价格,接着更新元数据,关联已上传的 build,最后提交审核。这个顺序很适合放进 CI/CD 或发布脚本:每一步都能拿到明确的 HTTP 响应,失败时也能停在具体资源上。(03:17)
同场还加入了 Power and Performance Metrics and Diagnostics API。它把 Xcode Organizer 里用来分析内存、启动时间、hang rate、磁盘写入和电量消耗的聚合数据开放出来。团队可以把线上性能趋势接进自己的 dashboard、bug 系统或回归检查流程。(22:39)
边界也很清楚。手动发布仍要在 App Store Connect 网站或 iOS App 里完成,内购和 Game Center 配置也还在网页端。价格和可用地区变更会立刻影响线上 App,不能拿 live app 做实验。(02:00、11:06)
详细内容
创建 App Store 版本
(04:16)创建版本的起点是 Apps 资源。每个 App 都有 App Store Versions 关系;每个版本有 platform 和 versionString。演示先用 bundle ID 查到 App ID,再创建 App Store Version。
GET /v1/apps?filter[bundleID]=com.example.ForestExplorer
200 OK
response data:
app id: {appId}
关键点:
filter[bundleID]来自演示,用来精确定位目标 App。- 响应里的 app id 也是文档里常见的 Apple ID,后续版本、价格和 build 关联都会用到它。
- 这一步只读取资源,适合作为发布脚本的第一个校验点。
POST /v1/appStoreVersions
platform: IOS
versionString: 2.0
app relationship: {appId}
201 CREATED
response data:
app store version id: {versionId}
关键点:
platform、versionString和 app relationship 是 transcript 明确点名的创建信息。201 CREATED表示 App Store Connect 已经创建版本;登录网页后会在侧边栏看到它。- 响应返回的 version id 是后续本地化、build 关联和提交审核的主线资源。
用一次 PATCH 原子化修改价格计划
(07:17)价格计划由 App Prices 和 Price Tier 组成。当前价格的 startDate 为 null;未来价格会带生效日期。演示先读取当前价格,并把相关的 priceTier 一起 include 进响应。
GET /v1/apps/{appId}/prices?include=priceTier
200 OK
response data:
price startDate: null
priceTier: Tier 1
关键点:
- 当前价格用
startDate: null表示正在生效。 priceTier指向只读参考数据,和 App Store Connect 里的 All Prices and Currencies 页面一致。- include priceTier 后,脚本能在同一次响应里拿到价格层级关系。
(08:24)如果要做一周免费促销,演示没有发三次创建请求,而是对 App 发一次 PATCH,把三个新价格作为同一个变更提交。
PATCH /v1/apps/{appId}
relationships.prices:
- ${new-price-1}
- ${new-price-2}
- ${new-price-3}
included:
- id: ${new-price-1}
startDate: null
priceTier: Tier 1
- id: ${new-price-2}
startDate: 2020-06-29
priceTier: Tier 0
- id: ${new-price-3}
startDate: 2020-07-06
priceTier: Tier 1
200 OK
关键点:
${...}是演示强调的临时 ID 语法,用来引用同一个请求里还没创建的资源。included里的三个资源会被 App Store Connect 创建、分配真实 ID,并链接到 App。- 价格和可用地区变更会马上上架生效,测试脚本时要避开已经发布的 live app。
上传 App Preview 的四步流程
(13:33)元数据分成 App 级别和版本级别。本地化名称、subtitle、隐私政策在 App Info Localizations;截图、promotional text、关键词和 app preview 在 App Store Version Localization。演示以 US English 的 6.5 英寸 iPhone app preview 为例。
GET /v1/appStoreVersions/{versionId}/appStoreVersionLocalizations
GET {appPreviewSets relationship URL}
POST /v1/appPreviewSets
previewType: IPHONE_65
localization relationship: {localizationId}
关键点:
- 每个版本至少有一个本地化,也就是主语言对应的 localization。
- 如果 appPreviewSets 返回空数组,需要先创建 preview set。
IPHONE_65是演示里的 previewType,代表 6.5 英寸 iPhone。
(15:45)真正上传视频文件时,App Store Connect API 使用四步:创建 reservation、上传一个或多个 part、commit asset、检查错误。
POST /v1/appPreviews
file name: ForestExplorer.mov
file size in bytes: <bytes>
appPreviewSet relationship: {previewSetId}
response upload operations:
method
url
length in bytes
offset in bytes
request headers
关键点:
- 创建 reservation 时要告诉 App Store Connect 文件名和字节大小。
- 响应会给出 upload operations;小文件可能只有一个操作,大文件可能有多个。
- 客户端要按
length和offset切分文件,并带上每个 operation 给出的 method、URL 和 headers。
for each upload operation:
read bytes from offset with length
upload that part with the provided method, URL, and headers
retry only the failed part when a part upload fails
关键点:
- 多个 part 的上传顺序不重要,也可以并行上传。
- 单个 part 失败时只重试这一段,已经成功的 part 不需要重新上传。
- 客户端要始终按多个 operation 设计,因为同一个资源今天可能一段上传,明天可能被拆成多段。
PATCH /v1/appPreviews/{previewId}
uploaded: true
source file MD5 checksum: <checksum>
关键点:
- commit 阶段把
uploaded设为 true,并提交原始文件的 MD5 checksum。 - App Store Connect 会重新组装 asset、校验 checksum、检查文件完整性、视频长度、尺寸和音轨。
- 处理是异步的;重新 fetch asset 后,
state变成COMPLETE才算成功,FAILED时看 errors array 后删除、修复、重传。
关联 build 并提交审核
(19:49)build 本身仍由 Xcode 或 Transporter 上传。API 负责查到 build id,然后把它挂到新版本。
GET /v1/builds
filters:
app ID: {appId}
pre-release version number: {preReleaseVersion}
build version number: {buildNumber}
关键点:
- 演示按 app ID、pre-release version number 和 build version number 三个条件定位 build。
- 响应里的 build id 会用于版本关系更新。
- 这一步适合检查 CI 刚上传的 build 是否已经进入 App Store Connect。
PATCH /v1/appStoreVersions/{versionId}/relationships/build
build id: {buildId}
204 NO CONTENT
关键点:
204 NO CONTENT表示关系更新成功,没有资源正文返回。- 这个响应能确认 build id 和 version id 都有效。
- 元数据和 build 都准备好后,版本才具备送审条件。
(21:00)App Review 仍然需要联系信息、demo account、备注和必要附件。API 里对应的是 App Review Details、App Review Attachments 和 App Store Version Submission。
POST /v1/appReviewDetails
version relationship: {versionId}
POST /v1/appStoreVersionSubmissions
version relationship: {versionId}
DELETE /v1/appStoreVersionSubmissions/{submissionId}
关键点:
- Review details 可以在真正提交前多次 PATCH 修改。
- 创建 App Store Version Submission 等同于点击 Submit for Review。
- 如果发现错误,可以删除 submission 撤回;如果版本缺少截图等必要内容,创建 submission 会得到
400和错误说明。
读取 Power and Performance 指标与诊断
(23:21)Power and Performance API 读取的是 Xcode Power and Performance 视图背后的聚合数据。入口可以是 App,也可以是 build。
GET /v1/apps/{appId}/perfPowerMetrics
Accept: <Power and Performance custom media type>
GET /v1/builds/{buildId}/perfPowerMetrics
Accept: <Power and Performance custom media type>
关键点:
- 从 App URL 的
perfPowerMetrics关系读取最近版本的指标。 - 从 build URL 的
perfPowerMetrics关系读取某个 build 的指标。 - transcript 明确提到返回里包含 HANG metrics,hang rate 的单位是 seconds per hour。
(24:09)磁盘写入还有诊断签名和 log data。它们能把“写入量变高”推进到具体调用栈。
GET /v1/builds/{buildId}/diagnosticSignatures
response data:
signature
weight
log data relationship
GET {log data relationship URL}
Accept: <Power and Performance custom media type>
关键点:
- diagnostic signatures 按对总磁盘写入的贡献排序,最大贡献排在前面。
signature标识运行时写入位置,weight表示它对总写入的贡献。- log data 响应包含 app 信息、总磁盘写入和详细 call stack,可用来定位性能问题来源。
核心启发
-
做什么:把发版草稿创建纳入 CI。 为什么值得做:本场演示的主链路从 app id 查询、版本创建、build 关联一直走到 App Review submission,适合把“准备发版”从网页点击改成可审计的脚本。 怎么开始:先实现
GET /v1/apps?filter[bundleID]=...和POST /v1/appStoreVersions,把返回的{versionId}记录到发布流水线日志。 -
做什么:做一个价格促销排期脚本。 为什么值得做:价格计划可以用一次 PATCH 原子化更新,避免半途只创建了部分价格节点。 怎么开始:先读取
/v1/apps/{appId}/prices?include=priceTier,再用临时 ID${new-price-*}生成完整促销周期;上线前加环境保护,禁止对 live app 运行测试 payload。 -
做什么:把多语言元数据从仓库同步到 App Store Connect。 为什么值得做:App Info Localizations 和 App Store Version Localizations 覆盖名称、subtitle、privacy policy、截图、关键词和 promotional text,适合和本地化文件一起进入代码评审。 怎么开始:按 locale 读取 version localizations,先只同步一个市场的名称和关键词,确认审核流程无误后再接入截图和 preview set。
-
做什么:实现可恢复的素材上传 worker。 为什么值得做:app preview、截图、App Review attachments 和 GeoJSON routing app coverage files 都走 reservation、part upload、commit、error check 这套流程。 怎么开始:把 upload operations 按
offset和length落成任务队列;单段失败只重试这一段;commit 后轮询state,遇到FAILED时把 errors array 写进构建日志。 -
做什么:把线上性能指标接进团队 dashboard。 为什么值得做:
perfPowerMetrics和diagnosticSignatures能把 Xcode Organizer 的聚合数据放进自定义工具,hang rate、磁盘写入和调用栈可以进入回归告警。 怎么开始:先从 App 级perfPowerMetrics拉最近版本趋势,再对异常 build 请求diagnosticSignatures和 log data,把signature、weight和 call stack 关联到问题单。
关联 Session
- Identify trends with the Power and Performance API — 深入讲
perfPowerMetrics、diagnostic signatures 和 log data,正好承接本场最后的性能 API 概览。 - Diagnose performance issues with the Xcode Organizer — 从 Xcode Organizer 视角解释同一批聚合性能数据,适合理解 API 数据在工具里的呈现方式。
- What’s new in App Store Connect — 汇总 App Store Connect 在 2020 年的改进,包括本场涉及的 API、内购、订阅和 Game Center。
- Introducing StoreKit Testing in Xcode — 讲本地 StoreKit 测试环境,适合和自动化发版流程里的购买测试搭配。
- What’s new with in-app purchase — 补充内购、退款、服务端通知和 StoreKit 更新;本场明确说明内购配置仍需在网页端完成。
评论
GitHub Issues · utterances