From b071ced6578b34f525b5d782a6c9a613a180d4e6 Mon Sep 17 00:00:00 2001 From: joywayer Date: Mon, 22 Jun 2026 19:59:00 +0800 Subject: [PATCH] =?UTF-8?q?Phase=204=20=E6=96=B9=E5=90=91=E5=86=8D?= =?UTF-8?q?=E6=AC=A1=E7=BA=A0=E6=AD=A3=EF=BC=9A=E6=92=A4=E9=94=80=20A?= =?UTF-8?q?=EF=BC=8CQQ=20+=20=E6=8A=96=E9=9F=B3=20SharePanel=20=E4=B8=89?= =?UTF-8?q?=E9=80=89=E4=B8=80=E4=B8=8D=E4=BE=9D=20SDK?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 用户提示"原项目还有 QQ 分享、抖音分享"。深度调研发现: 上一轮 A 方向决策 (a6095ef) 错了 — grep 范围之前仅看 NewRootVC.m, 漏了 gameController.m。msext gameController.m:575-597 显示 H5 调 friendsShare 时原生**弹 SharePanel 三选一面板**: sharefriend == 1 → SharePanel.showWithDictionary(微信好友 / QQ / 抖音) sharefriend == 2 → WechatShareManager.shareWithContent(朋友圈) Contract §3.1 [2]旧描述(sharetype=3 闲聊)已被 msext 新代码覆盖; sharetype 字段在新代码里读了但不用。 调研 QQ + 抖音是否需要 SDK: - QQShareManager.m:14: __has_include() 条件编译 + line 716-771 simpleShareToQQFriend URL Scheme fallback (mqqapi://share/to_fri?...) — **不依赖 SDK** - DouyinShareManager.m: 只 import Photos + MobileCoreServices; 全程 URL Scheme(snssdk1128://share/video / camera)+ 保存截图到 相册让用户在抖音里选 — **不依赖 SDK** 撤销 A 决策。新方向(Plan §5 4.2-4.4): - 4.2 SharePanel 三选一面板(msext gameController.m:585 等价行为) - 4.3 QQShare URL Scheme(移植 simpleShareToQQFriend) - 4.4 DouyinShare URL Scheme + Photos - 4.5(原 4.B)微信 SDK 接入(仍需项目方提供 framework + AppID + UL) 文档同步: - Plan §2.3 阻塞表:QQ 改为"不需要 SDK,走 URL Scheme";抖音同款 - Plan §5 Phase 4:4.2 重写为 SharePanel 设计 + 4.3 QQ + 4.4 抖音 + 4.5 微信 - CLAUDE.md 依赖管理段:"不接入 QQ SDK / 也不接入抖音 SDK", 含 LSApplicationQueriesSchemes + NSPhotoLibraryAddUsageDescription 说明 - Verification-Checklist L/M/N 章节:SharePanel + QQ + 抖音验证项 - Plan §6.4 里程碑加纠正记录(标 a6095ef 已撤销) 下一步:代码实施 4.B SharePlatform 协议 + SharePanel UI + ShareCenter 分发。 Co-Authored-By: Claude Opus 4.7 --- CLAUDE.md | 2 +- docs/Development-Plan.md | 27 +++++++++++++++++++++------ docs/Verification-Checklist.md | 23 +++++++++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index b09590a..938e68d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -128,7 +128,7 @@ daoqi 仓库当前并存两条工作线: - **首选 SPM**:开源 / 官方提供 Swift Package 的库(Sentry / ZIPFoundation / 七牛 `https://github.com/qiniu/objc-sdk` v8.9.x 等) - **Vendor `.xcframework` 手动**:所有闭源二进制(微信 / 高德 AMap / opencore-amr 等),按 Design §14.1「Vendor 接入标准流程」放 `Vendor//` + Target → General → Frameworks 加入 + `Vendor//README.md` 记录版本与来源 -- **不接入 QQ SDK / 也不实现 QQ 分享**:Contract §3.1 [2]`friendsShare.sharetype` 取值仅 "1"/"2"=微信 / "3"=闲聊,**无 QQ 选项**。msext 的 QQShareManager 只服务于原生 SharePanel(独立功能,不接 H5 桥)。新外壳契约不变 → H5 桥不实现 QQ 分享。如未来需 QQ 入口(原生 SharePanel-like),可走 URL Scheme 方案(`mqqapi://share/to_fri?...`,参 msext `QQShareManager.m:14` `__has_include` fallback)—— 但**不会触发 H5 桥 sharesuccess**,是独立于契约的另一条路径 +- **不接入 QQ SDK / 也不接入抖音 SDK**:H5 调 `friendsShare(sharefriend=1, ...)` 时原生弹 SharePanel 三选一(微信好友 / QQ / 抖音,参 msext `gameController.m:585`)。QQ 走 URL Scheme(`mqqapi://share/to_fri?...`,参 msext `QQShareManager.m:14` `__has_include` fallback),抖音走 URL Scheme + Photos(`snssdk1128://share/video` + 保存截图到相册让用户在抖音里选,参 msext `DouyinShareManager.m`)。两者都无 SDK 依赖,Info.plist 仅需 `LSApplicationQueriesSchemes`(`mqq` / `mqqapi` / `mqqopensdkfriend` / `snssdk1128`)+ `NSPhotoLibraryAddUsageDescription`(抖音需要写入相册) - **禁止 CocoaPods**:项目内不放 `Podfile` / `Podfile.lock` / `Pods/` / `.xcworkspace`。工程入口固定为 `ylgamehall.xcodeproj` - **新增第三方依赖时**:按 SPM → Vendor 顺序尝试,PR 描述写明选型理由;若发现某 SDK 既无 SPM 又无 XCFramework,回到 ADR-006 决策框架重新评估 diff --git a/docs/Development-Plan.md b/docs/Development-Plan.md index d7747ab..28fa378 100644 --- a/docs/Development-Plan.md +++ b/docs/Development-Plan.md @@ -62,7 +62,8 @@ Contract Design Plan(本文档) | 11 个渠道注入目录的目录名值 | 渠道 / 游戏 ID / 七牛域名 / market 等 | Phase 1 | 项目方/运营 | | 微信 OpenSDK `.framework` | 登录 / 分享 | Phase 4 | 项目方(可从 msext/Vendor 拷贝) | | 微信 AppID(`wx586a9b321e56efb7`)+ Universal Links 配置 | 微信回调 | Phase 4 | 项目方 | -| ~~QQ OpenSDK `.framework` + AppID~~ | ~~QQ 分享~~ | **不需要** — Contract §3.1 [2]`friendsShare` 的 `sharetype` 取值仅 "1"/"2"=微信 / "3"=闲聊,**没有 QQ 选项**。msext 里 QQShareManager 只服务于原生 SharePanel(独立功能),不接 H5 桥。新外壳契约不变 → 不实现 QQ 分享。grep 验证:msext `NewRootVC.m` / `gameController.m` 全文未引用 QQShareManager | — | +| ~~QQ OpenSDK `.framework`~~ | QQ 分享 | **不需要 SDK** — msext `QQShareManager.m:14` `__has_include` fallback 路径已有完整 URL Scheme 实现(`mqqapi://share/to_fri?...`),新外壳直接照搬即可。Info.plist 仅需加 `LSApplicationQueriesSchemes`(`mqq` / `mqqapi` / `mqqopensdkfriend` 等) | — | +| ~~抖音 OpenSDK `.framework`~~ | 抖音分享 | **不需要 SDK** — msext `DouyinShareManager.m` 全程 URL Scheme(`snssdk1128://share/video` / `snssdk1128://camera`)+ Photos 框架(保存图片到相册让用户在抖音里选)。Info.plist 仅需加 `LSApplicationQueriesSchemes`(`snssdk1128`)+ `NSPhotoLibraryAddUsageDescription` 写入相册权限文案 | — | | 后台 `/wechat/login` 中转接口 | secret 不入 IPA 的前提 | Phase 4 | 后台团队 | | 高德地图 `APIKey` + SDK XCFramework | 定位 | Phase 5 | 已有 key `b0d4a8e3fcbbcc0dd96283b7df6a4494`(但绑死 msext Bundle ID,需用新 Bundle ID 重新申请);SDK 走 Vendor 手动接入(ADR-006),下载页 https://lbs.amap.com/api/ios-location-sdk/download | | 七牛上传 token 颁发接口 | 录音上传 | Phase 3 | 后台团队 | @@ -467,7 +468,8 @@ Contract Design Plan(本文档) #### 前置 - Phase 1 完成 - ⏳ 微信 OpenSDK `.framework` + AppID + Universal Links -- ✗ ~~QQ OpenSDK~~ **不需要**:QQ 分享走 URL Scheme 路径(msext `QQShareManager.m` 已实现的 fallback),无 SDK 无 AppID 验证 +- ✗ ~~QQ OpenSDK~~ **不需要**:URL Scheme(参 msext `QQShareManager.m:14` `__has_include` fallback) +- ✗ ~~抖音 OpenSDK~~ **不需要**:URL Scheme + Photos 框架(参 msext `DouyinShareManager.m` 全程无 SDK) - ⏳ 后台 `/wechat/login` 接口(或先用客户端直拼 fallback) #### 任务清单 @@ -477,9 +479,21 @@ Contract Design Plan(本文档) - [ ] **4.1** `Vendor/WechatSDK/` 拷贝微信 SDK - Info.plist 加 URL Scheme(`wx586a9b321e56efb7`)+ `LSApplicationQueriesSchemes`(`weixin` / `weixinULAPI` / `weixinURLParamsAPI`) - Entitlement 加 Associated Domains(Universal Links) -- ✗ ~~**4.2** QQ 分享~~ **不实施**(按 A 方向最终决策) - - **理由**:H5 桥契约 §3.1 [2]`friendsShare.sharetype` 取值仅 "1"/"2"=微信 / "3"=闲聊,**无 QQ 选项**。msext 的 QQShareManager 只接原生 SharePanel(独立功能),不接 H5 桥。新外壳契约不变 → 不实现 QQ 分享 - - **保留路径**:未来项目方如确需 QQ 入口(如原生 SharePanel-like 触发),可参 msext `QQShareManager.m:14` `__has_include` fallback(URL Scheme `mqqapi://share/to_fri?` 直接调起),无需 SDK 无需 AppID。但**不会触发 H5 桥 `sharesuccess`**——这与契约无关,是另一条独立路径 +- [ ] **4.2** **SharePanel 三选一面板(msext gameController.m:585 等价行为)** + - **关键发现**:msext `gameController.m:575-597` 表明 H5 调 `friendsShare` 时: + - `sharefriend == 1`(好友/私聊)→ 弹 **SharePanel 三选一面板**(微信好友 + QQ + 抖音) + - `sharefriend == 2`(朋友圈)→ 直接 `WechatShareManager.shareWithContent`(朋友圈) + - Contract §3.1 [2]旧描述(sharetype=3 闲聊)已被 msext 新代码覆盖;`sharetype` 字段在新代码里读了但不用 + - 新外壳按 SharePanel 模式实现,不依赖 Contract 旧描述 +- [ ] **4.3** **QQ 分享走 URL Scheme,不依赖 SDK** + - 移植 msext `QQShareManager.m:716-771` `simpleShareToQQFriend` 简化版 + - URL 构造:`mqqapi://share/to_fri?version=1&cflag=0&req_type=1&url=...&title=...&description=...` + - `canOpenURL` 检查 + `openURL` 异步打开 +- [ ] **4.4** **抖音分享走 URL Scheme + Photos,不依赖 SDK** + - 移植 msext `DouyinShareManager.m` 简化版 + - URL Scheme:`snssdk1128://share/video` / `snssdk1128://camera` + - Photos:保存截图到相册让用户在抖音 app 里选取(H5 截图 / 远端图共用此路径) + - Info.plist 加 `NSPhotoLibraryAddUsageDescription` 写入权限文案 - [ ] **4.3** `Source/SDK/WeChat/WeChatSDK.swift` 启动注册(Design §4.2 `registerFull` + 全部 12 个 `MMAPP_SUPPORT_*` flag) - [ ] **4.4** `Source/SDK/WeChat/WeChatManager.swift`(@MainActor) - 持久 delegate @@ -786,7 +800,8 @@ H5 调 `OpenurlTitleData` 打开弹层 WebView,弹层内 H5 用 `window.settin | 2026-06-22 | 新增 `docs/Verification-Checklist.md` 功能验证清单:累积各 Phase 验证步骤、不在 Phase 进行中频繁验证、完成后统一跑。与 Contract §10 契约边界保持独立 | `b2ee1b3` | | 2026-06-22 | Phase 3.A srcIsloop 本地音频 + 3.B/C/D RemoteAudio stub。AudioPlayer @MainActor 实现 playOnce/loopBackground/stopBackground 三方法与 msext 等价 | `0602b9d` | | 2026-06-22 | **Phase 4.A 登录+分享 stub + QQ 改走 URL Scheme 不依 SDK**:AccreditLoginHandler + FriendsShareHandler stub;Plan §2.3 阻塞表去掉 QQ SDK | `aa80aec` | -| 2026-06-22 | **Phase 4 方向最终决策(A)**:grep msext NewRootVC.m / gameController.m 未发现 QQShareManager 引用 — Contract §3.1 [2] `sharetype` 取值仅"1"/"2"=微信 / "3"=闲聊无 QQ;msext 的 QQShareManager 只接原生 SharePanel(独立功能不接 H5 桥)。新外壳契约不变 → 不实现 QQ 分享。Plan §2.3 + §5 4.2 + CLAUDE.md + Verification-Checklist 同步调整为"不实施"+ 保留 URL Scheme 备用知识库 | 本次 commit | +| 2026-06-22 | **Phase 4 方向最终决策(A)**:grep msext NewRootVC.m / gameController.m 未发现 QQShareManager 引用 — Contract §3.1 [2] `sharetype` 取值仅"1"/"2"=微信 / "3"=闲聊无 QQ;msext 的 QQShareManager 只接原生 SharePanel(独立功能不接 H5 桥)。新外壳契约不变 → 不实现 QQ 分享 | `a6095ef`(**已被下一行撤销**) | +| 2026-06-22 | **Phase 4 方向再次纠正**:用户提示"原项目还有 QQ 分享、抖音分享"。深度调研发现 grep 范围之前不够 — msext `gameController.m:575-597`(不是 NewRootVC)显示 H5 调 `friendsShare(sharefriend=1)` 时原生**弹 SharePanel 三选一面板**(微信好友 / QQ / 抖音);Contract §3.1 [2]旧描述(sharetype=3 闲聊)已被 msext 新代码覆盖(sharetype 字段读了但不用)。QQ + 抖音都不依赖 SDK:QQ 走 URL Scheme(`QQShareManager.m:14` `__has_include` fallback),抖音走 URL Scheme + Photos(`DouyinShareManager.m` 全程无 SDK)。撤销 A 决策,新方向:Phase 4.2 SharePanel + 4.3 QQ URL Scheme + 4.4 抖音 URL Scheme | 本次 commit | > **§3.4.1 撤销说明**:早期 commit `82bad8a` 实现的 `window.settings.getXxx()` polyfill 已撤销 — Contract §附录 A 自身明示「iOS<9 路径,新外壳如最低系统 ≥ iOS 14 可不实现」,本项目最低 iOS 15.6 → polyfill 路径未启用,H5 用 §7.5 的 `app_*.js` 文件路径作为唯一主路径。详细缘由见 Design §3.4.1(撤销说明)和 CLAUDE.md「典型案例」段。 diff --git a/docs/Verification-Checklist.md b/docs/Verification-Checklist.md index 0402f37..adcfd26 100644 --- a/docs/Verification-Checklist.md +++ b/docs/Verification-Checklist.md @@ -185,11 +185,26 @@ H5 需先用 `bridge.registerHandler('callbackName', fn)` 注册: > - sharesuccess({success:"2", type:"1"/"2"}) > - app 切到后台微信授权 → 切回 app sharelogin 触发 -### L. ~~QQ URL Scheme 分享~~(不实施,按 A 方向最终决策) +### L. SharePanel 三选一面板(4.B 待实现) -> Contract §3.1 [2]`sharetype` 取值仅 "1"/"2"=微信 / "3"=闲聊,无 QQ 选项。 -> msext 的 QQShareManager 只服务于原生 SharePanel,不接 H5 桥。新外壳契约 -> 不变 → 不实现 QQ 分享,无需验证。 +> H5 调 friendsShare(sharefriend=1) → 弹 SharePanel 让用户选微信好友 / QQ / 抖音 +> 实施后填充验证项: +> - 三个按钮点击响应正确(dismiss 后再触发对应平台分享) +> - 半透明背景点击关闭面板 + +### M. QQ URL Scheme 分享(4.C 待实现,**不依赖 SDK**) + +> 移植 msext QQShareManager.m simpleShareToQQFriend 后填充: +> - QQ 已安装:`mqqapi://share/to_fri?...` 调起 QQ app 分享链接 +> - QQ 未安装:H5 alert 提示"未安装 QQ" +> - 调起即视为 success(URL Scheme 单向无返回,乐观策略) + +### N. 抖音 URL Scheme + Photos 分享(4.D 待实现,**不依赖 SDK**) + +> 移植 msext DouyinShareManager.m 后填充: +> - 抖音已安装:保存截图到相册 + `snssdk1128://share/video` 调起抖音 +> - 抖音未安装:H5 alert 提示"未安装抖音" +> - Info.plist 已配 NSPhotoLibraryAddUsageDescription 写入相册权限 ---