2017-02-25 147 views
0

所以我和斯威夫特一個新手,並稍微與一般的編程。我只是一直在做這件事,因爲第一年的......我試圖做一個簡單的應用程序,從外部JSON文件中提取數據,並將其輸入到UILabels。我得到的數據拉,並追加到一個數組。從這裏,它似乎退出了範圍,不能在其他地方使用......我創建了一個結構來保存數據。正如你所看到的,我已經添加了打印標記來直觀地看到發生了什麼。從JSON解析返回數據 - 斯威夫特

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

你缺少調用回調,task.resume後'打印線()'總會打印*沒有數據*'因爲工作dataTask'異步。在你的代碼中還有另一個大的設計錯誤:一個自定義結構應該爲每個**證明創建一個**實例,而不是保存多個數組。在Swift 3中,爲JSON字典使用原生的'URL','URLRequest'和'[String:Any]'。 – vadian

+0

是的,我正在使用故事板。上面的代碼是它自己的.Swift文件,以保持ViewController'乾淨'。 – szady

回答

0

沒有與此代碼的幾個問題:

第一:您收到的JSON是不是在你的代碼期望的格式。根對象不是字典而是數組。

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

變化

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

這也需要你遍歷每個項目。

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

正如字典中的定義已經從[String:Any][String:String]as? String語句改變是不再被需要。

二:我不知道你是否意識到這一點(也許你已經這樣做了),但//Loses Scope線運行第一後的碼位。在Companies AGIAN AGAINCompanies 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"]