URLSession dataTask无法运行

时间:2018-10-17 15:49:57

标签: swift

我对这段代码有疑问。我正在“非常糟糕的网络”配置文件下使用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)

    }

1 个答案:

答案 0 :(得分:1)

  

我猜它由于连接不良而无法运行,但是由于该行从不运行,我无法从完成处理程序得到响应,因此该如何处理呢?

您应该简单地接受您可能不会从完成处理程序得到响应。这就是异步操作的全部要点:您可能很快就会收到响应,这可能需要很长时间,而永远不会。您的代码应该以这种方式编写。

默认情况下,当您创建URLSession时,其配置的truewaitsForConnectivity。您应该使用可达性来了解是否存在连通性;您应该只是开始任务并退后一步。该任务将在可能的情况下发生。

但是,如果这不可接受,并且您需要尽早失败,则将配置的false设置为f。然后,您将失败并超时,可能会在一分钟内(默认)。

但是,还应该指出,通过将数据任务与完成处理程序配合使用,您真是步履维艰。那是一个非常有限的方法。最好给会话一个委托并实现委托方法,以便接收有关发生的一切的完整信息。