如何从JSON中填充Swift 2中的tableView?

时间:2021-03-22 15:40:27

A new programmer here. How would I populate my tableView from this JSON?
My first problem is the JSON Serialization and then plugging it in the tableView.

一个新的程序员在这里。我如何从这个JSON填充我的tableView?我的第一个问题是JSON序列化,然后将其插入tableView。

Code

import UIKit

class LegislatorsTableVC: UITableViewController {

// MARK: Variables & Outlets
private let cellIdentifer = "cellReuse"

// MARK: View Did Load
override func viewDidLoad() {
    super.viewDidLoad()

    // Creating Congfiguration Object // Session Is Created // Getting Info/Data
    let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: configuration)
    let apiKey = "https://congress.api.sunlightfoundation.com/legislators?apikey=xxxxxxxxxxxxxxxxxxxxx&all_legislators=true&per_page=all"

    if let url = NSURL(string: apiKey) {
        // Spawning Task To Retrieve JSON Data
        session.dataTaskWithURL(url, completionHandler: { (data, response, error) -> Void in
            // Checking For Error
            if let error = error {
                print("The error is: \(error)")
                return
            }
            // Response
            if let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200, let data = data {
                print("Status Code: \(httpResponse.statusCode)")
                // self.JSONSerialization(data)
            }
        }).resume()
    }
} // End Of View Did Load

// JSON Serialization Function With SwiftyJSON.swift
private func JSONSerialization(data: NSData){

    // I See this Gets A Status Code 200 And Then I'm Lost.
    do {
        let json = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as! [String: AnyObject]

    } catch {
        print("Error Serializing JSON Data: \(error)")
    }
} // End Of JSONSerialization



// MARK: - Table view data source
// Number Of Sections
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
} // End Of Number Of Sections

// Number Of Rows In Section
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return 15
} // End Of Number Of Rows In Section

// Cell For Row At Index Path
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifer, forIndexPath: indexPath) as! LegislatorTVCell

    // Configure the cell...
    cell.name.text = "Name"
    cell.title.text = "Title"
    cell.party.text = "Party"

    return cell
} // End Of Cell For Row At Index Path
}

2 个解决方案

#1


6  

  • Create a custom class Person outside the view controller

    在视图控制器外部创建自定义类Person

    class Person {
      var firstName = ""
      var lastName = ""
      var title = ""
      var party = ""
    }
    
  • Create an array of Person in the view controller

    在视图控制器中创建Person数组

    var people = [Person]()
    
  • The JSON has a key results which contains an array of dictionaries.
    In viewDidLoad parse the JSON and create Person instances. Finally reload the table view.

    JSON具有包含字典数组的关键结果。在viewDidLoad中解析JSON并创建Person实例。最后重新加载表视图。

    override func viewDidLoad() {
      super.viewDidLoad()
    
      // Creating Congfiguration Object // Session Is Created // Getting Info/Data
      let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
      let session = NSURLSession(configuration: configuration)
      let apiKey = "https://congress.api.sunlightfoundation.com/legislators?apikey=xxxxxxxxxxxxxxxxxx&all_legislators=true&per_page=all"
    
      if let url = NSURL(string: apiKey) {
        // Spawning Task To Retrieve JSON Data
        session.dataTaskWithURL(url, completionHandler: { (data, response, error) -> Void in
          // Checking For Error
          if error != nil {
            print("The error is: \(error!)")
            return
          } else if let jsonData = data {
            do {
              let parsedJSON = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String:AnyObject]
              guard let results = parsedJSON["results"] as? [[String:AnyObject]] else { return }
              for result in results {
                let person = Person()
                person.firstName = result["first_name"] as! String
                person.lastName = result["last_name"] as! String
                person.party = result["party"] as! String
                person.title = result["title"] as! String
                self.people.append(person)
              }
              dispatch_async(dispatch_get_main_queue()) {
                self.tableView.reloadData()
              }
    
            } catch let error as NSError {
              print(error)
            }
          }
        }).resume()
      }
    } // End Of View Did Load
    
  • The table view delegate methods look very clear when using a custom class.
    Since cellForRowAtIndexPath is called very often the code is quite effective.

    使用自定义类时,表视图委托方法看起来非常清晰。由于cellForRowAtIndexPath经常被调用,所以代码非常有效。

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
      return 1
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return people.count
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifer, forIndexPath: indexPath) as! LegislatorTVCell
    
      let person = people[indexPath.row]
      cell.name.text = person.firstName + " " + person.lastName
      cell.title.text = person.title
      cell.party.text = person.party
    
      return cell
    } // End
    

Of course I couldn't test the code but this might be a starting point.

当然我无法测试代码,但这可能是一个起点。

#2


0  

Basically what you want to do is introduce a new variable to your class, for example jsonDict like so:

基本上你想要做的是为你的类引入一个新变量,例如jsonDict,如下所示:

