12

我在文档目录中有一个用字符串数据填充的 JSON 文件。在应用程序的用户界面中有一个 UIButton。按下按钮时,一个新字符串会附加到 JSON 文件中。

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

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

我用谷歌搜索并找到了后台提取,但它会performFetchWithCompletionHandler自动触发功能,我不知道 iOS 何时触发它。我想每 30 秒后自己触发一次这种服务。

4

5 回答 5

13

查看 Apple 的 iOS 应用程序编程指南的后台执行部分。

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
}
于 2016-09-15T14:18:35.770 回答
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()

 }

然后我只是调用了这个类,整个问题就解决了。

于 2016-09-20T11:20:11.580 回答
3
 DispatchQueue.global(qos: .background).async { // sends registration to background queue

 }
于 2018-01-05T19:32:48.790 回答
1

请参考 NSURLSessionUploadTask 可能对您有所帮助。

于 2016-09-20T07:04:44.370 回答
0

这是 JAL 的答案的 swift 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.
    }
于 2018-06-22T06:34:52.293 回答