按 msext gameController.m:637-678 字面行为,WechatShare 按 content.type 分发: - type=1 → shareLink(已有) - type=2 → captureScreenshot → JPEG 0.6 + thumb 0.4x → shareImage - type=其它 → downloadRemote(URL) → JPEG 0.9 + thumb 0.4x → shareImage 新增: - ImageProvider.scaledThumb(_:scale:):等价 msext FuncPublic imageByScalingAndCroppingForSize 0.4x 缩放;微信 SDK setThumbImage: 内部再压到 32KB - WeChatManager.ShareImage 结构 + shareImage(_:scene:) 异步包装 (WXImageObject + WXMediaMessage.setThumbImage,FIFO 串行复用 sharePending) 契约:与 type=1 一致,调成功 → sharesuccess 反向 callback(success/cancelled 都发);errCode=-2 → cancelled;其它 errCode → failed。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
92 lines
3.3 KiB
Swift
92 lines
3.3 KiB
Swift
//
|
||
// WechatShare.swift
|
||
// ylgamehall
|
||
//
|
||
// 微信分享 SharePlatform 实现。
|
||
//
|
||
// ⚠️ canImport(WechatOpenSDK) 守卫:SDK 未链接前 isInstalled = true / share = .success
|
||
// 让 SharePanel 按钮可点;项目方在 Xcode Embed & Sign 后真实路径激活。
|
||
//
|
||
|
||
import Foundation
|
||
import UIKit
|
||
|
||
#if canImport(WechatOpenSDK)
|
||
import WechatOpenSDK
|
||
#endif
|
||
|
||
@MainActor
|
||
public final class WechatShare: SharePlatform {
|
||
|
||
public static let shared = WechatShare()
|
||
|
||
public let name = "WeChat"
|
||
|
||
public var isInstalled: Bool {
|
||
#if canImport(WechatOpenSDK)
|
||
return WXApi.isWXAppInstalled()
|
||
#else
|
||
return true // 未链接 SDK 时让按钮可点,share 也只是 stub success
|
||
#endif
|
||
}
|
||
|
||
public init() {}
|
||
|
||
public func share(_ content: ShareContent, scene: ShareScene) async -> ShareResult {
|
||
#if canImport(WechatOpenSDK)
|
||
guard WXApi.isWXAppInstalled() else {
|
||
return .notInstalled(platform: name)
|
||
}
|
||
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 = ImageProvider.scaledThumb(shot)
|
||
try await WeChatManager.shared.shareImage(
|
||
.init(imageData: imageData, thumb: thumb),
|
||
scene: wxScene
|
||
)
|
||
default:
|
||
// 远端图分享(msext gameController.m:659-680:type 是其它值就当 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
|
||
)
|
||
}
|
||
return .success
|
||
} catch let WeChatError.shareFailed(errCode) {
|
||
if errCode == -2 { return .cancelled }
|
||
return .failed(reason: "WeChat errCode \(errCode)")
|
||
} catch {
|
||
return .failed(reason: "\(error)")
|
||
}
|
||
#else
|
||
// SDK 未链接:维持 Phase 4.B 的 stub 行为(让 SharePanel 流程能跑通)
|
||
return .success
|
||
#endif
|
||
}
|
||
}
|