【发布时间】:2021-12-07 04:07:22
【问题描述】:
我有一个手写类 MyURLRequest,它实现了 Operation。在它里面创建 URLSession,配置它
public init(shouldWaitForConnectivity: Bool, timeoutForResource: Double?) {
baseUrl = URL(string: Self.relevantServerUrl + "api/")
self.shouldWaitForConnectivity = shouldWaitForConnectivity
self.timeoutForResource = timeoutForResource
super.init()
localURLSession = URLSession(configuration: localConfig, delegate: self, delegateQueue: nil)
}
public var localConfig: URLSessionConfiguration {
let res = URLSessionConfiguration.default
res.allowsCellularAccess = true
if let shouldWaitForConnectivity = shouldWaitForConnectivity {
res.waitsForConnectivity = shouldWaitForConnectivity
if let timeoutForResource = timeoutForResource {
res.timeoutIntervalForResource = timeoutForResource
}
}
return res
}
创建 URLRequest、dataTask,然后在 OperationQueue 上运行。操作的方法是这样的
override open func start() {
if isCancelled {
isFinished = true
return
}
startDate = Date()
sessionTask?.resume()
localURLSession.finishTasksAndInvalidate()
}
override open func cancel() {
super.cancel()
sessionTask?.cancel()
}
MyURLRequest 还实现了 URLSessionDataDelegate 和 URLSessionTaskDelegate 以及它自己的 URLSession 的代理。
waitsForConnectivity NSURLSessionConfiguration 的标志有问题。在构造函数中,我将其设置为 true,但此标志被忽略。在运行时,当网络关闭时,请求立即结束,错误 -1009。 URLSessionTaskDelegate 的方法 urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) 立即触发。 func urlSession(_ session: URLSession, taskIsWaitingForConnectivity task: URLSessionTask) 根本没有被调用。
原因绝对不是,waitsForConnectivity 标志设置不正确:我检查了 urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) 收到的任务中的配置 , 并且 waitsForConnectivity == true。
我也尝试在没有操作队列的情况下发出请求,结果很好 - 表现如预期。也许与 OperationQueue 有关。非常感谢您的帮助!
更新: 似乎问题的根源是操作发布得太早(当请求尚未完成时)。我尝试使用 DispatchGroup() 来同步它们:
override open func start() {
if isCancelled {
isFinished = true
return
}
startDate = Date()
dispatchGroup.enter()
sessionTask?.resume()
dispatchGroup.wait()
localURLSession.finishTasksAndInvalidate()
}
其中 .leave() 在 URLSessionDelegate 的方法中被调用。没有任何改变,仍然没有等待连接。
更新: 这是我在 didCompleteWithError 中遇到的错误:
Error Domain=NSURLErrorDomain Code=-1009 "" UserInfo={_kCFStreamErrorCodeKey=50, NSUnderlyingError=0x7fc319112de0 {Error Domain=kCFErrorDomainCFNetwork Code=-1009 "(null)" UserInfo={_kCFStreamErrorCodeKey=50, _kCFStreamErrorDomainKey=1}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <6388AD46-8497-40DF-8768-44FEBB84A8EC>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <6388AD46-8497-40DF-8768-44FEBB84A8EC>.<1>",
"LocalDataTask <26BCBD73-FC8B-4A48-8EA2-1172ABB8093C>.<1>"
), NSLocalizedDescription=., NSErrorFailingURLStringKey=}
【问题讨论】:
标签: ios swift multithreading nsurlsession operation