迅速。在后台运行异步下载,让用户与UI进行交互

时间:2016-03-05 17:35:09

标签: ios swift asynchronous grand-central-dispatch dispatch-async

以下函数用于将应用程序与来自服务器的json数据同步,如果内容尚未更新一段时间,则需要几分钟。至于现在,应用程序阻止主UI并告诉用户它用新内容更新并出现旋转轮。 我想删除"阻止覆盖,更新数据..文本和旋转轮"让应用程序下载并在后台将json同步到数据库,以便用户可以继续与UI进行交互。

我已尝试使用dispatch_async,但在更新完成之前,UI一直被阻止。有没有人对如何实现这个有任何建议?

我将代码剥离到相关点并添加了updateData函数,其中ApiWrapper执行网络作业。

func syncData(now: Bool) {

    var synced : Bool = false

    if ((NSUserDefaults.standardUserDefaults().objectForKey("lastSyncApp")) != nil) {
        var interval = 0
        if ((NSUserDefaults.standardUserDefaults().objectForKey("intervalSyncValue")) != nil) {
            interval = NSUserDefaults.standardUserDefaults().objectForKey("intervalSyncValue") as! Int
        }
        else{
            interval = 86400
        }
        let date = NSUserDefaults.standardUserDefaults().objectForKey("lastSyncApp") as! NSDate
        var timestamp = UInt64(floor(date.timeIntervalSince1970))
        //Create final date
        let lastsyncTimestampDate : UInt64 = timestamp + UInt64(interval)

        var nowTimestampDate = UInt64(floor(NSDate().timeIntervalSince1970))

        if ((nowTimestampDate > lastsyncTimestampDate) || now) {


                synced = true
                let formatter = NSDateFormatter()
                formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

                //MRProgressOverlayView.showOverlayAddedTo(self.window, title: "Aggiorno dati...", mode: MRProgressOverlayViewMode.Indeterminate, animated: true, tintColor: UIColor.blackColor())

                self.downloadDate = formatter.stringFromDate(date)
                NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("updateData:"), userInfo: nil , repeats: false)



    ….}        








func updateData(timer: NSTimer!) {


    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_async(dispatch_get_global_queue(priority, 0)) {
        // do some task



    var ApiWrapper = API()

    let date = self.downloadDate


            ApiWrapper.model.deleteNews()
            ApiWrapper.model.resetNewsFetch()



            //var ApiWrapper = API()

... .. }

1 个答案:

答案 0 :(得分:2)

我在这段代码中看不到你在哪里使用后台线程,但这里有一个非常简洁的example如何做到这一点。

基本上,

dispatch_async(dispatch_get_global_queue(priority, 0)) {}

会让你进入后台线程,如果你需要从那里更新UI,请确保在主线程上执行该代码:

dispatch_async(dispatch_get_main_queue()) {}

Swift 4 UPDATE

DispatchQueue.global(qos: [Desired QoSClass]).async {
    // This code is executing on a background thread at 
    // your desired quality of service level

    DispatchQueue.main.async {
         // Code to be executed on the main thread here
    }
}