用Swift 3解析JSON

用Swift 3解析JSON

问题描述:

我一直试图让这个工作两个星期。它使用Swift 2在iOS 9上工作,但现在看起来没有任何理由。我添加了print("[DEBUG] I was here 1/2/3/4")来调试代码,打印出的所有代码都是[DEBUG] I was here 1。有任何想法吗?它让我疯狂。用Swift 3解析JSON

func downloadData() { 
    //clear the arrays 
    arrayPosts = [String]() 
    arrayLinks = [String]() 
    arrayConditions = [String]() 
    arrayIDs = [String]() 
    //debug 
    print("[DEBUG] I was here: 1") 

    //baseURL is a string with URL to JSON Endpoint 
    let url = URL(string: baseURL) 
    URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in 
     if error != nil { 
      print("[ERROR] [DEBUG] Error with connection: \(error)") 
     } else { 
      do { 
       //debug 
       print("[DEBUG] I was here: 2") 
       if let json = try JSONSerialization.jsonObject(with: data!, options:[.mutableContainers, .allowFragments]) as? [[String: Any]] { 
        for item in json { 
         //debug 
         print("[DEBUG] I was here: 3") 
         if let startTime = item["current_time"] as? Int { 
          if self.defaults.integer(forKey: "startTime") == 0 { 
           self.defaults.set(startTime, forKey: "startTime") 
          } 
         } 

         if let posts = item["posts"] as? [[String: AnyObject]] { 
          //debug 
          print("[DEBUG] I was here: 4") 
          for post in posts { 
           if let text = post["text"] as? String { 
            if let condition = post["conditions"] as? String{ 
             if let url = post["url"] as? String { 
              if let id = post["id"] as? String { 
               self.arrayPosts.append(text) 
               self.arrayConditions.append(condition) 
               self.arrayLinks.append(url) 
               self.arrayIDs.append(id) 
              } 
             } 
            } 
           } 
          } 

         } 
        } 
       } 
      } catch { 
       print("[ERROR] [DEBUG] Something went wrong during data download from the server.") 
      } 
     } 

    }).resume() 
} 

这里的JSON数据,以防万一:

{ 
    "status": "ok", 
    "num_results": "4", 
    "current_time": 1474386061, 
    "user_time": 0, 
    "posts": [ 
    { 
     "text": "If your shirt isn't tucked into your pants, then your pants are tucked into your shirt.", 
     "conditions": "4", 
     "url": "0", 
     "time": "0", 
     "id": "108" 
    }, 
    { 
     "text": "Veteran Kills Himself in Parking Lot of V.A. Hospital on Long Island", 
     "conditions": "6", 
     "url": "http://www.nytimes.com/2016/08/25/nyregion/veteran-kills-himself-in-parking-lot-of-va-hospital-on-long-island.html", 
     "time": 1472076000, 
     "id": "1472076000" 
    }, 
    { 
     "text": "Leaked Script Shows What Advisers Want Donald Trump to Say at Black Church", 
     "conditions": "6", 
     "url": "http://www.nytimes.com/2016/09/02/us/politics/donald-trump-black-voters-wayne-jackson.html", 
     "time": 1472767200, 
     "id": "1472767200" 
    }, 
    { 
     "text": "Creepy Clown Sightings in South Carolina Cause a Frenzy", 
     "conditions": "6", 
     "url": "http://www.nytimes.com/2016/08/31/us/creepy-clown-sightings-in-south-carolina-cause-a-frenzy.html", 
     "time": 1472594400, 
     "id": "1472594400" 
    } 
    ] 
} 
+0

我刚刚用假网址测试,它关系到“[DEBUG]我在这里:2“。 – Moritz

+0

是'let url = URL(string:baseURL)'nil? – Larme

+0

@EricAya理论上它应该。我再次运行它,以防万一它停在“[DEBUG]我在这里:1”。可能是其他的错误?就像我使用http而不是https一样? –

我已经找到了解决办法。我将代码移到了后台队列中。解决了这个问题。

