I'm trying to upload data using NSURLSession with a background task from an OSX share extension.
As soon as I start the task, by delegate is called back with the world's least helpful error message:
The operation couldn’t be completed. (NSURLErrorDomain error -995.)
There's no other information in the NSError object, nor in the console.
After scouring the internet, the only clue I have is to make sure that I've set up the configuration.sharedContainerIdentifier
correctly, however I've already done that:
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(uniqueId)
configuration.sharedContainerIdentifier = Config.appGroupName
urlSession = NSURLSession.init(configuration: configuration, delegate: self, delegateQueue: nil)
I then prepare the request and create the task:
let task = self.urlSession!.dataTaskWithRequest(request)
self.tasks.append(task)
task.resume()
Note that everything works perfectly when from my main app. It's just the sharing extension that fails.
What other problems could cause error -995?
(Bear with me, I don't have rep yet for a comment so I have to answer, and notwithstanding the possibility you've found a bug, the last part I'm adding might help others)
When you're using an NSURLSession any background upload/download that completes will launch your main application. This is detailed in the Common Scenarios page.
As you show you've done, you need to set the NSURLSessionConfiguration
with a sharedContainerIdentifier
:
let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(uniqueId)
configuration.sharedContainerIdentifier = Config.appGroupName
urlSession = NSURLSession.init(configuration: configuration, delegate: self, delegateQueue: nil)
You also need to ensure that both your app extension and your main app are all triple-checked in the 'App Groups' option in Xcode (I'm looking at Xcode 8.1), which means:
- The app group name is the same for both app and extension(!)
- the check beside
Add the App Group entitlements in the entitlement file
- the check beside
Add the App Groups feature to your App ID
- the check beside
Add App Groups to your App ID
And the checks need to be there on both app and extension.
I'm a bit rusty on adding these but my recollection is these aren't listed in the right order, e.g. you have to 'Add App Groups to your ID' before you can check them in both app and extension, but I could be wrong.
Advanced - Thirdparty libraries in app extensions.
Looking at the github project nst/STTwitter
, a third-party Twitter REST library, they needed to add a configurable group ID to allow setting the NSURLSessionConfiguration
sharedContainerIdentifier
to the library user's group ID.
I may again be mistaken but this seems like it would be a general problem when using thirdparty libraries in an app extension - e.g. I've just now come across this error when trying to use the ChromeCast SDK and this could be the kick in the pants.