You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RxSwift新手求助:如何监听UIWebView.request的赋值变化?

Hey Eugene, 作为RxSwift新手碰到这个问题真的太正常了,我来给你拆解下问题原因和解决方案~

问题原因分析

你直接监听webView.request只拿到初始nil的核心原因是:UIWebView的request属性并不是KVO兼容的——系统不会在这个属性变化时主动发送KVO通知,所以Rx的rx.observe方法只能捕获到初始值,后续请求加载时不会触发回调。

推荐解决方案

方法一:利用Rx封装UIWebView的代理方法(最直接高效)

UIWebView在准备加载新请求时,会触发webView(_:shouldStartLoadWith:navigationType:)代理方法,我们可以通过RxCocoa把这个代理事件转换成Observable,轻松捕获每次加载的request:

import RxSwift
import RxCocoa

// 假设你已经初始化了UIWebView和DisposeBag
let webView = UIWebView()
let disposeBag = DisposeBag()

// 订阅代理事件,捕获新请求
webView.rx.shouldStartLoadWithRequest
    .subscribe(onNext: { request, navigationType in
        print("捕获到新的Request: \(request)")
        // 这里可以根据navigationType区分加载类型(比如用户点击链接、页面刷新等)
        return true // 返回true允许请求加载,返回false则阻止
    })
    .disposed(by: disposeBag)

这个方法是最贴合UIWebView工作逻辑的,能100%捕获到所有即将加载的request,完全满足你的需求。

方法二:自定义KVO兼容属性(特殊场景可选)

如果你一定要通过属性监听的方式实现,可以给UIWebView添加一个自定义的关联属性,在代理方法里更新它,再用Rx监听这个属性的变化:

import RxSwift
import RxCocoa

extension UIWebView {
    private static let currentRequestKey = UnsafeRawPointer(bitPattern: "currentRequest".hashValue)!
    
    // 自定义的KVO兼容属性
    var currentRequest: URLRequest? {
        get {
            objc_getAssociatedObject(self, UIWebView.currentRequestKey) as? URLRequest
        }
        set {
            objc_setAssociatedObject(self, UIWebView.currentRequestKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
}

// 初始化相关实例
let webView = UIWebView()
let disposeBag = DisposeBag()

// 在代理事件里更新自定义属性
webView.rx.shouldStartLoadWithRequest
    .subscribe(onNext: { [weak webView] request, _ in
        webView?.currentRequest = request
    })
    .disposed(by: disposeBag)

// 监听自定义属性的变化(跳过初始nil)
webView.rx.observe(URLRequest?.self, "currentRequest")
    .skip(1)
    .subscribe(onNext: { request in
        print("通过自定义属性捕获到Request: \(request!)")
    })
    .disposed(by: disposeBag)

这种方式稍显繁琐,只推荐在你有特殊属性监听需求的场景下使用。

额外小建议

苹果已经废弃了UIWebView,推荐你迁移到WKWebView——它的API设计更合理,RxSwift的支持也更完善,比如可以通过wkWebView.rx.didStartProvisionalNavigation轻松捕获加载的request,后续维护也更省心。

内容的提问来源于stack exchange,提问作者Eugene Don

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:35:43