swift - 如何在 JSON 模型中快速添加自定义变量?
问题描述
请告诉我,是否可以在模型中添加一个新的(自定义)变量NewResult
,其中数据来自 API?我想将isFavorite: Bool
变量添加到模型中,以便将来跟踪更改并交换此变量。
这是我的模型:
class News: Codable {
var results: [NewResult]?
}
class NewResult: Codable {
var isFavorite = false
let url: String?
let section: String?
let byline: String?
let title, abstract, publishedDate: String?
let media: [Media]?
enum CodingKeys: String, CodingKey {
case url
case section
case byline
case title
case abstract
case publishedDate = "published_date"
case media
}
}
class Media: Codable {
let mediaMetadata: [MediaMetadata]?
enum CodingKeys: String, CodingKey {
case mediaMetadata = "media-metadata"
}
}
class MediaMetadata: Codable {
let url: String?
}
我使用 Alamofire,所以这是我的 requestData 方法:
static func requestData(url: String, completion: @escaping (News) -> ()) {
guard let url = URL(string: url) else { return }
request(url).responseData { (responseData) in
switch responseData.result {
case .success(let data):
guard let news = try? JSONDecoder().decode(News.self, from: data) else { return }
completion(news)
case .failure(let error):
print(error.localizedDescription)
}
}
在我的MainVC
课堂上,我有标准的TableViewDelegate
,TableViewDataSource
和Navigation
to方法Detail VC
:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let indexPath = tableView.indexPathForSelectedRow else { return }
guard let destination = segue.destination as? DetailViewController else { return }
destination.currentNew = news?.results?[indexPath.row]
}
在DetailVC
我有webView
:
// MARK: - Properties
var currentNew: NewResult!
private var isFavorite = false
// MARK: - @IBOutlets
@IBOutlet var progressView: UIProgressView!
@IBOutlet var webView: WKWebView!
@IBOutlet var favoriteButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
let newUrl = currentNew.url
guard let url = URL(string: newURL) else { return }
let request = URLRequest(url: url)
webView.load(request)
}
// MARK: - @IBAction
@IBAction func addToFavorite(_ sender: UIBarButtonItem) {
self.isFavorite.toggle()
self.currentNew.isFavorite = self.isFavorite
setFavoriteButton(isFavorite: self.isFavorite)
}
// MARK: - Methods
private func setFavoriteButton(isFavorite: Bool) {
if isFavorite {
favoriteButton.image = UIImage(named: "favoriteTrue")
// and here I should change variable isFavorite in currentNew and in news
} else {
favoriteButton.image = UIImage(named: "favoriteFalse")
// and also here
}
}
}
当我返回MainVC
并选择results[indexPath.row]
已经在我的收藏夹中时,results
即使在应用程序重新启动后也应该进行更改。
解决方案
isFavourite
只需在 中创建一个属性NewResult
,即
struct NewResult: Codable {
//all other properties....
var isFavorite = false
enum CodingKeys: String, CodingKey {
//don't include isFavorite here...
//all the other cases...
}
}
不要包含case
for isFavourite
in enum CodingKeys
。
用法:
既然要results
稍后修改,所以把它从let
改为var
,即
struct News: Codable {
var results: [NewResult]?
}
现在,解析 JSON 并修改results
withisFavourite = true
if let data = data {
do {
var news = try JSONDecoder().decode(News.self, from: data)
news.results = news.results?.map({
var tempResult = $0
tempResult.isFavourite = true
return tempResult
})
print(news)
} catch {
print(error)
}
}
在DetailVC
中,您必须具有类型的属性NewResult
。选择/取消选择时,请根据starButton
其更新基于该值的值,即isFavourite
result
class DetailVC: UIViewController {
var result: NewResult?
func onTapStarButton(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
self.result?.isFavourite = sender.isSelected
}
}
注意:制作您的模型class
,而不是struct
为了跨多个屏幕跟踪更改。
推荐阅读
- c# - Hangfire商店如何回电?
- java - 如何在 JDI 测试框架中定义自己的复杂 WebElement
- python - Python - itertools groupby 但仅在新列表中包含组。然后过滤列表?
- clojure - 如何从 java-time 库中解构瞬间并提取年、月等
- javascript - modelbinder IsMultiPartContent 始终返回 false。如何使用反应上传文件
- javascript - 如何在新会议上从插件“模拟”发送按钮?
- phantomjs - phantomjs 错误地将日期解析为 1400 年 3 月之前的日期,为什么?
- postgresql - Osmosis 抛出奇怪的 Java 错误
- cloud-foundry - 如何在 Windows 中查看 PCF .droplet 文件的内容?
- apache-kafka - 如何通过kafka客户端查看集群中运行的kafka服务器的数量和IP?