2017-02-25 7 views
0

私はSwiftの初心者です。私は今年初めからそれをやってきました...私は外部のJSONファイルからデータを取り出し、それをUILabelsに入力する単純なアプリケーションを作ろうとしています。私は引っ張って、配列に追加するデータを得ました。ここからは、スコープを終了し、他の場所では使用できないようです...私はそれに応じてデータを保持するための構造体を作成しました。ご覧のとおり、視覚的に何が起こっているかを見るためのプリントマーカーを追加しました。JSON Parse - Swiftからのデータの返却

struct GlobalTestimonialData { 
     var testimonialsText: [String] 
     var customerNames: [String] 
     var companyNames: [String] 
    } 

    var TestimonialData = GlobalTestimonialData(testimonialsText: [""], customerNames: [""], companyNames: [""]) 

    func getData() { 
     let requestURL: URL = URL(string: "https://szadydesigns.com/test/mobileapp/testimonials.php")! 
     let urlRequest = URLRequest(url: requestURL as URL) 
     let session = URLSession.shared 
     let task = session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in 

      let httpResponse = response as! HTTPURLResponse 
      let statusCode = httpResponse.statusCode 

    if (statusCode == 200) { 
       print("File has been downloaded!") 
       do { 

        let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) 

        print("JSON Serialized") 

        if let JSONfile = json as? [String: AnyObject] { 
         print("JSON Reading") 
         if let testimonial = JSONfile["testimonial"] as? [String] { 
          print("Testimonials Read") 
          TestimonialData.testimonialsText.append(contentsOf: testimonial) 
          print(TestimonialData.testimonialsText) 
          print("Inside of loop Testimonial Text Number: \(TestimonialData.testimonialsText.count)") 

          if let name = JSONfile["name"] as? [String] { 
           print("Names Read") 
           TestimonialData.customerNames.append(contentsOf: name) 
           print(TestimonialData.customerNames) 
           print("Inside of loop Customers Number: \(TestimonialData.customerNames.count)") 
          } 
          if let company = JSONfile["company"] as? [String] { 
           print("Companies Read") 
           TestimonialData.companyNames.append(contentsOf: company) 
           print(TestimonialData.companyNames) 
          } 
          print("Companies: \(TestimonialData.companyNames)") 
         } 
         print("COMPANIES: \(TestimonialData.companyNames)") 
        } 
        print("Companies AGIAN: \(TestimonialData.companyNames)") 
       }catch { 
        print("Error with Json: \(error)") 
       } 
       print("Companies AGIAN AGAIN : \(TestimonialData.companyNames)") 
      } 
      print("Companies AGIAN AGAIN AGAIN: \(TestimonialData.companyNames)") 
     } 

     //Loses Scope 
     print("Companies AGIAN TIMES : \(TestimonialData.companyNames)") 
     task.resume() 

     print("Outside of loop Customers Number: \(TestimonialData.customerNames.count)") 
     print("Outside of loop Testimonial Text Number: \(TestimonialData.testimonialsText.count)") 
     print(TestimonialData.companyNames) 
    } 

私は私は本当に簡単な何かが欠けてる知っている...しかし、私は途方に暮れてよ...すべてのヘルプ/情報感謝です!

まず:

+0

ストーリーボードを使用していますか?あなたのコードは、ストーリーボードにリンクするカスタムクラス内にはありません。そのため、データをどのように表示するのか混乱します。 – Bawpotter

+0

'dataTask'が非同期に動作するので、' task.resume() 'の後の行はコールバックを呼び出すために欠けています。あなたのコードにもう一つの大きなデザインミスがあります:カスタム構造体は、複数の配列を保持するのではなく、それぞれ**の**証言のための** one **インスタンスを作成することになっています。 Swift 3ではJSON辞書のためにネイティブ 'URL'、' URLRequest'、 '[String:Any]'を使います。 – vadian

+0

はい、ストーリーボードを使用しています。上記のコードは、独自の.Swiftファイルで、ViewControllerをクリーンに保ちます。 – szady

答えて

0

は、このコードのいくつかの問題があり、あなたが受けているJSONはあなたのコードが期待する形式ではありません。ルートオブジェクトは辞書ではなく配列です。

if let JSONfile = json as? [[String: String]] { 

if let JSONfile = json as? [String: Any] { 

変更また、これは、各項目をループする必要があります。辞書の定義が[String:Any][String:String]からas? String文から変更されていたよう

print("JSON Reading") 
for item in JSONfile { 

いずれかの必要はなくなりました。

2番目://Loses Scope行以降のビットのビットがの最初のになるかどうかわかっているかどうかわかりません(おそらく既にそうです)。 Companies AGIAN AGAINおよびCompanies AGIAN AGAIN AGAIN行の前。

ページの下にあるかもしれませんが、上の行は、ファイルがダウンロードされた後に実行されるクロージャの中にあり、他の行が既に実行された後に後で実行されます。


完全固定コードです(これをコピーしてXcodeプレイグラウンドに貼り付けて動作させることができます)。

// Xcode 8.2, Swift 3 
import Cocoa 
import PlaygroundSupport 

// Required for the download to work. 
PlaygroundPage.current.needsIndefiniteExecution = true 


struct GlobalTestimonialData { 
    var testimonialsText: [String] 
    var customerNames: [String] 
    var companyNames: [String] 
} 

var testimonialData = GlobalTestimonialData(testimonialsText: [], customerNames: [], companyNames: []) 

func getData() { 
    let requestURL: NSURL = NSURL(string: "https://szadydesigns.com/test/mobileapp/testimonials.php")! 
    let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL as URL) 
    let session = URLSession.shared 
    let task = session.dataTask(with: urlRequest as URLRequest) { (data, response, error) in 

     let httpResponse = response as! HTTPURLResponse 
     let statusCode = httpResponse.statusCode 
     if (statusCode == 200) { 
      print("File has been downloaded!") 
      do { 
       let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) 

       print("JSON Serialized") 

       if let JSONfile = json as? [[String: String]] { 
        print("JSON Reading") 
        for item in JSONfile { 
         if let testimonial = item["testimonial"] { 
          testimonialData.testimonialsText.append(testimonial) 

          if let name = item["name"] { 
           testimonialData.customerNames.append(name) 
          } 
          if let company = item["company"] { 
           testimonialData.companyNames.append(company) 
          } 
         } 
        } 
       } 
      } catch { 
       print("Error with Json: \(error)") 
      } 
     } 
     print("Companies Last: \(testimonialData.companyNames)") 
     print(" ") 
     print(testimonialData) 
    } 

    //Loses Scope 
    print("Companies 1 : \(testimonialData.companyNames)") 
    task.resume() 

    print("Before the download of the JSON Customer names count: \(testimonialData.customerNames.count)") 
    print("Before the download of the JSON Testimonial Text Number: \(testimonialData.testimonialsText.count)") 
    print(testimonialData.companyNames) 
} 

getData() 

この出力が表示され、何が起こっているのかを説明するのに役立ちます(実際の会社名は削除しましたが)。

Companies 1 : [] 
Before the download of the JSON Customer names count: 0 
Before the download of the JSON Testimonial Text Number: 0 
[] 
File has been downloaded! 
JSON Serialized 
JSON Reading 
Companies: ["REMOVED_1", "REMOVED_2", "REMOVED_3", "REMOVED_4"] 
関連する問題