feat: add WeChat sharing and invite flow

This commit is contained in:
2026-07-07 16:53:39 +08:00
parent f1937e23d4
commit a80c181bd7
160 changed files with 7557 additions and 849 deletions
+89
View File
@@ -0,0 +1,89 @@
//
// WeChatManager.swift
// suixinkan
//
import Foundation
import WechatOpenSDK
/// 微信 SDK 生命周期与回调管理,负责注册、URL/Universal Link 回跳及分享结果分发。
@MainActor
final class WeChatManager: NSObject {
static let shared = WeChatManager()
/// 最近一次分享结果,便于调试或 UI 状态读取。
private(set) var lastShareResult: WeChatShareResult?
private var shareCompletion: ((WeChatShareResult) -> Void)?
private var isRegistered = false
private override init() {
super.init()
}
/// 向微信注册 AppID 与 Universal Link,应用启动时调用。
func registerIfNeeded() {
guard !isRegistered else { return }
guard WeChatConfig.validateUniversalLink(WeChatConfig.universalLink) else {
assertionFailure("WeChat Universal Link must use https and end with /")
return
}
isRegistered = WXApi.registerApp(WeChatConfig.appID, universalLink: WeChatConfig.universalLink)
}
/// 处理 URL Scheme 回调。
@discardableResult
func handleOpenURL(_ url: URL) -> Bool {
WXApi.handleOpen(url, delegate: self)
}
/// 处理 Universal Link 回调。
@discardableResult
func handleContinueUserActivity(_ userActivity: NSUserActivity) -> Bool {
WXApi.handleOpenUniversalLink(userActivity, delegate: self)
}
/// 发送分享请求到微信。
func sendShareRequest(_ request: SendMessageToWXReq, completion: ((WeChatShareResult) -> Void)? = nil) {
guard WXApi.isWXAppInstalled() else {
completion?(.notInstalled)
return
}
guard WXApi.isWXAppSupport() else {
completion?(.unsupported)
return
}
if let completion {
shareCompletion = completion
}
WXApi.send(request) { [weak self] success in
guard !success else { return }
Task { @MainActor in
self?.finishShare(with: .sendFailed(-1))
}
}
}
private func finishShare(with result: WeChatShareResult) {
lastShareResult = result
shareCompletion?(result)
shareCompletion = nil
}
}
extension WeChatManager: WXApiDelegate {
nonisolated func onReq(_ req: BaseReq) {
// 分享模块暂不处理来自微信的主动请求。
}
nonisolated func onResp(_ resp: BaseResp) {
guard let shareResp = resp as? SendMessageToWXResp else { return }
let result = WeChatShareResult.fromWXErrorCode(shareResp.errCode)
Task { @MainActor in
WeChatManager.shared.finishShare(with: result)
}
}
}