I read here that when using `URLSessionConfiguration.background(withIdentifier:)`, it shouldn't timeout and should try again 'till there is an available internet connection or 'till `timeoutIntervalForResource` reached out (which is set to 7 days), but in this case, I'm getting the timeout after less than 15 seconds and after that it doesn't seems to try again, also when there is an internet connection (e.g. turning off Network Link Conditioner).
I haven't set anything to that time so I really don't know why this is happening, all I've done is to set `100% Loss` in Network Link Conditioner to check offline usage (which shouldn’t matter to URLSession since it using background configuration).
In short:
My goal is to start the session whenever there is or there isn't an internet connection and let it fetch as soon as it can, when there is an available internet connection.
What happens right now is that the session is timed out and not performing the session also when there is an internet connection (e.g. turning off Network Link Conditioner).
*It's important to note that when there is an available internet connection while the session is resumed, it does fetching successfully, so the issue is not with the server I'm sending the task to for sure.
Here is my code:
Defining session configuration:
static let urlSessionConfiguration: URLSessionConfiguration = {
let configuration = URLSessionConfiguration.background(withIdentifier: FilesManager.urlSessionIdentifier)
configuration.sessionSendsLaunchEvents = false
configuration.sharedContainerIdentifier = "myApp"
return configuration
}()
Starting the session:
let url = URL(string: "https://url.com/path")!
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
urlRequest.httpBody = body
URLSession(configuration: FilesManager.urlSessionConfiguration, delegate: self, delegateQueue: nil).dataTask(with: urlRequest).resume()
Delegate:
extension FilesManager: URLSessionDataDelegate, URLSessionDelegate {
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
print("\(#function) \(error)")
}
}
Print in console:
urlSession(_:task:didCompleteWithError:) Optional(Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={_kCFStreamErrorCodeKey=-2104, _NSURLErrorFailingURLSessionTaskErrorKey=BackgroundDataTask .<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"BackgroundDataTask .<1>",
"LocalDataTask .<1>"
), NSLocalizedDescription=The request timed out., _kCFStreamErrorDomainKey=4, NSErrorFailingURLStringKey=https://url.com/path, NSErrorFailingURLKey=https://url.com/path})
If you know a better way to achieve my goal or you’re think there is something wrong in this code, please, let me know.
Thanks,
Ido.
Do you know of any sample code, which shows a good way of handling this?
That depends on the lifecycle of your app. If you’re using a traditional app delegate, adding code to application(_:willFinishLaunchingWithOptions:)
is a good option.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"