URLSession dataTask не запускается - PullRequest
       4

URLSession dataTask не запускается

0 голосов
/ 17 октября 2018

У меня проблема с этим блоком кода.Я тестирую свое приложение с помощью 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 или следующего блока кода, оно вернет 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 голосов
/ 17 октября 2018

Я предполагаю, что это не работает, потому что соединение плохое, но как я могу справиться с этим сценарием, так как я не могу получить ответ от обработчика завершения, поскольку строка никогда не запускается?

Вы должны просто принять, что вы можете не получить ответ от обработчика завершения.В этом весь смысл асинхронной операции: вы можете получить ответ в ближайшее время, это может занять много времени, а может и никогда.Ваш код должен быть написан так, чтобы справиться с этим.

По умолчанию, когда вы создаете URLSession, его конфигурация waitsForConnectivity равна true.Вы должны не использовать Reachability, чтобы узнать, есть ли связь;Вы должны просто начать задание и отступить.Задача будет выполняться тогда, когда она может.

Однако, если это неприемлемо и вам необходимо выполнить сбой раньше, установите для waitsForConnectivity конфигурации значение false.Затем вы потерпите неудачу с таймаутом, вероятно, через одну минуту (по умолчанию).

Следует также отметить, что вы как бы стреляете себе в ногу, используя задачу данных с завершениемобработчик.Это очень ограничительный подход.Было бы намного лучше дать сеансу делегат и реализовать методы делегата, чтобы получить полную информацию о том, что происходит, как это происходит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...