Hiram Elguezabal
Hiram Elguezabal

Reputation: 151

Error Code=-1005 "The network connection was lost." in Swift while consuming Web Service

I'm working on a iOS project in Swift 2.0, which has Web service calls, these services are slow to respond and that is normal, can be up to 1 minute or a little more, when i call the service 70% of the time it answers with the error "the network connection was lost." The tests were conducted in both simulator and different phone devices and iPad and the result is the same. The network connection is strong and the same application was also created on Android and working properly almost 100% of the time.

The way I call services from any view is as follows:

@IBAction func contratarAct(sender: AnyObject) {
    conexion.delegate = self
    loadingView = MEXLoadingView(delegate: self, title: "Espere por favor", percent: false, view: self.view)
    self.loadingView.showAnimated(true)
    let url = urlServicios.urlBaseServicios + "/" + idSolicitud + "/" + idNoCliente + "/CONTRATO"
    conexion.consultaServicioGET(url, httpMethod: "PUT")
}

And the method that is executed is as follows:

func consultaServicioGET(url : String, httpMethod : String ){
    let urlString = url
    let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
    request.timeoutInterval = 540
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
    request.addValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")

    var session = NSURLSession.sharedSession()
    request.HTTPMethod = httpMethod

    let urlconfig = NSURLSessionConfiguration.defaultSessionConfiguration()
    urlconfig.timeoutIntervalForRequest = 540
    urlconfig.timeoutIntervalForResource = 540
    session = NSURLSession(configuration: urlconfig, delegate: self, delegateQueue: nil)

    let task = session.dataTaskWithRequest(request , completionHandler: {
        (data:NSData?, response:NSURLResponse?, error:NSError?) in

        if error != nil {
            let jsonError : NSDictionary = NSDictionary()
            self.delegate?.respuestaServicioGET!(jsonError, mensaje: "\(error!.localizedDescription)")
            return
        }

        let jsonString = NSString(data: data!,encoding: NSASCIIStringEncoding)
        let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)

        let json: NSDictionary = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSDictionary

        if (json.isKindOfClass(NSDictionary) ){
            self.delegate?.respuestaServicioGET!(json, mensaje: "OK")
        }else{
            let jsonError : NSDictionary = NSDictionary()
            self.delegate?.respuestaServicioGET!(jsonError, mensaje: "ERROR")
        }
    })
    task.resume()
}

the error displayed is:

error=Optional(Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={NSUnderlyingError=0x7fbde5f51df0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={_kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=https://particulares-gw-obparticularesmx-pre.appls.cto2.paas.gsnetcloud.com:443/OPB/57dadf7de4b0ac2e518de44a/57dadf7de4b06c6b04ef0dcf/CONTRATO, NSErrorFailingURLKey=https://particulares-gw-obparticularesmx-pre.appls.cto2.paas.gsnetcloud.com:443/OPB/57dadf7de4b0ac2e518de44a/57dadf7de4b06c6b04ef0dcf/CONTRATO, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-4, NSLocalizedDescription=The network connection was lost.})

I add some code like the following:

urlconfig.timeoutIntervalForRequest = 540 urlconfig.timeoutIntervalForResource = 540

Trying to get more "timeout" but this is not looks like a timeout.

I can not get out of this error for days, any help will be greatly appreciated. I'm desperate.

Upvotes: 1

Views: 12624

Answers (4)

Blazej Kita
Blazej Kita

Reputation: 135

I don't why but it's works when I add sleep before my request:

sleep(10000) 

    AF.request(ViewController.URL_SYSTEM+"/rest,get_profile", method: .post, parameters: params, encoding: JSONEncoding.default , headers: headers).responseJSON { (response) in
                    }

Upvotes: -2

Akash Sharma
Akash Sharma

Reputation: 816

I faced the same issue and I am attaching a screenshot of the resolution to show how I resolved the issue.

In my case, the issue was that the API requests are blocked from the server Sucuri/Cloudproxy (Or you can say firewall service). Disabling the firewall resolved the issue

Resolution Image

Upvotes: 2

Ahtazaz
Ahtazaz

Reputation: 885

I faced this issue and spend more than 1 week to fix this. AND i just solved this issue by changing Wifi connection.

Upvotes: -3

dgatwood
dgatwood

Reputation: 10407

If you're expecting a socket to stay open for minutes at a time, you're in for a world of hurt. That might work on Wi-Fi, but on cellular, there's a high probability of the connection glitching because of tower switching or some other random event outside your control. When that happens, the connection drops, and there's really nothing your app can do about it.

This really needs to be fixed by changing the way the client requests data so that the responses can be more asynchronous. Specifically:

  • Make your request.
  • On the server side, immediately provide the client with a unique identifier for that request and close the connection.
  • Next, on the client side, periodically ask the server for its status.
    • If the connection times out, ask again.
    • If the server says that the results are not ready, wait a few seconds and ask again.
  • On the server side, when processing is completed, store the results along with the identifier in a persistent fashion (e.g. in a file or database)
  • When the client requests the results for that identifier, return the results if they are ready, or return a "not ready" error of some sort.
  • Have a periodic cron job or similar on the server side to clean up old data that has not yet been collected.

With that model, it doesn't matter if the connection to the server closes, because a subsequent request will get the data successfully.

Upvotes: 4

Related Questions