PWA 转原生应用
PWA 封装工作流程与 API 文档
工作流程概述
封装过程是异步的,遵循以下步骤:
- POST
/wrap– 启动封装过程(立即返回一个草稿 ID) - GET
/draft/{draft_id}– 轮询状态更新,直到完成或失败 - 下载构建 – 完成后,从
download_url下载.zip文件
端点
1. 启动封装过程
POST /wrapper/wrap
启动 PWA 封装过程。 立即返回一个用于追踪进度的草稿 ID。
请求正文
{
"url": "https://example.com",
"bundle_id": "com.example.app",
"team_id": "A1B2C3D4E5",
"auth_redirects": {
"accounts.google.com": "https://example.com/auth/google/callback"
}
}
请求参数
| 字段 | 类型 | 是否必需 | 说明 |
|---|---|---|---|
| url | string (URL) | ✅ 是 | 要封装的 PWA URL |
| bundle_id | string | ✅ 是 | iOS 软件包标识符(com.company.app) |
| team_id | string | ❌ 否 | Apple Developer 团队 ID — 仅用于原生认证 |
| auth_redirects | object | ❌ 否 | 认证重定向路径 — 仅用于原生认证 |
原生认证与 WebView 认证
✅ 在以下情况下提供 team_id 和 auth_redirects:
- 您希望使用 Universal Links 以原生方式处理认证
- 启用设备存储的登录(Google、Facebook 等)
- 更可靠 — 使用 Safari/原生浏览器进行认证
⚠️ 在以下情况下省略 team_id 和 auth_redirects:
- 您希望在 WebView 内进行认证
- 可靠性较低(某些提供商会阻止 WebView 认证)
- 用户体验较差(社交提供商没有存储的登录)
响应示例(201 Created)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"pwa_url": "https://example.com",
"status": "created",
"manifest_url": null,
"project_zip_filename": null,
"build_zip_filename": null,
"download_url": null,
"error_message": null,
"created_at": "2025-11-10T12:00:00Z",
"updated_at": "2025-11-10T12:00:00Z"
}
2. 获取草稿状态
GET /wrapper/draft/{draft_id}
轮询此端点以追踪封装进度。
路径参数
| 参数 | 类型 | 说明 |
|---|---|---|
| draft_id | string (UUID) | 来自 POST /wrap 的草稿 ID |
响应示例(200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"pwa_url": "https://example.com",
"status": "completed",
"manifest_url": "https://example.com/manifest.json",
"project_zip_filename": "550e8400-e29b-41d4-a716-446655440000.zip",
"build_zip_filename": "550e8400-e29b-41d4-a716-446655440000.zip",
"download_url": "https://pwa-ios.aptoide.com/pwa-ios/8.20251013/storage/file/550e8400-e29b-41d4-a716-446655440000.zip",
"error_message": null,
"created_at": "2025-11-10T12:00:00Z",
"updated_at": "2025-11-10T12:05:00Z"
}
状态流程
| 状态 | 说明 |
|---|---|
created | 草稿已创建,封装过程正在启动 |
fetching_manifest | 正在获取并验证 PWA 清单 |
generating_project | 正在生成 Xcode 项目文件 |
building | 正在构建 iOS 应用程序 |
completed | ✅ 构建已完成 — download_url 可用 |
failed | ❌ 过程失败 — 参见 error_message |
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
| id | string | 唯一的草稿标识符 |
| pwa_url | string | 原始 PWA URL |
| status | string | 当前状态 |
| manifest_url | string? | 所获取清单的 URL |
| project_zip_filename | string? | 生成的 Xcode 项目文件名 |
| build_zip_filename | string? | 最终构建的文件名 |
| download_url | string? | 下载 URL(仅在完成时) |
| error_message | string? | 错误详情(仅在失败时) |
| created_at | datetime | 草稿创建时间戳 |
| updated_at | datetime | 最后更新时间戳 |
下载内容
当状态为 completed 时,.zip 包含:
始终包含
-
未签名的
.app(模拟器) 可直接在 iOS 模拟器上运行以进行测试。 -
未签名的
.ipa分发前需要手动签名。 -
Xcode 项目文件夹 使用它来手动签名并发布应用程序。
仅在原生认证(已提供 team_id)时包含
-
OAUTH_SETUP.md设置原生认证和 Universal Links 的说明。 -
apple-app-site-association预配置的文件,需放置于:{base_url}/.well-known/apple-app-site-association
⚠️ 如果_未_配置原生认证,则不包含。
轮询建议
| 参数 | 推荐值 |
|---|---|
| 轮询间隔 | 5–10 秒 |
| 超时 | 20–25 分钟 |
| 典型构建时间 | 3–8 分钟 |
下载后的后续步骤
✅ 使用原生认证(team_id + auth_redirects)
- 解压
.zip - 在模拟器中测试
- 阅读
OAUTH_SETUP.md - 将
apple-app-site-association放置到您的网站上 - 打开 Xcode 项目并配置代码签名
- 在 Xcode 中构建并归档
- 提交到 App Store
⚠️ 不使用原生认证(WebView 认证)
- 解压
.zip - 在模拟器中测试
- 打开 Xcode 项目并配置代码签名
- 在 Xcode 中构建并归档
- 提交到 App Store
重要说明
✅ 要点
- 封装在后台异步运行
- 构建时间:3–8 分钟
download_url仅在 status = completed 时可用- 草稿会被保留以用于历史追踪
⚠️ 重要警告
-
未签名的
.ipa在分发前必须进行签名 -
原生认证需要:
team_idauth_redirects- 正确托管
apple-app-site-association
-
WebView 认证虽然可用,但存在以下问题:
- 用户体验较差
- 社交登录支持不可靠