Background execution in iOS The following class BackgroundExecutable is to be used to take a function f and return a function f' where f' asks iOS for background execution. f takes a completion closure which it uses to end the background execution.

class BackgroundExecutable {
  var identifier: UIBackgroundTaskIdentifier
  let f: (() -&gt; Void) -&gt; Void

  init(f: (completion: () -&gt; Void) -&gt; Void) {
    self.f = f
    self.identifier = UIBackgroundTaskInvalid
  }

  func execute() {
    let application = UIApplication.sharedApplication()
    identifier = application.beginBackgroundTaskWithExpirationHandler {
      application.endBackgroundTask(self.identifier)
    }
    f(endBackgroundTask)
  }

  func endBackgroundTask() {
    UIApplication.sharedApplication().endBackgroundTask(identifier)
  }
}

func backgroundExecutable(f: (() -&gt; Void) -&gt; Void) -&gt; (() -&gt; Void) {
  let b = BackgroundExecutable(f: f)
  return b.execute
}


Usage:

func F(completion: () -&gt; Void) {
  println("F Called")
  completion()
}

let newF = backgroundExecutable(F)
func backgroundExecutable(f: (() -&gt; Void) -&gt; Void) -&gt; (() -&gt; Void)



This is madness and it takes a number of mental gymnastics to figure out what is going on here.

This method takes, as its only (and poorly named) argument, a closure which returns void and takes, as its single argument, a closure which returns void from taking no arguments.  Then this method returns a closure which takes no arguments and returns void.

Even writing it out in plain-English, it's hard to understand what's actually going on.  And I'm left scratching my head trying to figure out why we even need a closure which takes a closure as its argument.

The major problem here is that we're using this closure's closure argument to pass the call to endBackgroundTask(), a method which must be called, or we risk the OS killing our app.

Your class is attempting to provide a convenient wrapper to handling the background means for executing code while your application is in the background.  But your class hasn't made things any more convenient then what they already are.  It only makes them more nested and complicated.

So let's look at execute for a second, shall we?


func execute() {
    let application = UIApplication.sharedApplication()
    identifier = application.beginBackgroundTaskWithExpirationHandler {
        application.endBackgroundTask(self.identifier)
    }
    f(endBackgroundTask)
}



The crux of this is that endBackgroundTask, another method of this class (which should perhaps be private) is passed in as the closure the the user's background executing closure.  If they don't call the closure that's passed in (and call it only as the last thing their closure does), there will be unintended problems going on here.

But why do that?  We can instead do this:

f()
endBackgroundTask()


That's a step in the right direction.  We're no longer relying on the caller to end the background task.



But there's another problem here.  What if we call execute multiple times and on multiple threads?  The identifier will be different each time we call execute, and each time it overwrites the previous identifier.  So all the previous background tasks can't be stopped, and so the OS will eventually kill our app for running indefinitely in the background.

Instead, we need our endBackgroundTask method to take a string argument... the identifier of the task we're stopping.  And we need to not rely on a string variable for our class.  

So, it needs to look more like this:

f()
endBackgroundTask(identifier)


At this point, I'm not entirely certain the point of the class at all when a single method with just a handful of lines can manage it:

func backgroundExecute(worker: () -&gt; Void) -&gt; Void {
    let application = UIApplication.sharedApplication()
    identifier = application.beginBackgroundTaskWithExpirationHandler {
        // you can't call endBackgroundTask here, and you don't need to
        // here you should put code to handle the task running out of time before it is complete
    }
    worker()
    application.endBackgroundTask(identifier)
}