如何在UI中显示已解析的JSON数据?

时间:2018-03-26 10:01:04

标签: arrays json swift parsing codable

我已经从我从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填充的吗?提前感谢。

2 个答案:

答案 0 :(得分:0)

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

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

或以封闭的方式:

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

事实上,您的产品已经在数组中:productData.items

评论后编辑

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

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

答案 1 :(得分:0)

创建数据源数组

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)"