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数据的处理
首先我们需要知道,从网络上请求回来的数据是返回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当中,由于我个人的实力问题,部分代码还无法进行很好的解释,在后续的学习当中我会更新讲解