3

我想确保以正确的方式实现 URLSessionTaskDelegate 和 URLSessionDataDelegate。我使用它们,因为我希望能够跟踪进度。这是到目前为止的代码:

final public fileprivate(set) var data:     Data?
final public fileprivate(set) var response: URLResponse?
final public fileprivate(set) var error:    Error?


public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {        
    if let response = response as? HTTPURLResponse, response.statusCode == 200 {
        data = Data()
    }

    self.response = response

    completionHandler(.allow)
}

public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    self.data?.append(data)
}

public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    self.error = error

    // ... Work with downloaded data
}

和几个问题:

  1. 我应该总是在 didReceive 响应中执行 completionHandler,它应该总是 .allow 吗?也许我应该只在响应状态代码为 200 时才这样做?
  2. 在这种情况下,状态码 200 是我唯一需要真正检查的吗?这是初始化数据的正确位置吗?也许这个函数可以用不同的代码执行几次,我应该区别对待任何代码?
  3. didCompleteWithError 是我唯一需要分配错误的地方吗?也许错误也可以在不同的地方产生?
  4. 在 URLResponse 的文档中,我可以看到 expectedContentLength 的默认值为 NSURLResponseUnknownLength,但该值不存在。现在有什么新名字吗?
  5. 还有什么我应该知道的,以便这个代码是通用的吗?
4

1 回答 1

1
  1. 如果状态码不是 200,则响应正文通常包含帮助您诊断为什么不是 200 的信息,因此您可能希望继续捕获该信息。我可能会将该状态代码检查移至didCompleteWithError.

  2. 我通常期望 200,因此只检查 200。从技术上讲,所有 2xx 代码都是“成功”代码,因此您可能希望将它们全部视为成功。这取决于你。

  3. didCompleteWithError是唯一与连接相关的错误。从理论上讲,您可能需要检查urlSession(_:didBecomeInvalidWithError:). 此外,如果您获得非 2xx 状态代码,或者在更高级别,如果响应解析失败,您可能希望分配自己的错误代码。

  4. 他们似乎没有从 Swift 3 中定义适当的常量。仅供参考,查看标题,您可以看到值是-1,但通常我们只检查response.expectedContentLength < 0.

于 2016-11-12T09:54:58.227 回答