class LegislatorsTableVC: UITableViewController {
    var jsonDict:Dictionary<String,AnyObject>?
    // further code

And then - you almost got it right already - save your JSON serialization into that in your JSONSerialization function. (which I would rename to parseJSON or something like that to avoid confusion) like so:

然后 - 你几乎已经把它弄好了 - 将JSON序列化保存到JSONSerialization函数中。 (我会将其重命名为parseJSON或类似的东西,以避免混淆),如下所示:

do {
    jsonDict = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as! [String: AnyObject]

} catch {
    print("Error Serializing JSON Data: \(error)")
}

So then you can return the right values to your tableView data source:

那么您可以将正确的值返回到tableView数据源:

// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return jsonDict["your JSON key"].count ?? 0
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return jsonDict["your JSON key"]["items"].count ?? 0
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifer, forIndexPath: indexPath) as! LegislatorTVCell

    let item = jsonDict["your JSON key"][indexPath.row]

    // Configure the cell...
    cell.name.text = item["name"]
    cell.title.text = item["title"]
    cell.party.text = item["party"]

    return cell
}

Naming is a little confusing, as I don't know the layout of your JSON, but replace your JSON key with your path to the data of course.

命名有点令人困惑,因为我不知道你的JSON的布局,但当然用你的数据路径替换你的JSON密钥。

#1


6  

  • Create a custom class Person outside the view controller

    在视图控制器外部创建自定义类Person

    class Person {
      var firstName = ""
      var lastName = ""
      var title = ""
      var party = ""
    }
    
  • Create an array of Person in the view controller

    在视图控制器中创建Person数组

    var people = [Person]()
    
  • The JSON has a key results which contains an array of dictionaries.
    In viewDidLoad parse the JSON and create Person instances. Finally reload the table view.

    JSON具有包含字典数组的关键结果。在viewDidLoad中解析JSON并创建Person实例。最后重新加载表视图。

    override func viewDidLoad() {
      super.viewDidLoad()
    
      // Creating Congfiguration Object // Session Is Created // Getting Info/Data
      let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
      let session = NSURLSession(configuration: configuration)
      let apiKey = "https://congress.api.sunlightfoundation.com/legislators?apikey=xxxxxxxxxxxxxxxxxx&all_legislators=true&per_page=all"
    
      if let url = NSURL(string: apiKey) {
        // Spawning Task To Retrieve JSON Data
        session.dataTaskWithURL(url, completionHandler: { (data, response, error) -> Void in
          // Checking For Error
          if error != nil {
            print("The error is: \(error!)")
            return
          } else if let jsonData = data {
            do {
              let parsedJSON = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String:AnyObject]
              guard let results = parsedJSON["results"] as? [[String:AnyObject]] else { return }
              for result in results {
                let person = Person()
                person.firstName = result["first_name"] as! String
                person.lastName = result["last_name"] as! String
                person.party = result["party"] as! String
                person.title = result["title"] as! String
                self.people.append(person)
              }
              dispatch_async(dispatch_get_main_queue()) {
                self.tableView.reloadData()
              }
    
            } catch let error as NSError {
              print(error)
            }
          }
        }).resume()
      }
    } // End Of View Did Load
    
  • The table view delegate methods look very clear when using a custom class.
    Since cellForRowAtIndexPath is called very often the code is quite effective.

    使用自定义类时,表视图委托方法看起来非常清晰。由于cellForRowAtIndexPath经常被调用,所以代码非常有效。

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
      return 1
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return people.count
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifer, forIndexPath: indexPath) as! LegislatorTVCell
    
      let person = people[indexPath.row]
      cell.name.text = person.firstName + " " + person.lastName
      cell.title.text = person.title
      cell.party.text = person.party
    
      return cell
    } // End
    

Of course I couldn't test the code but this might be a starting point.

当然我无法测试代码,但这可能是一个起点。

#2


0  

Basically what you want to do is introduce a new variable to your class, for example jsonDict like so:

基本上你想要做的是为你的类引入一个新变量,例如jsonDict,如下所示:

class LegislatorsTableVC: UITableViewController {
    var jsonDict:Dictionary<String,AnyObject>?
    // further code

And then - you almost got it right already - save your JSON serialization into that in your JSONSerialization function. (which I would rename to parseJSON or something like that to avoid confusion) like so:

然后 - 你几乎已经把它弄好了 - 将JSON序列化保存到JSONSerialization函数中。 (我会将其重命名为parseJSON或类似的东西,以避免混淆),如下所示:

do {
    jsonDict = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers) as! [String: AnyObject]

} catch {
    print("Error Serializing JSON Data: \(error)")
}

So then you can return the right values to your tableView data source:

那么您可以将正确的值返回到tableView数据源:

// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return jsonDict["your JSON key"].count ?? 0
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return jsonDict["your JSON key"]["items"].count ?? 0
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifer, forIndexPath: indexPath) as! LegislatorTVCell

    let item = jsonDict["your JSON key"][indexPath.row]

    // Configure the cell...
    cell.name.text = item["name"]
    cell.title.text = item["title"]
    cell.party.text = item["party"]

    return cell
}

Naming is a little confusing, as I don't know the layout of your JSON, but replace your JSON key with your path to the data of course.

命名有点令人困惑,因为我不知道你的JSON的布局,但当然用你的数据路径替换你的JSON密钥。