修复微信授权无响应:authorize 改用 sendAuthReq:viewController:delegate:

H5 调 accreditlogin 后无反应。对照 daoqi msext 找到根因:

msext NewRootVC.m → WXApiRequestHandler.m:sendAuthRequestScope: 用的是
`[WXApi sendAuthReq:req viewController:vc delegate:[WXApiManager sharedManager]]`
(新版 SDK 2.x 推荐路径,传 viewController + delegate)。

而 ylgamehall 之前用 `WXApi.send(req)`——旧版 1.x 方法,新版头里已无声明,
不传 viewController(SDK 无法弹起微信 modal context)+ 不传 delegate
(SDK 不知道往哪发回包)= H5 调了无反应。

修复:
- authorize:改用 `WXApi.sendAuthReq(_:viewController:delegate:completion:)`,
  传当前最顶层 VC(新增 topmostViewController() helper:connectedScenes →
  foregroundActive windowScene → keyWindow.rootVC → 穿过 presented / nav.visible)
  + self(WXApiDelegate)。completion 处理拉起失败立即 fail continuation。
- shareLink / shareImage:从旧 send 改新 `WXApi.send(_:completion:)`
  (sendReq:completion: 的 Swift 桥名)。分享回包仍由 SceneDelegate
  openURL → WXApi.handleOpen(url:delegate:WeChatManager.shared) → onResp
  路径接收,不需要在 send 时再传 delegate。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
joywayer
2026-06-23 07:33:58 +08:00
co-authored by Claude Opus 4.7
parent be09e6e697
commit 624dd93c65
@@ -34,8 +34,12 @@ public final class WeChatManager: NSObject {
// MARK: - Authorize // MARK: - Authorize
/// msext state = "wechat_sdk" + scope = 4 /// msext NewRootVC.m WXApiRequestHandler.m
/// code WeChatAuth.exchangeForUser 7 /// SDK 2.x `sendAuthReq:viewController:delegate:completion:`
/// - viewController = SDK present SDK
/// - delegate = SDK WXApiDelegate.onResp SceneDelegate
/// openURL SDK delegate
/// 1.x `WXApi.send(req)` deprecated vc/delegate H5
public func authorize() async throws -> WXAuthCodePayload { public func authorize() async throws -> WXAuthCodePayload {
#if canImport(WechatOpenSDK) #if canImport(WechatOpenSDK)
let state = UUID().uuidString let state = UUID().uuidString
@@ -44,13 +48,51 @@ public final class WeChatManager: NSObject {
let req = SendAuthReq() let req = SendAuthReq()
req.scope = Self.authScope req.scope = Self.authScope
req.state = state req.state = state
WXApi.send(req)
guard let vc = Self.topmostViewController() else {
authPending.removeValue(forKey: state)
cont.resume(throwing: WeChatError.authFailed(-3))
return
}
WXApi.sendAuthReq(req, viewController: vc, delegate: self) { [weak self] success in
// success = SDK app fail
// URL Scheme onResp
guard !success else { return }
Task { @MainActor in
guard let self else { return }
if let pending = self.authPending.removeValue(forKey: state) {
pending.resume(throwing: WeChatError.authFailed(-3))
}
}
}
} }
#else #else
throw WeChatError.sdkNotLinked throw WeChatError.sdkNotLinked
#endif #endif
} }
/// ViewController presented / nav.visible SDK
/// modal present msext selfgameController/NewRootVC
/// AccreditLoginHandler stateless enum resolve
private static func topmostViewController() -> UIViewController? {
let windowScene = UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.first(where: { $0.activationState == .foregroundActive })
?? UIApplication.shared.connectedScenes.compactMap { $0 as? UIWindowScene }.first
guard let root = windowScene?.windows.first(where: \.isKeyWindow)?.rootViewController
?? windowScene?.windows.first?.rootViewController else {
return nil
}
var top: UIViewController = root
while let presented = top.presentedViewController {
top = presented
}
if let nav = top as? UINavigationController, let visible = nav.visibleViewController {
return visible
}
return top
}
// MARK: - Share // MARK: - Share
public enum ShareScene { public enum ShareScene {
@@ -103,7 +145,12 @@ public final class WeChatManager: NSObject {
case .session: req.scene = Int32(WXSceneSession.rawValue) case .session: req.scene = Int32(WXSceneSession.rawValue)
case .timeline: req.scene = Int32(WXSceneTimeline.rawValue) case .timeline: req.scene = Int32(WXSceneTimeline.rawValue)
} }
WXApi.send(req) // SceneDelegate.openURLContexts
// WXApi.handleOpen(url:delegate:WeChatManager.shared) onResp
// sendReq delegatecompletion=nil
// sharePending onResp FIFO
// SDK 2.x `sendReq:completion:` `send:` deprecated
WXApi.send(req, completion: nil)
} }
#else #else
throw WeChatError.sdkNotLinked throw WeChatError.sdkNotLinked
@@ -132,7 +179,12 @@ public final class WeChatManager: NSObject {
case .session: req.scene = Int32(WXSceneSession.rawValue) case .session: req.scene = Int32(WXSceneSession.rawValue)
case .timeline: req.scene = Int32(WXSceneTimeline.rawValue) case .timeline: req.scene = Int32(WXSceneTimeline.rawValue)
} }
WXApi.send(req) // SceneDelegate.openURLContexts
// WXApi.handleOpen(url:delegate:WeChatManager.shared) onResp
// sendReq delegatecompletion=nil
// sharePending onResp FIFO
// SDK 2.x `sendReq:completion:` `send:` deprecated
WXApi.send(req, completion: nil)
} }
#else #else
throw WeChatError.sdkNotLinked throw WeChatError.sdkNotLinked