微信分享去sdk

This commit is contained in:
joywayer
2026-06-30 17:41:10 +08:00
parent c1e51d2183
commit 113b4d4960
7 changed files with 227 additions and 171 deletions
@@ -261,12 +261,11 @@ public enum RemoteAudioHandler {
return // cb daoqi file return
}
// 2. lastUserId daoqi
// `self.User_id = userid;`
VoicePlayer.shared.recordIncomingUser(user)
// 3. VoicePlayer.onFinish mediaTypeAudio bridge
// [weak bridge] bridge onFinish
// 2. VoicePlayer.onFinish mediaTypeAudio bridge
// [weak bridge] bridge onFinish
// onFinish / / play
// payload `finishedUser` / user
// VoicePlayer currentUser user
VoicePlayer.shared.onFinish = { [weak bridge] finishedUser in
Task { @MainActor in
bridge?.call(
@@ -277,7 +276,7 @@ public enum RemoteAudioHandler {
}
}
// 4. AMR
// 3. AMR
let amrData: Data
do {
let (d, _) = try await URLSession.shared.data(from: downloadURL)
@@ -288,7 +287,7 @@ public enum RemoteAudioHandler {
// `if (![[NSFileManager defaultManager] fileExistsAtPath:filename]) return;`
}
// 5. .amr
// 4. .amr
let tempName = VoiceRecorder.currentTimeString()
let docs = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let amrLocal = docs.appendingPathComponent(tempName).appendingPathExtension("amr")
@@ -300,7 +299,7 @@ public enum RemoteAudioHandler {
return
}
// 6. AMR WAV
// 5. AMR WAV
// daoqi tempName + "_AmrToWav.wav"NewRootVC.m:341
let wavLocal = docs
.appendingPathComponent("\(tempName)_AmrToWav")
@@ -317,14 +316,16 @@ public enum RemoteAudioHandler {
transcoded = false
}
// 7. voicePlaying + + gameui_play_voice
// 6. voicePlaying + + gameui_play_voice
// + enabled daoqi
// NewRootVC.m:343-353 if (canbofang) { play + callHandler }
// NewRootVC.m:343-353 if (canbofang) { play + callHandler }
// playerVoicePlayer.play player
// onFinish gameui_stop_voice H5
let canPlay = await VoiceCenter.shared.isEnabled
log.debug("mediaTypeAudio user=\(user, privacy: .public) transcoded=\(transcoded, privacy: .public) canPlay=\(canPlay, privacy: .public)")
if transcoded, canPlay {
do {
try VoicePlayer.shared.play(wavLocal)
try VoicePlayer.shared.play(wavLocal, user: user)
// gameui_play_voice user dict
bridge.call(
"gameui_play_voice",
@@ -337,7 +338,7 @@ public enum RemoteAudioHandler {
}
}
// 8. mediaTypeAudio cb daoqi NewRootVC.m:357****
// 7. mediaTypeAudio cb daoqi NewRootVC.m:357****
// 使 / canbofang=NO return
callback?(.string("Response from mediaTypeAudio"))
}
@@ -2,10 +2,11 @@
// WeChatManager.swift
// ylgamehall
//
// SDK delegate + authorize + share
// WXApiDelegate async/awaitstate UUID
// SDK delegate + authorize
// WXApiDelegate onResp async/awaitstate UUID
//
// Design §8.5msext WXApiManager.m
// + WechatShare.swift
// SDK SendMessageToWXReq OAuth
//
import Foundation
@@ -23,8 +24,6 @@ public final class WeChatManager: NSObject {
/// resolve authorize continuationstate UUID
private var authPending: [String: CheckedContinuation<WXAuthCodePayload, Error>] = [:]
/// resolve share continuationFIFO ID
private var sharePending: [CheckedContinuation<Void, Error>] = []
public override init() {
super.init()
@@ -84,125 +83,6 @@ public final class WeChatManager: NSObject {
return top
}
// MARK: - Share
public enum ShareScene {
case session //
case timeline //
}
/// `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,
thumb: UIImage?, mediaTagName: String? = nil
) {
self.url = url; self.title = title; self.desc = desc
self.thumb = thumb; self.mediaTagName = mediaTagName
}
}
/// 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 messageExt: String
public let mediaTagName: String?
public init(
imageData: Data, thumb: UIImage,
messageExt: String = "", mediaTagName: String? = nil
) {
self.imageData = imageData
self.thumb = thumb
self.messageExt = messageExt
self.mediaTagName = mediaTagName
}
}
/// FIFO ID
public func shareLink(_ link: ShareLink, scene: ShareScene) async throws {
try await withCheckedThrowingContinuation { (cont: CheckedContinuation<Void, Error>) in
sharePending.append(cont)
let media = WXWebpageObject()
media.webpageUrl = link.url
let message = WXMediaMessage()
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
req.message = message
switch scene {
case .session: req.scene = Int32(WXSceneSession.rawValue)
case .timeline: req.scene = Int32(WXSceneTimeline.rawValue)
}
// 1.x: sendReq BOOL SceneDelegate.openURLContexts
// WXApi.handleOpen(url:delegate:WeChatManager.shared) onResp
// ObjC selector +sendReq:Swift send(_:) Req
// +[WXApi sendReq:]
WXApi.send(req)
}
}
/// 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)
let media = WXImageObject()
media.imageData = img.imageData
let message = WXMediaMessage()
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
req.message = message
switch scene {
case .session: req.scene = Int32(WXSceneSession.rawValue)
case .timeline: req.scene = Int32(WXSceneTimeline.rawValue)
}
// ObjC selector +sendReq:Swift send(_:) Req
// +[WXApi sendReq:]
WXApi.send(req)
}
}
// MARK: - Internal: resolve callbacks
fileprivate func resolveAuth(state: String, code: String?, errCode: Int) {
@@ -213,16 +93,6 @@ public final class WeChatManager: NSObject {
cont.resume(throwing: WeChatError.authFailed(errCode))
}
}
fileprivate func resolveShare(errCode: Int) {
guard !sharePending.isEmpty else { return }
let cont = sharePending.removeFirst()
if errCode == 0 {
cont.resume(returning: ())
} else {
cont.resume(throwing: WeChatError.shareFailed(errCode))
}
}
}
// MARK: - WXApiDelegate
@@ -242,11 +112,8 @@ extension WeChatManager: WXApiDelegate {
Task { @MainActor in
Self.shared.resolveAuth(state: state, code: code, errCode: errCode)
}
} else if resp is SendMessageToWXResp {
Task { @MainActor in
Self.shared.resolveShare(errCode: errCode)
}
}
// WechatShare SendMessageToWXResp
}
}
@@ -260,5 +127,4 @@ public struct WXAuthCodePayload: Sendable {
public enum WeChatError: Error, Sendable {
case sdkNotLinked
case authFailed(Int)
case shareFailed(Int)
}
+1 -1
View File
@@ -22,7 +22,7 @@ public final class SharePanel: UIView {
private static let log = Logger(subsystem: "ylgamehall", category: "SharePanel")
private static let panelHeight: CGFloat = 200
private static let panelHeight: CGFloat = 150
private static let buttonSize: CGFloat = 60
private static let animationDuration: TimeInterval = 0.25
+14 -10
View File
@@ -104,16 +104,20 @@ public final class WechatShare: SharePlatform {
// MARK: -
/// title + desc + url UIPasteboard.string
/// "" DouyinShare
/// title + "\n\n" + desc UIPasteboard.string
/// DouyinShare 1:1 url
/// ""
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")
var shareText = ""
if !content.title.isEmpty {
shareText = content.title
}
if !content.desc.isEmpty {
shareText = shareText.isEmpty ? content.desc : "\(shareText)\n\n\(content.desc)"
}
if shareText.isEmpty {
shareText = "来自进贤聚友棋牌的精彩内容分享"
}
UIPasteboard.general.string = shareText
Self.log.debug("WechatShare 链接已复制到剪贴板")
@@ -121,7 +125,7 @@ public final class WechatShare: SharePlatform {
✅ 内容已复制到剪贴板
🎯 分享到好友、群聊或朋友圈步骤:
1️⃣ 打开微信,选择好友、群聊或朋友圈
1️⃣ 打开微信选择好友、群聊或朋友圈
2️⃣ 在输入框长按粘贴内容
3️⃣ 点击发送即可分享
"""