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

子类化URLSession遇iOS13弃用警告,如何改用sessionWithConfiguration?

解决URLSession子类初始化的废弃警告问题

你在创建Mock URLSession的子类时遇到了如下警告:

'init()' was deprecated in iOS 13.0: Please use +[NSURLSession sessionWithConfiguration:] or other class methods to create instances

下面针对这个问题给出两种解决方案,优先推荐协议抽象的方式,更符合Swift的设计原则:

方案一:协议抽象(更优解)

直接子类化URLSession会受限于其初始化规则,改用协议定义网络请求接口,既能避开废弃警告,又能让Mock实现更灵活。

  1. 定义网络请求协议
protocol NetworkSession {
    func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
    func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
}
  1. 让系统URLSession遵守该协议
extension URLSession: NetworkSession {}
  1. 实现Mock类
class WeatherURLSessionFake: NetworkSession {
    var data: Data?
    var response: URLResponse?
    var error: Error?
    
    init(data: Data?, response: URLResponse?, error: Error?) {
        self.data = data
        self.response = response
        self.error = error
    }
    
    func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
        let task = WeatherURLSessionDataTaskFake()
        task.completionHandler = completionHandler
        task.data = data
        task.urlResponse = response
        task.responseError = error
        return task
    }
    
    func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
        let task = WeatherURLSessionDataTaskFake()
        task.completionHandler = completionHandler
        task.data = data
        task.urlResponse = response
        task.responseError = error
        return task
    }
}

后续业务代码依赖NetworkSession协议即可,轻松切换真实URLSession和Mock实例。

方案二:子类化URLSession(兼容原有思路)

如果坚持要子类化,需要重写父类的指定初始化器,并用类方法创建实例,避免调用废弃的无参初始化器:

class WeatherURLSessionFake: URLSession {
    var data: Data?
    var response: URLResponse?
    var error: Error?
    
    // 用类方法创建Mock实例,内部调用父类的配置初始化器
    static func fakeSession(data: Data?, response: URLResponse?, error: Error?) -> WeatherURLSessionFake {
        let config = URLSessionConfiguration.default
        let session = self.init(configuration: config) as! WeatherURLSessionFake
        session.data = data
        session.response = response
        session.error = error
        return session
    }
    
    // 重写父类指定初始化器,避开废弃的init()
    override init(configuration: URLSessionConfiguration, delegate: URLSessionDelegate? = nil, delegateQueue: OperationQueue? = nil) {
        super.init(configuration: configuration, delegate: delegate, delegateQueue: delegateQueue)
    }
    
    // 必须实现废弃的init(),但标记为不推荐使用
    @available(*, deprecated, message: "请使用fakeSession(data:response:error:)创建实例")
    override init() {
        super.init()
    }
    
    override func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
        let task = WeatherURLSessionDataTaskFake()
        task.completionHandler = completionHandler
        task.data = data
        task.urlResponse = response
        task.responseError = error
        return task
    }
    
    override func dataTask(with request: URLRequest, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
        let task = WeatherURLSessionDataTaskFake()
        task.completionHandler = completionHandler
        task.data = data
        task.urlResponse = response
        task.responseError = error
        return task
    }
}

使用时通过WeatherURLSessionFake.fakeSession(data:..., response:..., error:...)创建实例即可消除警告。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 09:30:56