6

I'm not clear on how to use this properly but had seen other people doing this type of thing:

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
    manager.sharedInstance.backgroundCompletionHandler = completionHandler
}

In our similar implementation, at this point completionHandler is partial apply forwarder for reabstraction thunk helper...

Where manager is (despite being a singleton) essentially:

let configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("com.ourcompany.app")
let manager = Alamofire.Manager(configuration: configuration)

However this causes the following warning to be printed in the console:

Warning: Application delegate received call to -application:handleEventsForBackgroundURLSession:completionHandler: but the completion handler was never called.

I set a breakpoint here and at this point the message is already visible in the console and backgroundCompletionHandler is nil.

We're building against the iOS 9 SDK with Xcode 7.0 and currently using Alamofire 2.0.2

I originally thought this was introduced when we merged our Swift 2.0 branch but I'm also seeing the message with an earlier commit using Xcode 6.4 against the iOS 8 SDK.


Update 1

To address @cnoon's suggestions:

  • The identifier matches - the configuration and manager are set inside a singleton so there's no way for it to be wrong.
  • When adding and printing inside of didSet on backgroundCompletionHandler in the Manager class, the message is logged before the warning.
  • When printing inside of the closure set to sessionDidFinishEventsForBackgroundURLSession on the delegate inside the Manager class, the message is printed after the warning.
  • When overriding sessionDidFinishEventsForBackgroundURLSession and printing inside of it before calling backgroundCompletionHandler, the message is printed after the warning.
  • As for verifying I have my Xcode project set up correctly for background sessions, I'm not sure how to do that and couldn't find any documentation on how to do so.

I should note that when trying to upload some screenshots from my phone I was initially unable to reproduce this issue in order to try these suggestions.

It was only after trying to share some photos that I was able to reproduce this again. I'm not sure or the correlation (if any) but it may be related to the photos taking longer to upload.


Update 2

The UIBackgroundModes are set exactly as @Nick described, and calling completionHandler() directly inside of application:handleEventsForBackgroundURLSession:completionHandler: does not display the warning.


Update 3

So, it appears I overlooked an small but important detail. There's a wrapper around Alamofire.Manager that doesn't expose it directly. The relevant part of its implementation looks like this:

private var manager: Manager

public var backgroundCompletionHandler: (() -> Void)? {
    get {
        return manager.backgroundCompletionHandler
    }
    set {
        manager.backgroundCompletionHandler = backgroundCompletionHandler
    }
}

and setting the completion handler in the AppDelegate executes that code path.

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
    myManager.sharedInstance.backgroundCompletionHandler = completionHandler
}

I've confirmed that the following change to expose the instance of Alamofire.Manager and access it directly does not produce the warning:

public var manager: Manager

//    public var backgroundCompletionHandler: (() -> Void)? {
//        get {
//            return manager.backgroundCompletionHandler
//        }
//        set {
//            manager.backgroundCompletionHandler = backgroundCompletionHandler
//        }
//    }

and in the AppDelegate:

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
    myManager.sharedInstance.manager.backgroundCompletionHandler = completionHandler
}

Based on this it appears that using a computed property to proxy the completion handler is the cause of the issue.

I'd really prefer not to expose this property and would love to know of any workarounds or alternatives.

Paul Young
  • 1,489
  • 1
  • 15
  • 34
  • For project configuration, this is what we do. That said specific documentation is difficult to find on this topic. ` UIBackgroundModes fetch remote-notification ` – Nick Sep 27 '15 at 03:36

1 Answers1

1

It appears as though everything you are doing is correct. I have an example app that does exactly what you've described that works correctly and does not throw the warning you are seeing. I'm guessing you still have some small error somewhere. Here are a few ideas to try out:

  • Verify the identifier matches the identifier of your background session
  • Add a didSet log statement on the backgroundSessionHandler in the Manager class temporarily to verify it is getting set
  • Add a log statement into the sessionDidFinishEventsForBackgroundURLSession to verify it is getting called as expected
  • Override the sessionDidFinishEventsForBackgroundURLSession on the delegate and manually call the backgroundSessionHandler
  • Verify you have your Xcode project set up correctly for background sessions

Update 2

Your computed property is wrong. Instead it needs to set the backgroundCompletionHandler to newValue. Otherwise you are never setting it to the new value correctly. See this thread for more info.

cnoon
  • 16,575
  • 7
  • 58
  • 66
  • I'd definitely try to set the `UIBackgroundModes` as @Nick suggests. I'd also try to call the completion closure pass in the `AppDelegate` manually just to verify that does in fact stop the warning. If that doesn't stop the warning, then your chasing the wrong issue and it's not a problem with Alamofire at all, but instead most likely a project configuration issue. – cnoon Sep 27 '15 at 18:58
  • Thanks for continuing to look into this. Would love to know if you can reproduce the issue using my approach in the latest update. – Paul Young Sep 28 '15 at 01:52
  • Yep. This was not intentional and just a dumb mistake. Thanks again for your help! – Paul Young Sep 28 '15 at 18:58