从swift 4中的json加载数据的空tableview

时间:2018-01-04 16:17:08

标签: json swift swift4

所以,谢谢你们,我只是将整个代码改为可编码到适当的快速4 lol。但桌面视图仍未显示在控制台上: "下载 下载后出现问题"

final let url = URL(string: "https://newsapi.org/v2/top-headlines?sources=espn&apiKey=ada86a1d56d348a29a7c7501869bac2f")
private var articles = [Article]()
@IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        downloadJson()
        tableView.tableFooterView = UIView()
    }

func downloadJson(){
            guard let downloadURL = url else {return}
            URLSession.shared.dataTask(with: downloadURL){data, URLResponse, error in
                guard let data = data, error == nil, URLResponse != nil else{
                    print("something is wrong")
                    return
                }
                print("downloaded")
                do
                {
                    let decoder = JSONDecoder()
                    let downloadedArticles = try decoder.decode(Articles.self, from: data)
                    self.articles = downloadedArticles.articles
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }catch {
                    print("something is wrong when downloaded")
                }
            }.resume()
        }

这是来自文章可编码类

class Articles: Codable {
    let articles: [Article]

    init(articles: [Article]){
        self.articles = articles
    }
}

class Article: Codable{
    let title: String
    let description: String
    let author: String
    let image: String

    init(title: String, description: String, author: String, image: String){
        self.title = title
        self.description = description
        self.author = author
        self.image = image
        }
}

这里是cellforrowat(我不能发布它,因为我的整个帖子主要是代码。大声笑):

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "ArticleCell") as? ArticleCell else {
            return UITableViewCell()}
        cell.titleLabel.text = "" + articles[indexPath.row].title
        cell.descLabel.text = "" + articles[indexPath.row].description
        cell.authorLabel.text = "" + articles[indexPath.row].author

        if let imageURL = URL(string: articles[indexPath.row].image){
            DispatchQueue.global().async {
                let data = try? Data(contentsOf: imageURL)
                if let data = data {
                    let image = UIImage(data: data)
                    DispatchQueue.main.async {
                        cell.imgView.image = image
                    }
                }
            }
        }
        return cell
    }

2 个答案:

答案 0 :(得分:0)

首先确保在Interface Builder中连接表视图的datasource(以及delegate以供将来使用)。

对于表格视图,它是indexPath.row而不是indexPath.item

此外,建议在cellForRow中仅获取一次数据源项,并将数据源数组声明为非可选项(教程非常差,表明不良习惯和一半知识)。并且 - 一如既往 - 选项.mutableContainers在Swift中毫无意义。

var articles = [Article]()

<击>

<击>
     if let json = try JSONSerialization.jsonObject(with: data!) as? [String:Any],
        let articlesFromJson = json["articles"] as? [[String:Any]] {
        ...
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "articleCell", for: indexPath) as! ArticleCell

    let article = articles[indexPath.row]
    cell.title.text = article.headline
    cell.desc.text = article.desc
    cell.author.text = article.author
    cell.imgView.downloadImage(from: article.imageUrl!)!
    return cell
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return articles.count
}

删除numberOfSections方法。默认值为1

在Swift 3+中,JSON字典为[String : Any],而不是[String : AnyObject]

在Swift 4中,考虑使用Codable协议将JSON解析为结构。它更方便。

<击>

<强>更新

Article与给定URL处的JSON不匹配。将其更改为以下内容。 author必须是可选的,且没有密钥image。顺便说一下,如果你采用Codable,则不需要编写初始值。

class Articles: Codable {
    let articles: [Article]
}

class Article: Codable {
    let title: String
    let description: String
    let author: String?
    let urlToImage: URL
}

PS:URLResponse是一种类型。使用小写的东西来避免混淆,例如dataTask(with: downloadURL) {data, response, error。但在您的情况下,根本不需要参数。

答案 1 :(得分:0)

您应该使用json和articlesFromJs检查调试内容。 也许articlesFromJs为空或JSON格式不正确。

  

让json =尝试使用JSONSerialization.jsonObject(带:data!,options:.mutableContainers)! [String:AnyObject]

  

如果让articlesFromJson = json [“articles”]为? [[String:&gt; AnyObject]]

也可以使用Codable代替JSONSerialization。