0

My app connects to a localhost API through Alamofire. I have implemented URL Scheme, so when I click the link from iMessage it opens my app and in viewDidLoad() it connects to the API. For some reason I am getting following error only in iOS 13.1.3 but it is working smoothly in iOS 12.4. All I am testing in real devices.

Error:

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}

Here is the Code:

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
}
iOSLover
  • 45
  • 8

1 Answers1

1

Essentially, the underlying NSURLRequest is trying to re-use an HTTP connection that has been dropped by the server. This is apparently caused because the client libraries and your server expect different lifespans for the connection. Or something. Honestly, I'm not 100% sure on the why, but the solutions below all suggest that's what is happening.

There are 3 different ways to solve this one:

  1. Disable KeepAlive on your server

    This will cause new connections to be re-created for each new request. Depending on the pattern in which you talk to the server
    this may be inconsequential ... or it may be performance concern.

  2. Leave KeepAlive ON but make KeepAliveTimeout longer than 30s

    This is the opposite tradeoff as #1. It will be faster and if you're hitting the server a lot you may notice it. This will however cause your server to build up connections and reduce the number of concurrent users you can support. The performance impact of either choice depends somewhat on what server you're running and you should be able to decide with a little googling around for "KeepAlive best practices".

  3. Detect the error code and immediately retry the same query.

    When you receive this error - check the error code and immediately retry the same request. If the error is caused by using a defunct connection, the new query will create a new connection automagically and should work. If the network is genuinely gone the you've got bigger problems.

It's possible that this error will come from other sources, but I've tried all 3 of these approaches and each one solved the issue (obviously with different tradeoffs).

refer to : this post

mohsen
  • 4,698
  • 1
  • 33
  • 54