数据与AI
用 asc 收集并校验 App Store Connect…
当需要通过 asc CLI 发现、下载并校验 App Store Connect Analytics 报告分段时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
用 asc 收集并校验 App Stor特定
解决思路
- 在认证或收集前先检查已安装命令:运行 `asc analytics view --help`,仅当帮助中列出 `--processing-date`、`--granularity`、`--paginate` 和 `--include-segments` 时才继续;这些过滤器需要 asc 3.5.0 或更新版本,若缺少任一过滤器则请用户升级,不要用已弃用的 `--date` 替代,因为它使用旧式本地匹配而非 Apple 服务端 processing-date 过滤。
- 在捕获 JSON 或下载分段前准备私有存储:运行 `umask 077`,用 `ASC_ANALYTICS_DIR="$(mktemp -d "${TMPDIR:-/tmp}/asc-analytics.XXXXXX")"` 创建仓库外的私有临时目录,并 `mkdir -m 700 "$ASC_ANALYTICS_DIR/segments"`;将命令输出和错误重定向到该目录,不要把原始 inventory JSON 或错误输出粘贴到聊天、提交、issue 或 PR。
- 查找已有请求:解析 app ID 和所选 asc profile,运行 `asc --profile "$PROFILE" analytics requests --app "$APP_ID" --paginate --output json > "$ASC_ANALYTICS_DIR/requests.json" 2> "$ASC_ANALYTICS_DIR/requests.stderr"` 列出所有请求;结构化检查 JSON 并选择已有可用请求,发现可用时不要依赖 `--state`。
- 若无可用请求则停止并询问用户是否创建 `ONGOING` 或 `ONE_TIME_SNAPSHOT` 访问;在请求批准前说明目标 app 和 profile;批准后优先使用 `--reuse-existing` 避免重复:`asc --profile "$APPROVED_PROFILE" analytics request --app "$APP_ID" --access-type "$ACCESS_TYPE" --reuse-existing --output json > "$ASC_ANALYTICS_DIR/request.json" 2> "$ASC_ANALYTICS_DIR/request.stderr"`;未经明确批准不要运行该命令。
- 从私有 JSON 响应读取返回的请求 ID 再继续:`REQUEST_ID="$(jq -er '.requestId' "$ASC_ANALYTICS_DIR/request.json")"`;当请求是用已批准 profile 创建或复用时设置 `ANALYTICS_PROFILE="$APPROVED_PROFILE"`,对于用只读 profile 发现的已有请求设置 `ANALYTICS_PROFILE="$PROFILE"`,后续每次 `analytics view` 和 `analytics download` 调用都使用同一 profile。
- 先检索报告和实例元数据而不含分段 URL:运行 `asc --profile "$ANALYTICS_PROFILE" analytics view --request-id "$REQUEST_ID" --paginate --output json > "$ASC_ANALYTICS_DIR/discovery.json" 2> "$ASC_ANALYTICS_DIR/discovery.stderr"`。
- 选择可用的 `processingDate` 和用户请求的 granularity:接受 `DAILY`、`WEEKLY`、`MONTHLY`,可单独或逗号分隔列表;按逗号拆分输入、去除每个 token 空白并规范化为大写;对每个 token(包括空 token)按该允许列表校验;报告无效输入并在运行 `analytics view` 前停止,绝不静默丢弃不支持的值或用空过滤器继续;校验后去重并用逗号连接剩余值;将 `processingDate` 视为 Apple 处理报告的日期,不一定是其行所代表的周期。
- 检索包含所有分段元数据的过滤后 inventory:运行 `asc --profile "$ANALYTICS_PROFILE" analytics view --request-id "$REQUEST_ID" --processing-date "$PROCESSING_DATE" --granularity "$GRANULARITY" --paginate --include-segments --output json > "$ASC_ANALYTICS_DIR/inventory.json" 2> "$ASC_ANALYTICS_DIR/inventory.stderr"`;始终使用 `--paginate`,asc 会跟随 Apple 提供的报告和实例 next 链接;不要手动重建、修改或跟随分页 URL。
- 结构化解析 `inventory.json`:对每个所选实例枚举所有分段,并保留每个分段的精确 ID、`sizeInBytes` 和 `checksum` 以供校验;不要打印 `downloadUrl`。
- 按请求、实例和分段 ID 下载每个分段:使用仅由分段 ID 派生的文件名并保持压缩字节不变;分析报告是制表符分隔文本,因此使用 `.txt.gz` 而非暗示 CSV:`SEGMENT_FILE="$ASC_ANALYTICS_DIR/segments/$SEGMENT_ID.txt.gz"`,然后 `asc --profile "$ANALYTICS_PROFILE" analytics download --request-id "$REQUEST_ID" --instance-id "$INSTANCE_ID" --segment-id "$SEGMENT_ID" --output "$SEGMENT_FILE" > /dev/null 2>> "$ASC_ANALYTICS_DIR/download.stderr"`;校验前不要使用 `--decompress`;若实例有多个分段则全部下载,绝不把第一个分段当作整个报告。
- 校验下载文件:对每个文件比较压缩字节数与 `sizeInBytes`,并将小写 MD5 摘要与 `checksum` 比较;使用本地系统工具如 `actual_size="$(wc -c < "$SEGMENT_FILE" | tr -d ' ')"`、`actual_md5="$(openssl dgst -md5 -r "$SEGMENT_FILE" | awk '{print tolower($1)}')"`、`expected_md5="$(printf '%s' "$CHECKSUM" | tr '[:upper:]' '[:lower:]')"`;要求 `actual_size` 等于 `sizeInBytes` 且 `actual_md5` 等于 `expected_md5`。
- 校验不匹配时:将该分段标记为失败,保持原始错误私有,不要声称收集完整;`asc analytics download` 拒绝覆盖已有输出,因此将失败分段重试一次到新路径如 `$ASC_ANALYTICS_DIR/segments/$SEGMENT_ID.retry-1.txt.gz`;独立校验重试文件,仅当两项检查都通过时才使用;除非用户批准删除,否则保留原始失败文件;在校验成功前不要解析或分析文件。
- 报告结果:返回简洁摘要,包含所选 processing date 和 granularity 值;reports、instances、expected segments、downloaded segments 和 verified segments 的计数;收集是否完整;失败或缺失的分段 ID(如有),不含签名 URL 或报告行;在当前用户会话适当时给出私有输出目录;不要在公开产物中包含分析值、签名 URL、profile 名称、凭据或原始行;保留已校验文件供用户下一步工作流使用;删除临时目录或任何下载证据前先询问。
适用边界 · 注意事项
- 不要解释、聚合或呈现报告内容——本技能只负责收集和校验,分析应交给单独的工作流。
- 未经明确用户批准不要创建请求,因为创建请求会改变 App Store Connect 状态并需要 Admin 授权 profile。
- 不要删除或替换请求,也不要在校验成功前解析或分析文件。