4.B 分享逻辑对齐 daoqi msext:调用即触发 sharesuccess

【契约影响】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
This commit is contained in:
joywayer
2026-06-24 07:34:03 +08:00
parent d471393806
commit 9bd5a81e6c
7 changed files with 259 additions and 219 deletions
+52 -51
View File
@@ -2,17 +2,20 @@
// WechatShare.swift
// ylgamehall
//
// SharePlatform
// SharePlatform 1:1 daoqi msext WechatShareManager
// `shareWithContent:completion:`
// - type == "2" getImageWithFullScreenshot + JPEG 0.6 + sendImageData
// - else sendLinkURL + webpageUrl + title + desc
//
// canImport(WechatOpenSDK) SDK isInstalled = true / share = .success
// SharePanel Xcode Embed & Sign
// app icon `[self getAppIconImage]` sharelogo
//
// fire-and-forgetH5 sharesuccess FriendsShareHandler
// dispatch_after 1s completion(YES)
//
import Foundation
import UIKit
// SDK 1.8.2 Bridging Header import
@MainActor
public final class WechatShare: SharePlatform {
@@ -26,55 +29,53 @@ public final class WechatShare: SharePlatform {
public init() {}
public func share(_ content: ShareContent, scene: ShareScene) async -> ShareResult {
guard WXApi.isWXAppInstalled() else {
return .notInstalled(platform: name)
}
public func share(_ content: ShareContent, scene: ShareScene) {
guard WXApi.isWXAppInstalled() else { return }
let wxScene: WeChatManager.ShareScene = (scene == .timeline) ? .timeline : .session
do {
switch content.type {
case "1":
// msext gameController.m:613-635
try await WeChatManager.shared.shareLink(
.init(
url: content.webpageUrl,
title: content.title,
desc: content.desc,
thumbnailURL: nil
),
scene: wxScene
)
case "2":
// msext gameController.m:637-658
let shot = try ImageProvider.captureScreenshot()
guard let imageData = shot.jpegData(compressionQuality: 0.6) else {
return .failed(reason: "screenshot JPEG encode failed")
let thumb = Self.appIconImage()
Task { @MainActor in
do {
if content.type == "2" {
// msext WechatShareManager isScreenshotShare
let shot = try ImageProvider.captureScreenshot()
guard let imageData = shot.jpegData(compressionQuality: 0.6) else { return }
try await WeChatManager.shared.shareImage(
.init(imageData: imageData, thumb: thumb),
scene: wxScene
)
} else {
// msext else type=="1"
try await WeChatManager.shared.shareLink(
.init(
url: content.webpageUrl,
title: content.title,
desc: content.desc,
thumbnailURL: nil
),
scene: wxScene
)
}
let thumb = ImageProvider.scaledThumb(shot)
try await WeChatManager.shared.shareImage(
.init(imageData: imageData, thumb: thumb),
scene: wxScene
)
default:
// msext gameController.m:659-680type URL
let remote = try await ImageProvider.downloadRemote(content.webpageUrl)
// msext data UIImage decode
// jpegData
guard let imageData = remote.jpegData(compressionQuality: 0.9) else {
return .failed(reason: "remote image JPEG encode failed")
}
let thumb = ImageProvider.scaledThumb(remote)
try await WeChatManager.shared.shareImage(
.init(imageData: imageData, thumb: thumb),
scene: wxScene
)
} catch {
// SDK H5 sharesuccess
}
return .success
} catch let WeChatError.shareFailed(errCode) {
if errCode == -2 { return .cancelled }
return .failed(reason: "WeChat errCode \(errCode)")
} catch {
return .failed(reason: "\(error)")
}
}
/// app icon Info.plist `CFBundleIcons` `CFBundlePrimaryIcon`
/// `CFBundleIconFiles` msext
/// WechatShareManager `getAppIconImage` 1x1
private static func appIconImage() -> UIImage {
if let icons = Bundle.main.object(forInfoDictionaryKey: "CFBundleIcons") as? [String: Any],
let primary = icons["CFBundlePrimaryIcon"] as? [String: Any],
let files = primary["CFBundleIconFiles"] as? [String],
let last = files.last,
let icon = UIImage(named: last) {
return icon
}
if let icon = UIImage(named: "AppIcon") { return icon }
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1))
return renderer.image { _ in }
}
}