如何使用 Alamofire 请求在我的 tableView 中显示我的数据

Posted

技术标签:

【中文标题】如何使用 Alamofire 请求在我的 tableView 中显示我的数据【英文标题】:how to display my data in my tableView with Alamofire request 【发布时间】:2018-09-19 21:59:07 【问题描述】:

我有一个包含这些数据的 JSON 表,我想获取标题 + oreview,然后在我的应用程序中显示它们,但在这种情况下我被阻止了,我不知道如何继续,想法?。 我使用 Alamofire 来满足我的要求。

我的标签 json:

"results":
["title":"The Predator",
  "poster_path":"\/wMq9kQXTeQCHUZOG4fAe5cAxyUA.jpg"
  "overview":"From the outer reaches of space to the small-town streets of suburbia, the hunt comes home. Now, the universe’s most lethal hunters are stronger, smarter and deadlier than ever before, having genetically upgraded themselves with DNA from other species. When a young boy accidentally triggers their return to Earth, only a ragtag crew of ex-soldiers and a disgruntled science teacher can prevent the end of the human race.",
  "release_date":"2018-09-13"

我的班级 Movie.swift :

   import UIKit

class Movie 
    var title: String
    var oreview: String

    public init(title: String, oreview: String) 
        self.title = title
        self.oreview = oreview
    

    public init?(json: [String: Any]) 
        guard
            let title = json["title"] as? String,
            let oreview = json["oreview"] as? String else 
                return nil

        

        self.title = title
        self.oreview = oreview
    

我的 MovieTableVieWCell.swift :

import UIKit
import Alamofire

class MovieTableViewCell: UITableViewCell 

    @IBOutlet var posterView: UIImageView!
    @IBOutlet var title: UILabel!
    @IBOutlet var oreview: UILabel!

    override func awakeFromNib() 
        super.awakeFromNib()
        // Initialization code
    

    override func setSelected(_ selected: Bool, animated: Bool) 
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    

    @IBAction func DescriptionButton(_ sender: UIButton) 
    



extension MovieTableViewCell 
    func draw(movie: Movie) 
        self.title.text = "\(movie.title)"
        self.oreview.text = "\(movie.oreview)"
    

我的 MovieViewController.swift :

import UIKit
import Alamofire
import SwiftyJSON

class MovieViewController: UIViewController 

    @IBOutlet var tableMovie: UITableView!

    var movie: [Movie]?

    override func viewDidLoad() 
        super.viewDidLoad()
        self.tableMovie.register(UINib(nibName: "MovieTableViewCell", bundle: nil), forCellReuseIdentifier: "Movie")

        self.tableMovie.delegate = self
        self.tableMovie.dataSource = self
        // Do any additional setup after loading the view.
        self.request()
    

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

    public func request() 
        let token = Token()
        Alamofire.request("https://api.themoviedb.org/3/movie/upcoming?api_key=\(token.getToken())").responseJSON  response in
            guard
                let json = response.result.value as? [String: Any]
                else 
                    return
            

            print(json)
             self.tableMovie.reloadData()
        
    


extension Movie: CustomStringConvertible 
    var description: String 
        let fields = [
            "title: \(self.title)",
            "oreview: \(self.oreview)",
            ]
        return fields.joined(separator: ",")
    


extension MovieViewController: UITableViewDelegate 
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return self.movie?.count ?? 0
    

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Movie", for: indexPath) as! MovieTableViewCell
        if let mov = self.movie?[indexPath.row] 
            cell.draw(movie: mov)
        
        return cell
    


extension MovieViewController: UITableViewDataSource 


【问题讨论】:

【参考方案1】:

您没有在movie中设置任何值。

首先,您需要解析响应并提取 results 这是一个对象数组

guard let json = response.result.value as? [String: Any], let results = json["results"] as? [[String: Any]] else 
    return

其次,您需要将对象数组转换为电影数组并设置它

self.movie = results.map  Movie(json: $0) 

三、重新加载TableView

self.tableMovie.reloadData()

【讨论】:

【参考方案2】:

例如,将电影数据保存在一个数组中,让数据源返回 1 个包含 array.count 元素的部分。然后表格视图将自动询问您将从数组中提供的元素。当您从请求中获取结果时,让表视图重新加载数据。

【讨论】:

【参考方案3】:

首先,将您的 json 作为代码发布:

"results":[
            
             "title":"The Predator",
             "poster_path":"/wMq9kQXTeQCHUZOG4fAe5cAxyUA.jpg",
             "overview":"From the outer reaches of space to the small-town streets of suburbia, the hunt comes home. Now, the universe’s most lethal hunters are stronger, smarter and deadlier than ever before, having genetically upgraded themselves with DNA from other species. When a young boy accidentally triggers their return to Earth, only a ragtag crew of ex-soldiers and a disgruntled science teacher can prevent the end of the human race.",
             "release_date":"2018-09-13"
            
           ]

其次,您的 json 已损坏。 “....jpg”和“overview”之间没有逗号。您没有关闭方括号和大括号。你从哪里得到这个 json?

第三,您没有正确解析您的 json,此外,您期望密钥被称为 "oreview" 而在 json 中它被命名为 "overview"

你应该这样做:

修改你的电影类:

class Movie 
    var title: String
    var overview: String

    public init(title: String, overview: String) 
        self.title = title
        self.overview = overview
    

    class func buildFrom(json: [String: Any]) -> Movie? 

       let results = json["results"] as! [[String : Any]]
       guard let title = results[0]["title"] as? String, let overview = results[0]["overview"] as? String else  return nil 

       return Movie(title: title, overview: overview)

    

现在从自定义单元格中删除所有代码:

class MovieTableViewCell: UITableViewCell 

    @IBOutlet var posterView: UIImageView!
    @IBOutlet var title: UILabel!
    @IBOutlet var overview: UILabel!


现在,让我们转到您的 viewController:

class MovieViewController: UIViewController 

    @IBOutlet var tableMovie: UITableView!

    var movie: Movie?

    override func viewDidLoad() 
        super.viewDidLoad()
        self.tableMovie.register(UINib(nibName: "MovieTableViewCell", bundle: nil), forCellReuseIdentifier: "Movie")

        self.tableMovie.delegate = self
        self.tableMovie.dataSource = self
        // Do any additional setup after loading the view.
        self.request()
    

    func request() 
        let token = Token()
        Alamofire.request("https://api.themoviedb.org/3/movie/upcoming?api_key=\(token.getToken())").responseJSON  response in
            guard let json = response.result.value as? [String : Any] else  return 
            self.movie = Movie.buildFrom(json: json)

            self.tableMovie.reloadData()
        
    


//UITableView Datasource & Delegate methods
extension MovieViewController: UITableViewDelegate, UITableViewDataSource 

   func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
      if self.movie != nil 
         return 1
      
      return 0
   

   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
      let cell = tableView.dequeueReusableCell(withIdentifier: "Movie", for: indexPath) as! MovieTableViewCell
      cell.title = self.movie.title
      cell.overview = self.movie.overview

      return cell
   

应该这样做。如果您错误地粘贴了 json 并且它实际上是一个包含超过 1 部电影的 json,那么将需要对代码进行一些更改。让我知道,我会改变我的答案。另外,不要忘记在问题中更新您的 json。祝你好运!

【讨论】:

感谢您的回答,所以是的,我必须得到不止一行,所以我想自己需要改变什么? Movie 类还是 MovieViewController?因为是你给我的,它只显示第一行。否则对于json我只是在主题上复制它犯了一个错误

以上是关于如何使用 Alamofire 请求在我的 tableView 中显示我的数据的主要内容,如果未能解决你的问题,请参考以下文章

带参数的 CURL 请求的 Alamofire

带有 XML 响应和正文的 SOAP 请求 swift 3,Alamofire

图片不会在我的 Alamofire .post 请求中发送到我的后端 - Swift 3

等待多个 Alamofire 请求完成

Alamofire 多个请求

如何暂停应用程序直到使用 Alamofire 下载 json 数据?