如何在迅速中解脱出来



我一直在遵循本教程以示出URLSession。该示例是通过创建协议并扩展现有URLSession的来完成的示例。

protocol URLSessionProtocol {
    typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
    func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol
}
extension URLSession: URLSessionProtocol {
    func dataTask(with request: NSURLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol {
        return dataTask(with: request, completionHandler: completionHandler) as URLSessionDataTaskProtocol
    }
}

单元测试按预期工作。但是,当我尝试运行真实的东西时,urlsession-> dataTask((进入无限循环并崩溃。似乎DataTask((正在呼唤自己。

我要忽略什么?

更新:

protocol URLSessionDataTaskProtocol {
    var originalRequest: URLRequest? { get }
    func resume()
}
extension URLSessionDataTask: URLSessionDataTaskProtocol {}

我终于找到了解决方案。当我们错过了树木的木头时,这令人着迷。有两个问题:

1(似乎Swift 4将dataTask(with: NSURLRequest)的签名更改为dataTask(with: URLRequest)

因此,我的开头问题中的行只能与协议的func签名相匹配,并且它永远不会在URLSession内部击中dataTask,因此无限循环。要解决此问题,我必须将NSURLRequest更改为URLRequest并相应地重构代码。

2(签名保持模糊,因此最好将结果存储为DataTask首先使用URLSessionDataTask的铸件,然后返回变量。

Swift 4的新重构代码:

typealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void
protocol URLSessionProtocol {
    func dataTask(with request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol
}
extension URLSession: URLSessionProtocol {
    func dataTask(with request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol {
        let task:URLSessionDataTask = dataTask(with: request, completionHandler: {
            (data:Data?, response:URLResponse?, error:Error?) in completionHandler(data,response,error) }) as URLSessionDataTask
        return task
    }
}

我还发现我必须将URLSession.shared注射为单身人士,而不是URLSession(),否则可能会崩溃。

来到这里以了解如何模拟URLSession诸如URLSessionDataTask之类的任务?

大约swift 5,更易于模拟URLSession使用的URLProtocol来发送请求。

请参阅使用URLProtocol的单元测试。

相关内容

  • 没有找到相关文章

最新更新