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

Posted

技术标签:

【中文标题】如何在 Swift 2 中从 JSON 填充我的 tableView?【英文标题】:How to populate my tableView in Swift 2 from JSON? 【发布时间】:2016-01-27 16:46:01 【问题描述】:

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

代码

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

【问题讨论】:

请不要破坏您的问题。 我“加密”了 api 密钥,因为 URL 确实有效,而且 JSON 可能包含机密数据。 如果有人因为敏感信息需要召唤一个模组来删除一个问题,那就这样做吧。如果这是问题。 【参考方案1】:

在视图控制器之外创建一个自定义类Person

class Person 
  var firstName = ""
  var lastName = ""
  var title = ""
  var party = ""

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

var people = [Person]()

JSON 有一个键 results,其中包含一个字典数组。 在 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

使用自定义类时,表格视图委托方法看起来非常清晰。 由于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

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

【讨论】:

感谢@vadian 的帮助。【参考方案2】:

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

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

然后 - 你几乎已经做对了 - 将 JSON 序列化保存到 JSONSerialization 函数中。 (我会重命名为 parseJSON 或类似名称以避免混淆)像这样:

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

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

那么您可以将正确的值返回给您的tableView data source

// 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

命名有点混乱,因为我不知道你的 JSON 的布局,但当然用你的数据路径替换 your JSON key

【讨论】:

感谢您的帮助。仍然对“您的 JSON 密钥”应该是什么感到有些困惑。 将可选字典 [String:AnyObject]? 作为数据源是不好的做法。由于表视图从不是可选的,因此数据源也应该是非可选的,但可以为空。此外,您必须一直从 AnyObject 向下转换为正确的类型,这非常昂贵。 嗯,取决于您的 JSON 的组成方式,这是您将要在 tableView 中禁用的数据的关键所在

以上是关于如何在 Swift 2 中从 JSON 填充我的 tableView?的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中从 json 解析我的数据有啥问题?

IOS - 如何在 Swift 3 中从 JSON 中捕获动态数组维度

如何在 xcode (swift) 中从 Json Schema / Json 生成模型对象?

IOS swift如何使用返回的Json数据填充我的TableView

如何在 Swift 中从 alamofire 中提取数据? [复制]

如何在 Swift 中从同一站点重新加载新的 JSON 数据?