0

I have a situation where i am using background fetch to call my data sync process, As the sync function is a heavy task, it is executed in a background thread.

here is my code,

func application(application: UIApplication, performFetchWithCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    print("Background Fetch")
    Utilities.syncCompleted = false // declared as :> static var syncCompleted:Bool = false
    BackgroundSync().startSync() // heavy background task, and iam updating [Utilities.syncCompleted = true) on thread completion
    while Utilities.syncCompleted == false {
        NSThread.sleepForTimeInterval(1) // sleep for sometime
    }
    if Utilities.syncCompleted{
        completionHandler(UIBackgroundFetchResult.NewData)
    }else {
        completionHandler(UIBackgroundFetchResult.NoData)
    }
}

Now i have some questions :

  1. As background fetch is of 30 sec, if my task is not completed in 30 sec then what happens, because i wont be able to set completionHandler to .NoData or .Failure

  2. Is there is any default completionHandler value which is set (like .NoData) if developer does not specify in 30 sec.

  3. Is there any other better way to do this.

Thanks in advance

Tej Pratap
  • 144
  • 1
  • 10
  • If a background fetch takes too long, the system shuts it down. Passing .Failure is fine (unless you do it all the time), but when system shuts down your process I'd expect priority of the next fetch to be lower. And I think your way of doing this is fine. – Yaroslav Sep 21 '15 at 10:19

1 Answers1

0

Actually, if you are starting a backgroundTask, you are not limited to 30s, but to 10 minutes or whatever is the current limit for those.

Background fetch is a full-on starting of your app, including access to the main thread, UI changes etc. Essentially equivalent to starting the app minus the actual on-screen display. Background task are much more limited in what you can do but are allowed to take longer.

Thus in your case I would not care much about returning proper value of NoData or NewData. Start your sync as background task and call completionHandler(UIBackgroundFetchResult.NewData).

If you want to get as fair to the system as possible, you can check application.backgroundTimeRemaining and then schedule dispatch_after just before that expiring. So if you task finished before it, it will send NewData/NoData as received, but if it takes longer, then your dispatch_after block will send NewData and be done with it.

Aleksandar Vacić
  • 4,433
  • 35
  • 35