Hou*_*man 5 unit-testing ios swift urlsession swift4
我一直在按照本教程进行讲解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
}
}
Run Code Online (Sandbox Code Playgroud)
单元测试按预期工作。但是,当我尝试运行真实对象时,URLSession-> datatask()陷入无限循环并崩溃。似乎datatask()正在调用自身。
请问我在俯视什么?
更新:
protocol URLSessionDataTaskProtocol {
var originalRequest: URLRequest? { get }
func resume()
}
extension URLSessionDataTask: URLSessionDataTaskProtocol {}
Run Code Online (Sandbox Code Playgroud)
我终于找到了解决方案。它\xe2\x80\x99很有趣,因为我们只见树木不见森林。有两个问题:
\n\n1) Swift 4 似乎已将签名更改dataTask(with: NSURLRequest)为dataTask(with: URLRequest)
因此,我的开头问题中的行只会与协议的 func 签名匹配,并且它永远不会到达内部dataTask,URLSession因此会出现无限循环。为了解决这个问题,我必须相应地更改NSURLRequest并URLRequest重构代码。
2)签名仍然模糊,因此最好先将结果存储为 dataTask 并进行强制转换URLSessionDataTask,然后返回变量。
Swift 4 的新重构代码:
\n\ntypealias DataTaskResult = (Data?, URLResponse?, Error?) -> Void\n\nprotocol URLSessionProtocol {\n func dataTask(with request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol\n}\n\nextension URLSession: URLSessionProtocol {\n func dataTask(with request: URLRequest, completionHandler: @escaping DataTaskResult) -> URLSessionDataTaskProtocol {\n let task:URLSessionDataTask = dataTask(with: request, completionHandler: {\n (data:Data?, response:URLResponse?, error:Error?) in completionHandler(data,response,error) }) as URLSessionDataTask\n return task\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n我还发现我必须URLSession.shared作为单例注入,而不是作为 注入URLSession(),否则它可能会崩溃。
| 归档时间: |
|
| 查看次数: |
798 次 |
| 最近记录: |