// // WechatShare.swift // ylgamehall // // 微信分享 SharePlatform 实现:剪贴板 + 引导框 + `weixin://` URL Scheme, // 与 QQShare / DouyinShare 同款交互模式,**不依赖微信 OpenSDK 的分享 API**。 // // 设计取舍: // - 微信 OpenSDK 的 sendReq 走"专有剪贴板 plist + AppID 后台白名单",与 // QQ / 抖音的"明文 URL Scheme"开放策略不同;为统一三方分享交互体验、 // 减少 SDK 协议变更带来的不稳定,分享路径改走剪贴板 + 手动粘贴。 // - 微信 OpenSDK 二进制依然保留(WeChatSDK.register / WeChatAuth.authorize // 用于登录),仅去掉分享 SDK 调用与 WeChatManager 中的分享桥接。 // - scene 参数(friend / timeline)保留以满足 SharePlatform 协议契约,但 // 剪贴板路径下用户进微信后自行决定粘贴到对话框还是朋友圈,文案统一不分。 // // 两条对外入口对应两个 ViewController 同名 handler 的差异(仅剪贴板内容分支不同): // // • share() — 子游戏路径(gameController.m),2 type 分支: // - type == "2" → 截图:UIPasteboard.image // - else → 链接:UIPasteboard.string // // • shareLobby() — 大厅路径(NewRootVC.m),3 type 分支: // - type == "1" → 链接 // - type == "2" → 截图 // - 其他 → 远端图(下载 → UIPasteboard.image) // // fire-and-forget:H5 端 sharesuccess 已在 FriendsShareHandler 立即触发, // 此处不再回传结果。 // import Foundation import UIKit import os.log @MainActor public final class WechatShare: SharePlatform { public static let shared = WechatShare() private static let log = Logger(subsystem: "ylgamehall", category: "WechatShare") private static let wechatScheme = "weixin://" public let name = "WeChat" public var isInstalled: Bool { guard let url = URL(string: Self.wechatScheme) else { return false } return UIApplication.shared.canOpenURL(url) } public init() {} // MARK: - 子游戏路径(gameController.m) public func share(_ content: ShareContent, scene: ShareScene) { guard isInstalled else { return } if content.type == "2" { shareScreenshot() } else { shareLink(content) } } // MARK: - 大厅路径(NewRootVC.m) public func shareLobby(_ content: ShareContent, scene: ShareScene) { guard isInstalled else { return } switch content.type { case "1": shareLink(content) case "2": shareScreenshot() default: shareRemoteImage(content) } } // MARK: - 截图分享 /// 截图 → UIPasteboard.image → 弹引导框(不自动拉起微信,等用户点"立即打开")。 private func shareScreenshot() { do { let shot = try ImageProvider.captureScreenshot() UIPasteboard.general.image = shot Self.log.debug("WechatShare 截图已复制到剪贴板") } catch { Self.log.error("WechatShare 截图失败 \(error.localizedDescription, privacy: .public)") return } let message = """ ✅ 图片已复制到剪贴板 🎯 分享到好友、群聊或朋友圈步骤: 1️⃣ 打开微信,选择好友、群聊或朋友圈 2️⃣ 在输入框长按粘贴图片 3️⃣ 点击发送即可分享 """ showGuidanceAlert(title: "微信分享准备完成", message: message) } // MARK: - 链接分享 /// title + desc + url 拼字符串 → UIPasteboard.string → 弹引导框。 /// 三字段均空时用兜底文案"来自进贤聚友棋牌的精彩内容分享"(与 DouyinShare 同款策略)。 private func shareLink(_ content: ShareContent) { var parts: [String] = [] if !content.title.isEmpty { parts.append(content.title) } if !content.desc.isEmpty { parts.append(content.desc) } if !content.webpageUrl.isEmpty { parts.append(content.webpageUrl) } let shareText = parts.isEmpty ? "来自进贤聚友棋牌的精彩内容分享" : parts.joined(separator: "\n") UIPasteboard.general.string = shareText Self.log.debug("WechatShare 链接已复制到剪贴板") let message = """ ✅ 内容已复制到剪贴板 🎯 分享到好友、群聊或朋友圈步骤: 1️⃣ 打开微信,选择好友、群聊或朋友圈 2️⃣ 在输入框长按粘贴内容 3️⃣ 点击发送即可分享 """ showGuidanceAlert(title: "微信分享准备完成", message: message) } // MARK: - 远端图分享(大厅 shareLobby 的"其他"分支) /// 下载远端图 → UIPasteboard.image → 弹引导框。对齐 msext NewRootVC.m:526-534 /// "公众号二维码分享"分支:原 SDK 路径直发 NSData,剪贴板路径写入解码后的 /// UIImage 让用户在微信里长按粘贴。 private func shareRemoteImage(_ content: ShareContent) { guard let url = URL(string: content.webpageUrl) else { Self.log.error("WechatShare 远端图 URL 解析失败") return } Task { @MainActor in do { let (data, _) = try await URLSession.shared.data(from: url) guard let image = UIImage(data: data) else { Self.log.error("WechatShare 远端图解码失败") return } UIPasteboard.general.image = image Self.log.debug("WechatShare 远端图已复制到剪贴板") } catch { Self.log.error("WechatShare 远端图下载失败 \(error.localizedDescription, privacy: .public)") return } let message = """ ✅ 图片已复制到剪贴板 🎯 分享到好友、群聊或朋友圈步骤: 1️⃣ 打开微信,选择好友、群聊或朋友圈 2️⃣ 在输入框长按粘贴图片 3️⃣ 点击发送即可分享 """ showGuidanceAlert(title: "微信分享准备完成", message: message) } } // MARK: - 引导弹窗 /// 弹"立即打开微信 / 稍后分享"二选一 Alert,与 QQShare / DouyinShare 同款 UX。 private func showGuidanceAlert(title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "立即打开微信", style: .default) { _ in if let url = URL(string: Self.wechatScheme), UIApplication.shared.canOpenURL(url) { UIApplication.shared.open(url) } }) alert.addAction(UIAlertAction(title: "稍后分享", style: .cancel)) guard let topVC = Self.topViewController() else { return } topVC.present(alert, animated: true) } private static func topViewController() -> UIViewController? { let scene = UIApplication.shared.connectedScenes .compactMap { $0 as? UIWindowScene } .first(where: { $0.activationState == .foregroundActive }) ?? UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.first guard var top = scene?.windows.first(where: \.isKeyWindow)?.rootViewController ?? scene?.windows.first?.rootViewController else { return nil } while let presented = top.presentedViewController { top = presented } if let nav = top as? UINavigationController, let visible = nav.visibleViewController { return visible } return top } }