mcpField
A
add-app-clip

add-app-clip

github.com/expo开发3.5k7.8k 次安装今天更新
代码仓库

关于 add-app-clip

该技能指导 Expo 开发者为现有 Expo 项目添加 iOS App Clip,并配置关联域名、AASA 文件、商店元数据及 TestFlight 发布流程。

主要功能

  1. 01创建 App Clip target
  2. 02配置关联域名与 AASA 文件
  3. 03设置 Smart App Banner
  4. 04准备 TestFlight 构建与提交
  5. 05配置 App Clip 商店元数据

适用场景

  1. 01为 Expo 应用添加可由网页链接启动的 App Clip
  2. 02设置 App Clip 与主应用的域名关联
  3. 03构建并提交包含 App Clip 的 TestFlight 版本

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/expo/skills --skill add-app-clip

安装后在 Claude Code 中输入/add-app-clip确认已加载。

附带文件agents/openai.yamlreferences/native-module.md

详细介绍

向 Expo 应用添加 App Clip

向 Expo 项目添加 iOS App Clip 目标。Clip 位于 targets/clip/,与父应用一同发布,并通过 Apple App Site Association(AASA)文件,从应用域名上的 URL 启动。

父应用的 bundle ID 会变为 com.<username>.<app-name>,Clip 的 bundle ID 则会自动派生为 <parent>.clip(例如,com.bacon.may20.clip)。

1. 设置 bundleIdentifier 和 appleTeamId

如果缺少这些配置,bun create target 会发出警告。在 app.json 中添加:

{
  "expo": {
    "ios": {
      "bundleIdentifier": "com.<username>.<app-name>",
      "appleTeamId": "XX57RJ5UTD"
    }
  }
}

2. 添加 App Clip 目标

bun create target clip

这会安装 @bacons/apple-targets,将其添加到 app.json 的 plugins 数组中,并写入:

  • targets/clip/expo-target.config.js — 该目标的配置插件
  • targets/clip/Info.plist — Clip 的 Info.plist
  • targets/clip/AppDelegate.swift、Assets.xcassets 等

选择一个合适的图标,或复用应用中已有的图标 — 使用 bunx expo config 检查 icon 或 ios.icon 键。

3. 配置关联域名

父应用和 Clip 都需要设置 Associated Domains 权限,指向托管 AASA 文件的域名。

在 app.json 中添加 applinks:(父应用)和 appclips:(Clip 启动)条目:

{
  "expo": {
    "ios": {
      "associatedDomains": [
        "applinks:may20.expo.app",
        "appclips:may20.expo.app"
      ]
    }
  }
}

在 targets/clip/expo-target.config.js 中声明 Clip 的权限:

/** @type {import('@bacons/apple-targets/app.plugin').ConfigFunction} */
module.exports = (config) => ({
  type: "clip",
  icon: "https://github.com/expo.png",
  entitlements: {
    "com.apple.developer.associated-domains": ["appclips:may20.expo.app"],
  },
});

如果跳过此步骤,expo prebuild 会打印:Apple App Clip may require the associated domains entitlement but none were found。

4. 注册 bundle ID 并创建 App Store 条目

bunx setup-safari

这会登录 Apple Developer 账户,注册 com.bacon.may20,创建 App Store Connect 条目,并打印:

  • 初始版 apple-app-site-association JSON
  • 包含 iTunes 应用 ID 的 <meta name="apple-itunes-app"> 标签
  • Team ID、iTunes ID 和 Bundle ID

5. 托管 AASA 文件

当 iOS 获取 https://<your-domain>/.well-known/apple-app-site-association 并找到匹配的 appclips 条目时,App Clip 就可以启动。

mkdir -p public/.well-known
touch public/.well-known/apple-app-site-association

粘贴 setup-safari 打印的 JSON,但还要添加一个 appclips 区块,填写 Clip 的完整应用 ID(<TeamID>.<ClipBundleID>)。setup-safari 的输出仅包含父应用:

{
  "applinks": {
    "details": [
      {
        "appIDs": ["XX57RJ5UTD.com.bacon.may20"],
        "components": [{ "/": "*", "comment": "Matches all routes" }]
      }
    ]
  },
  "appclips": {
    "apps": ["XX57RJ5UTD.com.bacon.may20.clip"]
  },
  "activitycontinuation": {
    "apps": ["XX57RJ5UTD.com.bacon.may20"]
  },
  "webcredentials": {
    "apps": ["XX57RJ5UTD.com.bacon.may20"]
  }
}

