2017-04-03 8 views
0

私のエラーははっきりしているはずですが、私はそれを見つけることができません。Jsonと可変スコープ

私はグローバル変数は、私のクラスの始まりを初期化してきました:

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

私は私を呼び出すと、その関数に

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

を使って遠くのJSONファイルで、この配列を移入してみてください関数は、viewDidLoadで、次に私はグローバル配列を印刷する、それは空です(URLは正しい、jsonデータが正しく読み取られ、ループ内の配列に追加されたデータを読み取るときに、(必要)値を印刷.. )

ありがとうございます。

+1

あなたは 'lesSemaines'を読まないとき?あなたの問題は、コードの非同期部分に起因すると思います。 – Larme

+0

問題点は何ですか?アレイは空ですか? –

+0

私のviewDidLoadでは、関数を呼び出して配列を印刷しようとしましたが、空です(関数で直接印刷すると問題ありません) –

答えて

0

ダウンロードには時間がかかります。別Methodeの紹介:

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

オーバーライド(){ super.viewDidLoad() getSemainesStages() プリント(self.lesSemaines) } –

+0

は、あなたはそれが配列を印刷する前に、getSemainesStages()関数を終了することを考えてはいけませんか? –

+0

はい、そうです。ダウンロードには時間がかかります。これが非同期呼び出しの性質です。しかし、すべてが完了したらUIが更新されます。それで私は余分な方法で 'print'を動かしました。 – shallowThought

0

私はあなたのコードを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() 
} 
+0

問題はまだあります。 print(self.lesSemaines)関数は、すべてのデータを完全に印刷します。しかし、私のViewDidLoadで配列を印刷しようとすると、空です。 (私は関数を呼び出すと、配列を印刷しようとします) –

+0

はい、あなたがビューを呼び出すと、実際に空のロードされ、コードがバックグラウンドスレッド上で実行されるためです。 viewDidLoadで印刷する場合は、補完ブロックを実装するか、それをsyncと呼んでください。 viewDidLoad FUNC –