我对这段代码有疑问。我正在“非常糟糕的网络”配置文件下使用Network Link Conditioner测试我的应用程序,并且在用户互联网连接状况不佳的情况下,此dataTask从未运行。如果连接良好,则此代码可以正常工作。我猜它由于连接不良而无法运行,但是由于该行从未运行,因此无法从完成处理程序获得响应,因此该如何处理这种情况?
let task = session.dataTask(with: request, completionHandler: { (data, response, error) in
do {
print("RUNNING RECEIPT UPLOAD TASK")
if let jsonObj: [String : AnyObject] = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions(rawValue: 0)) as? [String : AnyObject] {
if let resultData: [String : AnyObject] = jsonObj["result"] as? [String : AnyObject] {
if let status: Bool = resultData["status"] as? Bool {
if status {
completion(status, nil, resultData)
} else {
if let errorMessage: String = resultData["message"] as? String {
completion(status, errorMessage, resultData)
} else {
completion(status, "FAILED RECEIPT UPLOAD", resultData)
}
}
}
} else {
completion(false, "FAILED RECEIPT UPLOAD", nil)
}
} else {
completion(false, "FAILED RECEIPT UPLOAD", nil)
}
} catch _ {
completion(false, "FAILED RECEIPT UPLOAD", nil)
}
})
task.resume()
如果在使用Reachability或以下代码块运行该连接之前尝试测试活动的Internet连接,则即使存在连接但连接不良也将返回true,因此我无法处理未通过测试来运行的dataTask首先连接。
static func isInternetAvailable() -> Bool {
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection)
}
答案 0 :(得分:1)
我猜它由于连接不良而无法运行,但是由于该行从不运行,我无法从完成处理程序得到响应,因此该如何处理呢?
您应该简单地接受您可能不会从完成处理程序得到响应。这就是异步操作的全部要点:您可能很快就会收到响应,这可能需要很长时间,而永远不会。您的代码应该以这种方式编写。
默认情况下,当您创建URLSession时,其配置的true
为waitsForConnectivity
。您应该不使用可达性来了解是否存在连通性;您应该只是开始任务并退后一步。该任务将在可能的情况下发生。
但是,如果这不可接受,并且您需要尽早失败,则将配置的false
设置为f
。然后,您将失败并超时,可能会在一分钟内(默认)。
但是,还应该指出,通过将数据任务与完成处理程序配合使用,您真是步履维艰。那是一个非常有限的方法。最好给会话一个委托并实现委托方法,以便接收有关发生的一切的完整信息。