2

I am using a NSURLSession configured as a background session to upload multiple images to a bucket in GCS. For one test, 26 images were used, each around 10 MB each. The tests are performed with strong wifi connectivity and battery close to 100% if not actively charging. I am creating this NSURLSession at the point that the app is backgrounded and notifies via the background task expiration handler.

NSURLSession code:

let config = URLSessionConfiguration.background(withIdentifier: identifier)
config.waitsForConnectivity = true
config.allowsCellularAccess = true
config.isDiscretionary = false

let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
session.sessionDescription = identifier

Creating the requests for upload:

for (signedGCSURLDestination, image) in images {
  let request = URLRequest(url: signedGCSURLDestination, method: .put)
  request.headers.add(name: "Content-Type", value: "image/jpeg")

  let task = session.uploadTask(with: request, fromFile: file)

  task.taskDescription = identifier
  task.resume()
} 

Ultimately, the images in the GCS Bucket all have size 0B. Prior to transitioning to a background NSURLSession, we use Alamofire in the app foreground and these images upload to the buckets just fine.

I am starting to investigate using a background processing task to potentially continue using the Alamofire code while the app is minimized, but that is a separate issue from the NSURLSession simply not working.

FishStix
  • 4,560
  • 8
  • 34
  • 50
  • 1
    Have you implemented the [`URLSessionTaskDelegate`](https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate) methods? Any error reported by [`urlSession(_:task:didCompleteWithError:)`](https://developer.apple.com/documentation/foundation/urlsessiontaskdelegate/1411610-urlsession)? It’s also often useful to watch the uploads using tools like [Charles](https://charlesproxy.com) or [Wireshark](https://wireshark.org), perhaps comparing your Alamofire foreground implementation to this implementation. – Rob Apr 29 '20 at 23:06

1 Answers1

1

The file being uploaded did not have the proper permissions once the device was being locked. Setting the completeUntilFirstUserAuthentication attribute on each file that I wanted to upload solved the problem.

FileManager.default.setAttributes([FileAttributeKey.protectionKey: FileProtectionType.completeUntilFirstUserAuthentication],
                                           ofItemAtPath: path)

I imagine the upload had started before the device was locked, and it does seem like the NSURLSession uploads occur in parallel. So the uploads for all the files possibly started, hence the file place holders existing in GCS at 0B, and then they never completed due to the files becoming locked.

FishStix
  • 4,560
  • 8
  • 34
  • 50