请求网络json数据并加载到TableViewCell

首页 / iOS / 正文

swift写法

网络请求与数据处理

网络请求

利用URL和URLSession.dataTask完成我们的api请求

 let urlString = "http://v.juhe.cn/toutiao/index"
        let url = URL(string: urlString)!
        let session = URLSession.shared
        let task = session.dataTask(with: url) { (data, response, error) in
        
                                               }

json数据的处理

blog3-json.png

首先我们需要知道,从网络上请求回来的数据是返回dataTask的data,并且其中还带着一些请求所返回的参数,于是我们接着在dataTaks中将请求回来的数据转换为json数据,然后再利用字典逐步提取其中的我们所需要的数据。

guard error == nil else {
                fatalError("Task Error")
            }
            guard let jsonData = data else {
                fatalError("Data Error")
            }
            do {
                // Data 转 JSON
                guard let dic = try JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) as? [String : Any] else {
                    fatalError("JSONSerialization Error")
                }
                //提取JSON中的result
                guard let resultDic = dic["result"] as? [String : Any] else {
                    fatalError("JSONSerialization Error")
                }
                //提取result中的data
                guard let dataArray = resultDic["data"] as? [Any] else {
                    fatalError("JSONSerialization Error")
                }

由于这只是个人的开发,所以对于错误和数据为空的处理较为简单。接着我们将提取出来的字典数据,转化为model,并且。

model应该创建于一个独立的文件当中

import Foundation
import UIKit

public struct NewsModel {
    public var author_name: String
    public var category: String
    public var date: String
    public var thumbnail_pic_s: String
    public var title: String
    public var uniquekey: String
    public var url: String
}

转化过程的代码应该也在dataTask中

                                var modelArray = [NewsModel]()
                for item in dataArray {
                    let dic = item as! [String: String]
                    let model = NewsModel(author_name: dic["author_name"]!, category: dic["category"]!, date: dic["date"]!, thumbnail_pic_s: dic["thumbnail_pic_s"]!, title: dic["title"]!, uniquekey: dic["uniquekey"]!, url: dic["url"]!)
                    modelArray.append(model)

到此我们已经完成了第一步,网络请求和数据处理。接下来就是讲数据传递到cell中并加载数据。

数据加载到cell

加载的顺序

视图控制器创建网络请求并在子线程中执行 --> 网络请求获取数据并传入视图控制器 --> 主线程重加载cell的数据

数据的传递

首先我们需要在网络请求的方法中传入一个闭包用于传递数据,并且由于需要将数据的刷新加载至主线程中所以闭包必须是逃逸闭包

    public func loadNetWork(block: @escaping ((Bool, Array<NewsModel>) -> Void)) {
      ...
      ...
      DispatchQueue.main.async {
                    block(true, modelArray)
                }
    }

同时我们在cell中也要创建一个传递数据的方法

public func modelForCell(model: NewsModel) {
        titleLabel.text = model.title
        sourceLabel.text = model.category
        commentLabel.text = model.author_name
        timeLabel.text = model.date
        do {
            rightImage.image = UIImage(data: try Data(contentsOf: URL(string: model.thumbnail_pic_s)!))
        } catch {
            
        }
    }

在控制器中,我们需要创建网络请求,并且在cell的注册方法中调用modelForCell(model: NewsModel)

override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(newsTableView)
        let loader = ListLoder()
        loader.loadNetWork { (success, model) in
            self.data = model
            self.newsTableView.reloadData()
            }
            //extnsion
            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reusedcell") as! NewsTableViewCell
        cell.modelForCell(model: data[indexPath.row])
        return cell
    }

到此,我们就已经完成了整个数据从网络请求到加载到cell当中,由于我个人的实力问题,部分代码还无法进行很好的解释,在后续的学习当中我会更新讲解

附上最后的效果

blog3-final.png

附上我的仓库地址

评论区
头像
文章目录