【问题标题】:Showing JSON data on TableView using SwiftyJSON and Alamofire使用 SwiftyJSON 和 Alamofire 在 TableView 上显示 JSON 数据
【发布时间】:2016-07-01 09:23:25
【问题描述】:

我想在表格视图中显示从服务器抓取的 JSON 数据。问题是,我无法让它显示在上面。我尝试了几种不同的方法并搜索了很多以找到解决方案,但我做不到。

我的代码(全部)如下所示,希望有人能帮助我。提前致谢。

import UIKit
import Alamofire
import SwiftyJSON

class MasterViewController: UITableViewController {

var tableTitle = [String]()
var tableBody = [String]()

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    getJSON()

}

func getJSON(){

    Alamofire.request(.GET, "http://announcement.vassy.net/api/AnnouncementAPI/Get/").responseJSON { (Response) -> Void in

        // checking if result has value
        if let value = Response.result.value {

            let json = JSON(value)

            for anItem in json.array! {

                let title: String? = anItem["Title"].stringValue
                let body: String? = anItem["Body"].stringValue
                self.tableTitle.append(title!)
                self.tableBody.append(body!)

            }

        }

    }

    self.tableView.reloadData()

}

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

// Table View Stuff

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.tableTitle.count
}


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

    // cell config
    cell.title!.text = tableTitle[indexPath.row]
    cell.body!.text = tableBody[indexPath.row]
    return cell

}

}

【问题讨论】:

    标签: json swift uitableview alamofire swifty-json


    【解决方案1】:

    我认为@Eric 在他的回答中几乎说了所有内容,但是,这不是一个好的设计决定,将用于发出网络请求的代码保留在您的同一 UITableViewController 中,这样可以在两个独立的事物之间保留一些并改变不同的原因。

    我的建议是将代码的两个部分分开,以解耦两层之间的依赖关系。这样,当您需要更改与网络请求处理程序相关的任何内容时,您无需在任何发出相同请求的地方更改它,这是一个建议!!!。

    如果你想这样做,你可以使用闭包来处理 Alamofire 的异步行为,在你用来处理网络请求的包装器中传入 completionHandler,例如,让我们使用单例模式定义一个简单的包装器(这只是为了解释示例,您可以随意处理)。

    import AlamofireImage
    import SwiftyJSON
    
    class NetworkHandler { 
    
       /// The shared instance to define the singleton.
      static let sharedInstance = RequestManager()
    
    
      /**
      Private initializer to create the singleton instance.
      */
      private init() { }
    
      func getJSON(completionHandler: (json: JSON?, error: NSError?) -> Void) {
    
          Alamofire.request(.GET, http://announcement.vassy.net/api/AnnouncementAPI/Get/).responseJSON { response in
    
            switch(response.result) {
            case .Success(let value):
    
                let json = JSON(value)
                completionHandler(json: json, error: nil)
    
            case .Failure(let error):
                completionHandler(json: nil, error: error)
            }
        }
      }
    }
    

    然后在您的UITableViewController 中,您可以通过这种方式将新包装器调用到 Alamofire:

    class MasterViewController: UITableViewController {
    
       var tableTitle = [String]()
       var tableBody = [String]()
    
       override func viewDidLoad() {
           super.viewDidLoad()
           // Do any additional setup after loading the view, typically from a nib.
    
           NetworkHandler.sharedInstance.getJSON { [weak self] (json, error) -> Void in
    
             // request was made successful
             if error == nil {
                for anItem in json.array! {
                   let title: String? = anItem["Title"].stringValue
                   let body: String? = anItem["Body"].stringValue
                   self.tableTitle.append(title!)
                   self.tableBody.append(body!)
                }
    
                dispatch_async(dispatch_get_main_queue()) {
                    self.tableView.reloadData()             
                }
             }
           }
        }
    
        // rest of your code
     }
    

    通过上述方式你保持代码解耦,这是一个很好的设计。

    希望对你有帮助

    【讨论】:

      【解决方案2】:

      Alamofire 网络请求是异步的,这意味着你不知道什么时候结果会回来。

      这里的问题是你重新加载了tableView超出了Alamofire请求的范围,所以在数据回来之前就执行了。

      重新加载应该发生在同一范围内,并且在主线程上,例如:

      func getJSON(){
      
          Alamofire.request(.GET, "http://announcement.vassy.net/api/AnnouncementAPI/Get/").responseJSON { (Response) -> Void in
      
              // checking if result has value
              if let value = Response.result.value {
      
                  let json = JSON(value)
      
                  for anItem in json.array! {
      
                      let title: String? = anItem["Title"].stringValue
                      let body: String? = anItem["Body"].stringValue
                      self.tableTitle.append(title!)
                      self.tableBody.append(body!)
      
                  }
      
                  dispatch_async(dispatch_get_main_queue()) {
                      self.tableView.reloadData()             
                  }
      
              }
      
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-08
        • 1970-01-01
        • 2018-11-12
        • 1970-01-01
        • 2017-05-17
        • 1970-01-01
        • 2017-12-21
        • 1970-01-01
        相关资源
        最近更新 更多