请告诉我,是否可以在模型 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
到 的标准方法详细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
应该与即使在应用程序重新启动后也会发生更改。
最佳答案
只需在NewResult
中创建一个属性isFavourite
,即
struct NewResult: Codable {
//all other properties....
var isFavorite = false
enum CodingKeys: String, CodingKey {
//don't include isFavorite here...
//all the other cases...
}
}
不要在 enum CodingKeys
中包含 isFavourite
的 case
。
用法:
由于后面要修改results
,所以将let
改为var
,即
struct News: Codable {
var results: [NewResult]?
}
现在,解析 JSON 并使用 isFavourite = true
修改 results
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
被选中/取消选中时,根据它更新 result
的 isFavourite
值,即
class DetailVC: UIViewController {
var result: NewResult?
func onTapStarButton(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
self.result?.isFavourite = sender.isSelected
}
}
注意:让您的模型class
而不是struct
,以防想要跟踪跨多个屏幕的变化。
关于swift - 如何在 JSON 模型 swift 中添加自定义变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56749443/