【契约影响】docs/H5-Native-Contract.md §3.1[2]/§3.2[11]
H5 端 sharesuccess 时机改为"调用 friendsShare handler 即立刻发",与
原 msext 行为等价(live path 完全不等 SDK / URL Scheme 回包)。用户
明示有意为之:URL Scheme + 剪贴板路径本就没有可靠回包,乐观策略避免
H5 业务卡住。
3 平台分支严格 1:1 对齐 daoqi msext:
WechatShare(对齐 WechatShareManager shareWithContent)
- type=="2" → 截图 JPEG 0.6 + sendImageData + app icon thumb
- else → 链接分享 sendLinkURL + app icon thumb
- 移除原"远端图"分支(原项目无此分支)
- 新增 appIconImage helper(读 Info.plist CFBundleIcons,对齐
[self getAppIconImage])
QQShare(对齐 QQShareManager shareWithContent + simpleShareToQQFriend)
- type=="2" → 截图 → UIPasteboard.image → 4 URL Scheme fallback
- else → mqqapi://share/to_{fri,qzone}?req_type=1&url=...
&title=...&description=...(webpageUrl 空时 req_type=0)
- 不依赖 QQ SDK(CLAUDE.md ADR-006)
DouyinShare(对齐 DouyinShareManager shareWithContent)
- type=="2" → 截图 → UIPasteboard.image → "立即打开抖音"引导框
- else → title+"\n\n"+desc → UIPasteboard.string → 引导框
双侧空时兜底 "来自进贤聚友棋牌的精彩内容分享"
- 放弃之前的"存相册 + 自动拉起"激进路径,回到原项目"用户主动点"路径
架构调整:
- SharePlatform.share 改 sync fire-and-forget(去 ShareResult 返回)
- ShareCenter.dispatch / SharePanel.show 去 completion 参数
- FriendsShareHandler:解析后先发 responseCallback("sharefriend")
与 sharesuccess({success:"2", type:<sharefriend>}),再异步 dispatch
69 lines
2.5 KiB
Swift
69 lines
2.5 KiB
Swift
//
|
||
// SharePlatform.swift
|
||
// ylgamehall
|
||
//
|
||
// 分享平台抽象 + ShareContent 数据载荷。
|
||
//
|
||
// 策略模式:微信 / QQ / 抖音 各自实现 SharePlatform 协议,由 ShareCenter
|
||
// 按 sharefriend / 用户选择分发。
|
||
//
|
||
// **fire-and-forget 语义**:share 调用即认为分享流程已发起;H5 端的
|
||
// sharesuccess 在 FriendsShareHandler 解析参数后立即触发(与原 msext
|
||
// gameController.m 同款"乐观策略",由用户明示有意为之)。各平台 share()
|
||
// 只负责拉起对应 UI / URL Scheme,不再回传结果。
|
||
//
|
||
// 详见 docs/H5-Native-Implementation-Design.md §8.2 ShareKit。
|
||
//
|
||
|
||
import Foundation
|
||
import UIKit
|
||
|
||
/// 分享内容(H5 → Native 桥的 friendsShare 参数解析后的 Swift 类型)。
|
||
/// 项目默认 SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor 让 struct 也跨 actor 受限;
|
||
/// 标 nonisolated 让 handler 闭包(@Sendable async)可自由构造与传递。
|
||
nonisolated public struct ShareContent: Sendable {
|
||
/// 分享给好友("1")还是朋友圈("2")
|
||
public let sharefriend: String
|
||
/// msext 旧描述:1 微信 / 2 微信 / 3 闲聊。新代码读了但不用(SharePanel 由用户选平台决定)。
|
||
/// 保留字段以维持契约 §3.1 [2]兼容性
|
||
public let sharetype: String
|
||
/// 1 链接 / 2 截图 / 其他 = 按链接处理(原 WechatShareManager 行为,无独立远端图分支)
|
||
public let type: String
|
||
/// 链接 URL
|
||
public let webpageUrl: String
|
||
public let title: String
|
||
public let desc: String
|
||
|
||
public init(
|
||
sharefriend: String,
|
||
sharetype: String,
|
||
type: String,
|
||
webpageUrl: String,
|
||
title: String,
|
||
desc: String
|
||
) {
|
||
self.sharefriend = sharefriend
|
||
self.sharetype = sharetype
|
||
self.type = type
|
||
self.webpageUrl = webpageUrl
|
||
self.title = title
|
||
self.desc = desc
|
||
}
|
||
}
|
||
|
||
/// 分享场景:好友 / 朋友圈(仅微信有意义;QQ / 抖音 暂不区分)。
|
||
public enum ShareScene: Sendable {
|
||
case friend // 微信好友 / QQ 好友
|
||
case timeline // 微信朋友圈 / QQ 空间
|
||
}
|
||
|
||
@MainActor
|
||
public protocol SharePlatform: AnyObject {
|
||
/// 平台唯一标识(用于 log)
|
||
var name: String { get }
|
||
/// 平台 app 是否已安装(用于 SharePanel 按钮灰显)
|
||
var isInstalled: Bool { get }
|
||
/// 拉起分享 UI;fire-and-forget,不回传结果(sharesuccess 已在 handler 层先发)
|
||
func share(_ content: ShareContent, scene: ShareScene)
|
||
}
|