Сетевое соединение теряется только в iOS 13.1.3 (Alamofire) - PullRequest
0 голосов
/ 21 октября 2019

Мое приложение подключается к локальному API через Alamofire. Я реализовал схему URL, поэтому, когда я щелкаю ссылку в iMessage, он открывает мое приложение и в viewDidLoad() подключается к API. По какой-то причине я получаю следующую ошибку только в iOS 13.1.3, но она нормально работает в iOS 12.4. Все, что я тестирую на реальных устройствах.

Ошибка:

2019-10-21 10:32:13.059194+0530 TestAPI[882:164673] [] nw_read_request_report [C5] Receive failed with error "Software caused connection abort"
2019-10-21 10:32:13.060020+0530 TestAPI[882:164673] Task <45115A48-58C7-49EA-AB5D-2C6708E3C036>.<4> HTTP load failed, 363/0 bytes (error code: -1005 [4:-4])
2019-10-21 10:32:13.076737+0530 TestAPI[882:164603] Task <45115A48-58C7-49EA-AB5D-2C6708E3C036>.<4> finished with error [-1005] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x283d13840 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x2810a9a40 [0x1d42775e0]>{length = 16, capacity = 16, bytes = 0x100293ddc0a808680000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <45115A48-58C7-49EA-AB5D-2C6708E3C036>.<4>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <45115A48-58C7-49EA-AB5D-2C6708E3C036>.<4>"
), NSLocalizedDescription=The network connection was lost., NSErrorFailingURLStringKey=http://192.168.8.104:37853/auth/test, NSErrorFailingURLKey=http://192.168.8.104:37853/auth/test, _kCFStreamErrorDomainKey=4}
2019-10-21 10:32:13.590311+0530 TestAPI[882:164306] FBSDKLog: Missing [FBSDKAppEvents appID] for [FBSDKAppEvents publishInstall:]
Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x283d13840 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x2810a9a40 [0x1d42775e0]>{length = 16, capacity = 16, bytes = 0x100293ddc0a808680000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <45115A48-58C7-49EA-AB5D-2C6708E3C036>.<4>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalDataTask <45115A48-58C7-49EA-AB5D-2C6708E3C036>.<4>"
), NSLocalizedDescription=The network connection was lost., NSErrorFailingURLStringKey=http://192.168.8.104:37853/auth/test, NSErrorFailingURLKey=http://192.168.8.104:37853/auth/test, _kCFStreamErrorDomainKey=4}

Вот код:

override func viewDidLoad()
{
    super.viewDidLoad()

    txtLable.text = "test"
    let testServices = TestService()

    let test: Parameters = [
        "test": "test"
    ]

    testServices.TestNonSecureConnection(parameters: test, completionHandler: {(returnUserVerificationStatus) -> Void in
        if(returnUserVerificationStatus != "failed")
        {
            self.txtLable.text = returnUserVerificationStatus
        }else{
            print("failed")
        }
    })
}


class TestService
{
    func TestNonSecureConnection(parameters: Parameters, completionHandler: @escaping (_ returnUserVerificationStatus: String)-> Void )
    {
        var headers: HTTPHeaders = [:]
        var resultString = ""

        let url = URL(string: Config.LOGIN_SERVER_URL + "/auth/test")!
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = "POST"

        do {
            urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: [])
        } catch {
            // No-op
        }

         urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")

        Alamofire.request(urlRequest)
            .responseString() { response in
                switch response.result {
                case .success:
                    resultString = response.result.value!
                    completionHandler(resultString)
                case .failure(let error):
                    print(error)
                }
        }
    }

}


func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {

    self.window = UIWindow(frame: UIScreen.main.bounds)
    let storyBoard = UIStoryboard(name: "Main", bundle: nil)

    self.scheme = url.scheme
    self.path = url.path
    self.query = url.query

    let viewController = storyBoard.instantiateViewController(withIdentifier: "viewcontroller") as! ViewController
    self.window?.rootViewController = viewController
    self.window?.makeKeyAndVisible()
    return true
}

1 Ответ

0 голосов
/ 21 октября 2019

По сути, базовый NSURLRequest пытается повторно использовать HTTP-соединение, которое было сброшено сервером. Это, по-видимому, вызвано тем, что клиентские библиотеки и ваш сервер ожидают разные продолжительности жизни для соединения. Или что-то. Честно говоря, я не уверен на 100%, почему, но приведенные ниже решения предполагают, что именно так и происходит.

Существует 3 различных способа решения этого вопроса:

  1. Отключить KeepAlive на вашем сервере

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

  2. Оставьте KeepAlive ON включенным, но сделайте KeepAliveTimeout более 30 с

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

  3. Обнаружение кода ошибкии немедленно повторите тот же запрос.

    Когда вы получите эту ошибку - проверьте код ошибки и немедленно повторите тот же запрос. Если ошибка вызвана использованием несуществующего соединения, новый запрос автоматически создаст новое соединение и должен работать. Если сеть действительно исчезла, у вас есть большие проблемы.

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

см. этот пост

...