0

I'm developing an iOS app (SwiftUI, iOS15) which fetches data from an API using URLSession().dataTask(). The fetch request takes 30-60 seconds. Because the fetch request is long, the screen can turn off or the user can put the app in the background, and then, when the user returns to the app, the fetch request fails; XCode console shows: Receive failed with error "Socket is not connected".

If I manually keep the screen on by tapping occasionally, the API fetch successfully resolves and the server data is received.

How can I implement the API fetch request so that if either:

  • the screen turns off, or
  • the user puts the app in the background

the request will still complete and the data will be returned and processed (saved to Core Data)?

I tried following Apple's "Using background tasks to update your app", but couldn't make sense of it. I also tried URLSessionConfiguration.background() but couldn't get that to work either.

Code for API fetch request:

func fetchData(context: NSManagedObjectContext) {
    let url = "http://localhost:3000/records" // takes >30 seconds to respond
    let token = jwtToken
    var request = URLRequest(url: URL(string: url)!)
    request.httpMethod = "POST"
    request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
    request.setValue("application/json;charset=utf-8", forHTTPHeaderField: "Content-Type")
    
    let sessionConfig = URLSessionConfiguration.default
    sessionConfig.timeoutIntervalForRequest = 90.0      // to handle >30 second timeout (I think)
    sessionConfig.timeoutIntervalForResource = 90.0     // to handle >30 second timeout (I think)
    let session = URLSession(configuration: sessionConfig)
    
    session.dataTask(with: request) { (data, res, _) in
        guard let jsonData = data else { return }
        let response = res as! HTTPURLResponse
        if response.statusCode == 404 {
            print("API 404 error")
            return
        }

        do {
            let record = try JSONDecoder().decode(RecordModel.self, from: jsonData)
            DispatchQueue.main.async {
                self.records.append(record)
                self.saveOneRecord(context: context, record: record)
            }
        } catch {
            print("API fetch/save data error: \(error.localizedDescription)")
        }
    }.resume()
}

Thank you.

user3320795
  • 523
  • 2
  • 6
  • 17

0 Answers0