Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run operations in background while an iOS application is in foreground

I have a JSON file populated with strings data in Documents Directory. In user Interface of application there is a UIButton. On button press, a new string appends into the JSON file.

Now I am looking for any iOS Service that helps me to send these strings (from JSON file) to the server using swift. And this service should be totally independent of my code. The point is when I press a UIButton, the first step is a string is saved to the JSON file then service should take this string and send it to server if Internet is available.

When a string sent successfully, it should be removed from the JSON file. This service should track after every 30 seconds if there is any string saved into JSON file, then send it to server.

I Googled and found background fetch but It triggers performFetchWithCompletionHandler function automatically and I cannot know when iOS triggers it. I want to trigger this kind of service my self after every 30 seconds.

like image 721
user3314286 Avatar asked Aug 01 '16 14:08

user3314286


2 Answers

Review the Background Execution portion of Apple's App Programming Guide for iOS.

UIApplication provides an interface to start and end background tasks with UIBackgroundTaskIdentifier.

In the top level of your AppDelegate, create a class-level task identifier:

var backgroundTask = UIBackgroundTaskInvalid

Now, create your task with the operation you wish to complete, and implement the error case where your task did not complete before it expired:

backgroundTask = application.beginBackgroundTaskWithName("MyBackgroundTask") {
    // This expirationHandler is called when your task expired
    // Cleanup the task here, remove objects from memory, etc

    application.endBackgroundTask(self.backgroundTask)
    self.backgroundTask = UIBackgroundTaskInvalid
}

// Implement the operation of your task as background task
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
    // Begin your upload and clean up JSON
    // NSURLSession, AlamoFire, etc

    // On completion, end your task
    application.endBackgroundTask(self.backgroundTask)
    self.backgroundTask = UIBackgroundTaskInvalid
}
like image 113
JAL Avatar answered Oct 25 '22 23:10

JAL


What I have done is I just uses the approach discussed by JAL above.

these were the three methods which I used

    func reinstateBackgroundTask() {
        if updateTimer != nil && (backgroundTask == UIBackgroundTaskInvalid) {
            registerBackgroundTask()
           }
    }
    func registerBackgroundTask() {
        backgroundTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler {
            [unowned self] in
            self.endBackgroundTask()
        }
        assert(backgroundTask != UIBackgroundTaskInvalid)
    }

    func endBackgroundTask() {
        NSLog("Background task ended.")
        UIApplication.sharedApplication().endBackgroundTask(backgroundTask)
        backgroundTask = UIBackgroundTaskInvalid
    }

where updateTimer is of type NSTIMER class The above functions are in my own created class named "syncService" This class has an initialiser which is

init(){
  NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.reinstateBackgroundTask), name: UIApplicationDidBecomeActiveNotification, object: nil)

        updateTimer = NSTimer.scheduledTimerWithTimeInterval(30.0, target: self, selector: #selector(self.syncAudit), userInfo: nil, repeats: true)
        registerBackgroundTask()

 }

Then I just called this class and the whole problem is solved.

like image 25
user3314286 Avatar answered Oct 26 '22 00:10

user3314286