TIC TCP Err(54)

Good Morning,


My app makes a HTTPS call during background fetches, which works just fine when the app is in the foreground. However, when the app is in the background (e.g., lock screen) the background fetch task still completes, but the HTTPS calls does not run. I get the following error:


TIC TCP Conn Failed [28:0x60c000363780]: 1:54 Err(54)


There are not too many hits for Err(54), so I'm not sure what the problem is. I would appreciate any help.


This is the HTTPS call I make during the background fetches.


func requestLicenseNumberSearchFromDca(licensee: LicenseeWithUpdatesStruct) {
       
        let requestUrl = URL(string: "xxxxxxxxxxxxxxxxxxx)
        var request = URLRequest(url: requestUrl!)
        request.httpMethod = "GET"
        request.addValue("Basic XXXXXXXXXXXXXXXX=", forHTTPHeaderField: "Authorization")
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        let session = URLSession(configuration: URLSessionConfiguration.default)
        let task = session.dataTask(with: request as URLRequest) {
            ( data, response, error) in
           
            //Break if errors
            if let error = error {
                print(error.localizedDescription)
                return
            }
           
            //Break if HTTP Response Code is not OK
            guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
                print("Failed to get results. \(response?.description ?? "")")
                return
            }
           
            guard let data = data else { return }
           
            //Force main thread execution for Main Thread Checker. Otherwise it will execute on background thread.
            DispatchQueue.main.async  {
               
                //Convert HTTP data to UTF 8
                let dataString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
               
                //Remove \n and \r from HTTP data UTF 8
                var dataStringFiltered = dataString?.replacingOccurrences(of: "\n", with: "")
                dataStringFiltered = dataString?.replacingOccurrences(of: "\r", with: "")
               
                //Convert filtered data to Data
                guard let dataFiltered = dataStringFiltered?.data(using: .utf8) else { return }
               
                do {
                   
                    //Serialize JSON response and auto-populate response object
                    let jsonResponse = try JSONDecoder().decode(RootLicenseeStatusModelStruct.self, from: dataFiltered)
                   
                    //Call delegate
                    self.delegate?.didGetLicenseeStatus(rootLicenseeStruct: jsonResponse, licensee: licensee)
                   
                } catch let jsonError {
                    print("Error serializing JSON:", jsonError.localizedDescription, jsonError)
                }
            }
        }
        task.resume()


The reason I know the background fetch runs is because I have a notification in its completion handler.


Thank you.

Replies

In this context error 54 is

ECONNRESET
, meaning that the connection tore for some reason. There’s a bunch of potential causes for this but your description of how this comes about makes me suspect that your app got suspended while the request was in flight. Networking in the background works just fine as long as you avoid getting suspended. Once you get suspended, however, things get complex. Technote 2277 Networking and Multitasking has the details.

In situations like this you have two options:

  • You can use a UIApplication background task to prevent your app from being suspended (A).

  • You can run the request in a background session (B).

For a small request like this one I generally recommend A.

If you go down this path, make sure to read my UIApplication Background Task Notes post.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thank you eskimo 🙂