【问题标题】:How to display parsed JSON data in UI?如何在 UI 中显示解析的 JSON 数据?
【发布时间】:2018-03-26 10:01:04
【问题描述】:

我已从 API 调用收到的 JSON 对象解析数据。到目前为止,我可以在调试器控制台中打印 JSON 数据,但是我正在尝试将解析的 JSON 转换回可以在 UI 中显示的数据。我有两个模型,一个 JSON 对象的示例如下所示:

{ 
  "query": "milk",
  "sort": "relevance",
  "responseGroup": "base",
  "totalResults": 693,
  "start": 1,
  "numItems": 10,
  "items": [{
    "itemId": 10291863,
    "parentItemId": 10291863,
    "name": "Carnation Vitamin D Added Evaporated Milk, 12 oz",
    "msrp": 1.79,
    "salePrice": 1.48
  }]
}

我只想显示详细说明 namesalePrice 键的信息。但是,由于 JSON 是嵌套的,我不知道如何到达该层以检索值。这是我的数据模型代码:

struct Item: Codable {
  let query: String
  let sort: String
  let responseGroup: String
  let totalResults: Int
  let start: Int
  let numItems = 25
  let items: [Product]
}

struct Product: Codable {
  let name: String
  let salePrice: Double
}

我的 ViewController 的代码:

class ViewController: UIViewController {
  @IBOutlet weak var itemField: UITextField!  
  @IBAction func filterButton(_ sender: Any) {
    var components = URLComponents()
    components.scheme = "http"
    components.host = "api.walmartlabs.com"
    components.path = "/v1/search"
    let queryItemKey = URLQueryItem(name: "apiKey", value: secretKey)
    var queryItemQuery = URLQueryItem(name: "query", value: itemField.text)
    components.queryItems = [queryItemKey, queryItemQuery]
    let searchURL = components.url       
    //Task to make API Network Call
    guard let url = components.url else { return }
    URLSession.shared.dataTask(with: url) { (data, response, error) in
      if error != nil {
        print(error!.localizedDescription)
      }  
      guard let data = data else { return }
      //Implement JSON decoding and parsing
      do {
        //Decode retrived data with JSONDecoder and assing type of Item object
        let productData = try JSONDecoder().decode(Item.self, from: data)
            print(productData) 
      } catch let jsonError {
        print(jsonError)
      }          
    }.resume()
  }

  override func viewDidLoad() {
    super.viewDidLoad()
  }
}

当我运行我的代码时,打印日志显示以下内容(同样,我只想显示 namesalePrice 值。有没有办法可以将这些值放在数组中或将这些值转换为如何填充我的 UI?提前致谢。

【问题讨论】:

  • 您已经在使用[Product] 解析数组中的值,那么您想做什么?
  • 我想从键 namesalePrice 中取出所有值并将它们放在各自的数组中。
  • 你可以这样映射你的字段(我已经更新了我的答案):let names = productData.items.map { $0.name }let salePrices = productData.items.map { $0.salePrice }
  • 不要如果您已经有自定义结构,则将值放在单独的数组中。永远不要那样做。
  • 你能解释一下为什么吗? @vadian

标签: arrays json swift parsing codable


【解决方案1】:

创建数据源数组

var products = [Product]()

解析数据后将 products 数组赋值给数据源数组并重新加载表格视图

...
let productData = try JSONDecoder().decode(Item.self, from: data)
self.products = productData.items
DispatchQueue.main.async {
   self.tableView.reloadData()
}

numberOfRowsInSection 返回products.count

cellForRow 中获取当前产品并将值分配给标签

let product = products[indexPath.row]
cell.textLabel!.text = product.name
cell.detailTextLabel!.text = "\(product.salePrice)"

【讨论】:

    【解决方案2】:

    你可以尝试一个简单的循环:

    for product in productData.items {
        print("\(product.name) : \(product.salePrice)")
    }
    

    或以封闭方式:

    productData.items.forEach { print("\($0.name) : \($0.salePrice)") } 
    

    实际上您的产品已经在一个数组中:productData.items

    在 cmets 之后编辑

    您可以映射您的字段以获取单独数组中的每个值:

    let names = productData.items.map { $0.name } 
    let salePrices = productData.items.map { $0.salePrice } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-21
      • 2018-11-21
      • 2015-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多