如何在iOS应用程序处于前台时在后台运行操作

时间:2016-08-01 14:10:27

标签: ios swift synchronization background-fetch

我在Documents Directory中填充了字符串数据的JSON文件。在应用程序的用户界面中有一个UIButton。按下按钮,新的字符串将附加到JSON文件中。

现在我正在寻找任何帮助我使用swift将这些字符串(从JSON文件)发送到服务器的iOS服务。这项服务应完全独立于我的代码。 关键是当我按下UIButton时,第一步是将字符串保存到JSON文件,然后服务应该使用此字符串并在Internet可用时将其发送到服务器。

成功发送字符串后,应将其从JSON文件中删除。 如果有任何字符串保存到JSON文件中,则此服务应每30秒跟踪一次,然后将其发送到服务器。

我用Google搜索并找到background fetch但它会自动触发performFetchWithCompletionHandler函数,我无法知道iOS何时触发它。我想每30秒就触发一次这种服务。

5 个答案:

答案 0 :(得分:11)

查看Apple的iOS应用程序编程指南的Background Execution部分。

UIApplication提供了使用UIBackgroundTaskIdentifier开始和结束后台任务的界面。

AppDelegate的顶层,创建一个类级别的任务标识符:

var backgroundTask = UIBackgroundTaskInvalid

现在,使用您希望完成的操作创建任务,并实现任务在过期之前未完成的错误情况:

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
}

答案 1 :(得分:4)

我所做的是我只使用上面JAL讨论的方法。

这些是我使用的三种方法

    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
    }

其中updateTimer的类型为NSTIMER 上面的函数在我自己创建的名为“syncService”的类中 这个类有一个初始化器

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()

 }

然后我就打电话给这个班,整个问题就解决了。

答案 2 :(得分:1)

请参考NSURLSessionUploadTask对您有帮助。

答案 3 :(得分:1)

 DispatchQueue.global(qos: .background).async { // sends registration to background queue

 }

答案 4 :(得分:0)

这是日航的答案的第4版

  extension UIApplication {
  /// Run a block in background after app resigns activity
   public func runInBackground(_ closure: @escaping () -> Void, expirationHandler: (() -> Void)? = nil) {
       DispatchQueue.main.async {
        let taskID: UIBackgroundTaskIdentifier
        if let expirationHandler = expirationHandler {
            taskID = self.beginBackgroundTask(expirationHandler: expirationHandler)
        } else {
            taskID = self.beginBackgroundTask(expirationHandler: { })
        }
        closure()
        self.endBackgroundTask(taskID)
    }
  }

  }

用法示例

UIApplication.shared.runInBackground({
        //do task here
    }) {
       // task after expiration.
    }