注意:

  • 此文件没有扩展名,且无需满足任何特定的 Content-Type 要求,只需按原样提供即可。Expo Router 静态导出会原样提供 public/ 中的文件。
  • appclips 区块用于通过域名上的 URL 启动 Clip。
  • webcredentials 用于在网站、父应用和 App Clip 之间共享凭据。
  • activitycontinuation 是可选项,用于在移动设备和桌面设备之间共享链接。必须与 expo-router 的 Head 配合使用 — 参见 https://docs.expo.dev/router/advanced/apple-handoff/
  • 表示法和路由禁用详情:https://sosumi.ai/documentation/xcode/supporting-associated-domains

6. 添加 Smart App Banner 元标签

创建 src/app/+html.tsx(Expo Router 的 HTML 外壳),并添加 setup-safari 提供的标签。如果版本化模板不存在,则创建一个:

bunx expo customize src/app/+html.tsx

将元标签添加到 <head> 中:

import { ScrollViewStyleReset } from "expo-router/html";

export default function Root({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="apple-itunes-app" content="app-id=6771566491" />
        <ScrollViewStyleReset />
      </head>
      <body>{children}</body>
    </html>
  );
}

若要让网站显示 App Clip 卡片,而不是安装卡片,请使用:

<meta
  name="apple-itunes-app"
  content="app-id=6771566491, app-clip-bundle-id=com.bacon.may20.clip, app-clip-display=card"
/>

7. 部署网站

在 iOS 信任此关联之前,AASA 文件必须先上线。使用 EAS Hosting:

bunx expo export -p web
eas deploy --prod

这会发布网站(包括 /.well-known/apple-app-site-association),地址为 https://<slug>.expo.app。验证:

curl https://may20.expo.app/.well-known/apple-app-site-association

8. 镜像权限

预构建后检查父应用的权限:

npx expo config --type introspect

查看 infoPlist 对象 — 将其中的权限键镜像到 App Clip 的 Info.plist 中,以便在 Clip 中使用相应的 API。

在 Clip 的目标配置中设置 deploymentTarget: "17.6" — 在 iOS 17.6 中,App Clips 的最低体积限制更高。

如果应用使用推送通知或定位服务,请在 App Clip 的 Info.plist 中添加相应配置,以请求必要权限:

<key>NSAppClip</key>
<dict>
  <key>NSAppClipRequestEphemeralUserNotification</key>
  <false/>
  <key>NSAppClipRequestLocationConfirmation</key>
  <true/>
</dict>

9. 构建并提交到 TestFlight

bunx testflight

这将:

  1. 如果缺少 eas.json,则生成该文件。
  2. 为两个目标(主应用 + Clip)设置凭据。每个目标都有自己的配置描述文件,但可以共用一个分发证书。
  3. 同步功能配置 — 注意 Clip 目标的 Enabled: Associated Domains。
  4. 构建、上传并安排 TestFlight 提交。

10. 配置 App Clip 元数据

将现有 App Store 元数据拉取到本地:

eas metadata:pull

在 store.config.json 中添加 apple.appClip。最多可设置 3 个调用 URL,以便从网页启动 Clip:

{
  "configVersion": 0,
  "apple": {
    "appClip": {
      "defaultExperience": {
        "action": "PLAY",
        "releaseWithAppStoreVersion": true,
        "reviewDetail": {
          "invocationUrls": ["https://may20.expo.app/", null, null]
        },
        "info": {
          "en-US": {
            "subtitle": "Instantly native with Expo",
            "headerImage": "store/apple/app-clip/en-US/asc-app-clip.png"
          }
        }
      }
    }
  }
}

headerImage 必须是 1800x1200 的 PNG,且不能带透明度。

推送回商店:

eas metadata:push

Apple 推荐的 App Clip 元数据指南:https://sosumi.ai/documentation/appclip/configuring-the-launch-experience-of-your-app-clip

你将获得

  • 主应用目标:com.bacon.may20
  • App Clip 目标:com.bacon.may20.clip,位于 targets/clip/
  • 托管于 https://may20.expo.app/.well-known/apple-app-site-association 的 AASA
  • 每个网页路由上都有 Smart App Banner 元标签
  • 每个路由都链接到其原生对应项
  • 内嵌 Clip 的主应用 TestFlight 构建版本

当 Apple 从该域名中的 URL 调用 Clip 后,iOS 会打开 targets/clip/ 的入口点并加载 React Native 应用。

原生检测(可选)

若要让 JS 检测当前是否在 App Clip 中运行,并显示安装完整应用的提示,请创建本地 Expo 模块(bunx create-expo-module --local),以开放 navigator.appClip.prompt()。

Swift 模块、TypeScript 接口和用法请参阅 ./references/native-module.md。

参考资料

  • ./references/native-module.md — 用于检测 App Clip 上下文并显示 SKOverlay 安装提示的本地 Expo 模块

评论

支持 Markdown