ios - swift 。在后台运行异步下载并让用户与 UI 交互

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

以下函数用于将应用程序与来自服务器的 json 数据同步,如果内容有一段时间没有更新,这将花费几分钟。至于现在,该应用程序会阻止主 UI 并告诉用户它正在更新新内容并出现一个纺车。 我想删除“更新数据的阻塞覆盖..文本和旋转轮”并让应用程序下载 json 并将其同步到后台的数据库,以便用户可以继续与 UI 交互。

我已尝试使用 dispatch_async,但 UI 一直被阻塞,直到更新完成。有人对如何实现这一目标有任何建议吗?

我将代码精简到相关点,并在 ApiWrapper 执行网络作业的地方添加了 updateData 函数。

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

……

最佳答案

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

基本上,

dispatch_async(dispatch_get_global_queue(priority, 0)) {}

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

dispatch_async(dispatch_get_main_queue()) {}

swift 4 更新

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
    }
}

关于ios - swift 。在后台运行异步下载并让用户与 UI 交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35817414/

相关文章:

c# - 使用串行端口和 ReadAsync 超时的正确方法

c - 将输入重新打印到 C 中的终端

c# - 关于异步返回类型

android - 电晕 : Check nil value before call onComplete event

ios - SwiftUI使用步进器动态添加/删除TextField

ios - 试图限制iOS中UITextField的字符数

ios - 使用cellForRowAtIndexPath中的dispatch_async加载图像

ios - TableView 填充相同的字符串

swift - NSButton 组作为单选按钮组

swift - 尝试加载 skspritenode 两次后应用程序崩溃?