【问题标题】:Json and variable scopeJson 和变量范围
【发布时间】:2017-04-03 12:04:59
【问题描述】:

我的错误应该很明显,但我找不到;

我有一个全局变量初始化了我的类的开头:

class InscriptionStageViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var lesSemaines = [String]()

我尝试使用该函数用一个遥远的 json 文件填充这个数组

func getSemainesStages(){
        let url = URL(string: "http://www.boisdelacambre.be/ios/json/semaines.json")
        let task = URLSession.shared.dataTask(with: url!){ (data, response, error) in
            if let content = data {
                do {
                    let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
                    let listeSemaines = myJson["semaine"] as! [[String:AnyObject]]
                    //print(listeSemaines)

                    for i in 0...listeSemaines.count-1 {
                        var tabSem = listeSemaines[i]
                        let intituleSemaine:String = tabSem["intitule"] as! String
                        //let dateSemaine:String = tabSem["date"] as! String

                        DispatchQueue.main.sync
                            {

                                self.lesSemaines.append(intituleSemaine)
                            }

                    }

                } catch
                {
                    print("erreur Json")
                }
            }

        }
        task.resume()
    }

当我在 viewDidLoad 中调用我的函数然后打印我的全局数组时,它是空的(URL 正确,json 数据被正确读取,当我读取循环中数组中附加的数据时,它打印(所以)需要的价值...)

提前致谢

【问题讨论】:

  • 你什么时候阅读lesSemaines?因为我猜你的问题是由于代码的异步部分造成的。
  • 有什么问题?数组为空?
  • 在我的viewDidLoad中,我调用了函数,然后尝试打印数组,结果是空的(当我直接在函数中打印就可以了)

标签: ios json swift swift3


【解决方案1】:

下载需要时间。介绍另一种方法:

func updateUi() {
    print(lesSemaines)
    //pickerView.reloadAllComponents()
}

并在下载完成后调用它

func getSemainesStages(){
    // ... your code 
    let task = URLSession.shared.dataTask(with: url!){ (data, response, error) in
        // ... your code        
        for tabSem in listeSemaines{
             guard let intituleSemaine = tabSem["intitule"] as? String else {
                print("erreur Json")
                continue
            }
            self.lesSemaines.append(intituleSemaine)    
        }

        // update UI *after* for loop
        DispatchQueue.main.async {
            updateUi()   
        }
        // ... your code
    }
}

【讨论】:

  • 覆盖 func viewDidLoad() { super.viewDidLoad() getSemainesStages() print(self.lesSemaines) }
  • 你不认为它会在打印数组之前完成 getSemainesStages() 函数吗?
  • 是的,它会的。因为下载需要时间。这就是异步调用的本质。但是当一切都完成后,用户界面会更新。这就是为什么我以一种额外的方法移动了print
  • 如何使调用同步?因为我想将该数组用于pickerView
  • 您不想让它同步,因为这会在下载时阻止您的 UI(冻结应用程序)。更新updateUi() 中的pickerView。如果需要很长时间才能获得良好的用户体验,请显示UIActivityIndicator(加载微调器)。
【解决方案2】:

我已将您的代码更新为 Swift 3。请将其替换为以下代码。

func getSemainesStages(){
    let url = URL(string: "http://www.boisdelacambre.be/ios/json/semaines.json")
    let task = URLSession.shared.dataTask(with: url!){ (data, response, error) in
        if let content = data {
            do {
                let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String: Any]
                let listeSemaines = myJson["semaine"] as! [[String: Any]]

                for i in 0...listeSemaines.count-1 {
                    var tabSem = listeSemaines[i]
                    let intituleSemaine:String = tabSem["intitule"] as! String
                    self.lesSemaines.append(intituleSemaine)
                }
                print(self.lesSemaines)
            } catch {
                print("erreur Json")
            }
        }

    }
    task.resume()
}

【讨论】:

  • 问题依旧;当函数 print (self.lesSemaines) 完美地打印所有数据。但是当我尝试打印数组时,在我的 ViewDidLoad 中,它是空的。 (我调用函数然后尝试打印数组)
  • 是的,因为当您调用视图时确实加载了它实际上是空的并且代码在后台线程上运行。如果您想在 viewDidLoad 中打印,请实现完成块或将其称为同步。
猜你喜欢
  • 2014-01-31
  • 2017-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-26
  • 2010-12-21
  • 2012-03-30
相关资源
最近更新 更多