func downloadData() { 
    //clear the arrays 
    arrayPosts = [String]() 
    arrayLinks = [String]() 
    arrayConditions = [String]() 
    arrayIDs = [String]() 
    //debug 
    print("[DEBUG] I was here: 1") 

    //baseURL is a string with URL to JSON Endpoint 
    let url = URL(string: baseURL) 
    let session = URLSession.shared 

    let task = session.dataTask(with: url!) { (data:Data?, response:URLResponse?, error:Error?) in 
     if error != nil { 
      print("[ERROR] [DEBUG] Error with connection: \(error)") 
     } else { 
      do { 
       //debug 
       print("[DEBUG] I was here: 2") 
       if let json = try JSONSerialization.jsonObject(with: data!, options:[.mutableContainers, .allowFragments]) as? [[String: Any]] { 
        for item in json { 
         //debug 
         print("[DEBUG] I was here: 3") 
         if let startTime = item["current_time"] as? Int { 
          if self.defaults.integer(forKey: "startTime") == 0 { 
           self.defaults.set(startTime, forKey: "startTime") 
          } 
         } 

         if let posts = item["posts"] as? [[String: AnyObject]] { 
          //debug 
          print("[DEBUG] I was here: 4") 
          for post in posts { 
           if let text = post["text"] as? String { 
            if let condition = post["conditions"] as? String{ 
             if let url = post["url"] as? String { 
              if let id = post["id"] as? String { 
               self.arrayPosts.append(text) 
               self.arrayConditions.append(condition) 
               self.arrayLinks.append(url) 
               self.arrayIDs.append(id) 
              } 
             } 
            } 
           } 
          } 

         } 
        } 
       } 
      } catch { 
       print("[ERROR] [DEBUG] Something went wrong during data download from the server.") 
      } 
     } 

    } 
    task.resume() 
} 
+0

这似乎并不奏效。它停在“[DEBUG]我又来了1”。 –

试试下面的代码:

import UIKit 

class ViewController: UIViewController { 

    var arrayPosts = [String]() 
    var arrayLinks = [String]() 
    var arrayConditions = [String]() 
    var arrayIDs = [String]() 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     self.downloadData() 

    } 

    func downloadData() 
    { 
     let url = NSURL(string: "http://getmydetails.pe.hu/test/parsejsonswift3.php") //Provided JSON data on my server. i don't know how longer it is present there!. 
     let request = NSMutableURLRequest(url: url! as URL) 

     let task = URLSession.shared.dataTask(with: request as URLRequest) { data,response,error in 
     guard error == nil && data != nil else 
     { 
      print("Error:",error) 
      return 
      } 

      let httpStatus = response as? HTTPURLResponse 

      if httpStatus!.statusCode == 200 
      { 
       if data?.count != 0 
       { 
        let responseString = try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary //because JSON data started with dictionary. Not an array 
        let status = responseString["status"] as! String 

        if status == "ok" 
        { 
         print("Status is :", status) 

         let timevar = responseString["current_time"] //not specified as String or Int 
         print(String(describing: timevar)) // print by converting anyobject to string 

         if let posts = responseString["posts"] as? [AnyObject] // posts started with array 
         { 
         for post in posts 
          { 
           let text = post["text"] as! String //specify as String 
           print(text) 

           let condition = post["conditions"] as! String 
           let url = post["url"] as! String 
           let id = post["id"] as! String 
           DispatchQueue.main.sync 
           { 

            self.arrayPosts.append(text) 
            self.arrayConditions.append(condition) 
            self.arrayLinks.append(url) 
            self.arrayIDs.append(id) 

            //optional to check 
            self.afterJSON() 
           } 
          } 
         } 
         else 
         { 
          print("I could not find post array") 
         } 
        } 
        else 
        { 
         print("Status is not Okay!") 
        } 
       } 
       else 
       { 
        print("No data got from url!") 
       } 
      } 
      else 
      { 
       print("error httpstatus code is :",httpStatus!.statusCode) 
      } 
     } 
     task.resume() 
    } 

    func afterJSON() 
    { 
     print("Posts are:\n\t\t",arrayPosts) 
     print("Conditions are:\n\t\t",arrayConditions) 
     print("Links are:\n\t\t",arrayLinks) 
     print("ID's are:\n\t\t",arrayIDs) 

    } 
    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

输出就像下面的截图,

enter image description here

如果你迷惑,然后看到我video是给你的。

如果有任何疑问,请发表评论如下:d

感谢的人我按照你的代码中得到的数据))

func getJSON(){ 
    let wUrl = "http://api.fixer.io/latest" 
    let Url = NSURL(string: wUrl) 
    let request = NSMutableURLRequest(url: Url! as URL) 

    let task = URLSession.shared.dataTask(with: request as URLRequest){ data, response, error in 
     guard error == nil && data != nil else 
     { 
      print("Error:", error ?? "some error") 
      return 
     } 

     let httpStatus = response as? HTTPURLResponse 
     if httpStatus!.statusCode == 200 { 
      if data?.count != 0 { 

       let resposeString = try! JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! NSDictionary 

       let base = resposeString["base"] as? String 
       print(base ?? "") 
       let date = resposeString["date"] as? String 
       print(date ?? "") 
       let rates = resposeString["rates"] as! Dictionary<String, AnyObject> 

       for (key, value) in rates{ 
        print("\(key)->\(value)") 

       } 
      } 
      else 
      { 
       print("Data is emty") 
      } 
     } 
     else { 
      print("error httpStatus code: ", httpStatus?.statusCode ?? "") 
     } 

    };task.resume() 


}