4.B 截图分享补齐 msext 字段:WeChat description / QQ 引导框

【契约影响】docs/H5-Native-Contract.md §3.1[2]type==2 分支

WeChat 截图分享之前丢了 H5 description(msext 通过
sendImageData:MessageExt: 写到 WXMediaMessage.description,接收方在
微信聊天预览里能看到)。链接分享之前完全没传 thumb(msext 用 app
icon)。统一补齐:

- WeChatManager.ShareImage 加 messageExt / mediaTagName 字段;
  shareImage 内 message.description = messageExt + message.messageExt
  = messageExt + setThumbImage(thumb) + mediaTagName
- WeChatManager.ShareLink 把 thumbnailURL: String? 替换为 thumb:
  UIImage?;shareLink 内 setThumbImage(thumb) + mediaTagName。drop
  Sendable 因 UIImage 不可 Sendable(调用都在 MainActor 上无风险)
- WechatShare 双分支统一传 appIconImage() 做 thumb;截图分支 messageExt
  = content.desc + mediaTagName "进贤聚友棋牌游戏截图分享";链接分支
  mediaTagName "进贤聚友棋牌游戏分享"(字面对齐 msext WechatShareManager.m)

QQ 截图分享原本 4-fallback URL 链不靠谱(file_type=news 给截图场景实际
无意义)。简化为 Douyin 同款模式:截图 → UIPasteboard.image → 弹"立即
打开 QQ / 稍后分享"二选一 Alert。承认 ADR-006 无 QQ SDK 退化的现实,
但 UX 不再让用户摸不着北。
This commit is contained in:
joywayer
2026-06-24 07:53:14 +08:00
parent 9bd5a81e6c
commit 68c668a06c
3 changed files with 109 additions and 34 deletions
@@ -91,27 +91,45 @@ public final class WeChatManager: NSObject {
case timeline //
}
public struct ShareLink: Sendable {
public let url: String
public let title: String
public let desc: String
public let thumbnailURL: String?
/// `mediaTagName` msext WXApiRequestHandler `TagName:`
/// WXMediaMessage.mediaTagName
/// UIImage Sendable 使 MainActor actor
public struct ShareLink {
public let url: String
public let title: String
public let desc: String
public let thumb: UIImage?
public let mediaTagName: String?
public init(url: String, title: String, desc: String, thumbnailURL: String?) {
self.url = url; self.title = title; self.desc = desc; self.thumbnailURL = thumbnailURL
public init(
url: String, title: String, desc: String,
thumb: UIImage?, mediaTagName: String? = nil
) {
self.url = url; self.title = title; self.desc = desc
self.thumb = thumb; self.mediaTagName = mediaTagName
}
}
/// type=2 / type=3
/// imageData JPEG thumb SDK
/// `setThumbImage:` thumb 32KB
/// type=2
/// - `imageData`JPEG
/// - `thumb` SDK `setThumbImage:` 32KB
/// - `messageExt`H5 description `WXMediaMessage.description`
/// `.messageExt` msext `WXApiRequestHandler sendImageData:MessageExt:`
/// - `mediaTagName` msext `TagName:`
public struct ShareImage {
public let imageData: Data
public let thumb: UIImage
public let imageData: Data
public let thumb: UIImage
public let messageExt: String
public let mediaTagName: String?
public init(imageData: Data, thumb: UIImage) {
public init(
imageData: Data, thumb: UIImage,
messageExt: String = "", mediaTagName: String? = nil
) {
self.imageData = imageData
self.thumb = thumb
self.messageExt = messageExt
self.mediaTagName = mediaTagName
}
}
@@ -127,6 +145,12 @@ public final class WeChatManager: NSObject {
message.title = link.title
message.description = link.desc
message.mediaObject = media
if let mediaTagName = link.mediaTagName {
message.mediaTagName = mediaTagName
}
if let thumb = link.thumb {
message.setThumbImage(thumb)
}
let req = SendMessageToWXReq()
req.bText = false
@@ -143,8 +167,11 @@ public final class WeChatManager: NSObject {
}
}
/// FIFO sharePendingmsext gameController.m:637-678
/// type=2 / type= WXImageObject + setThumbImage
/// FIFO sharePending msext WechatShareManager
/// `sendImageData:TagName:MessageExt:Action:ThumbImage:InScene:`
/// TagName mediaTagName
/// MessageExt description+ messageExtSDK
/// ThumbImage setThumbImage
public func shareImage(_ img: ShareImage, scene: ShareScene) async throws {
try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Void, Error>) in
sharePending.append(cont)
@@ -153,9 +180,15 @@ public final class WeChatManager: NSObject {
media.imageData = img.imageData
let message = WXMediaMessage()
// title / descriptionmsext nil
message.description = img.messageExt
message.mediaObject = media
message.setThumbImage(img.thumb)
if !img.messageExt.isEmpty {
message.messageExt = img.messageExt
}
if let mediaTagName = img.mediaTagName {
message.mediaTagName = mediaTagName
}
let req = SendMessageToWXReq()
req.bText = false