swift - 如何在 JSON 模型 swift 中添加自定义变量?

标签 swift api networking model

请告诉我,是否可以在模型 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 类中,我有 TableViewDelegateTableViewDataSourceNavigation 的标准方法详细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 中包含 isFavouritecase

用法:

由于后面要修改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选中/取消选中时,根据它更新 resultisFavourite 值,即

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/

相关文章:

c++ - 最好的 2D c++ API?

c++ - 读句柄问题

java - 有没有办法将 DatagramSocket 绑定(bind)到特定网卡上的任何端口,或者如果我指定网卡,我必须指定端口?

c - getaddrinfo addrinfo 结果在堆栈或堆中

swift - 我想使用 SnapKit 将顶部 UIView 放置在 UITableView 之上

swift - PFQuery 使用 for In 循环将数据添加到表格 View 单元格

ios - 滚动浏览 tableView 后,视频在 AVPlayerController 的 UITableView 单元格中停止加载

ios - Facebook SDK获取用户图片

ruby - open_http: 403 禁止 (OpenURI::HTTPError)

windows - LoadLibrary 卡住