gpt4 book ai didi

ios - 在 swift 4 和 Xcode 9 中为 ExpandableTableView 解码嵌套的 json 数组

转载 作者:行者123 更新时间:2023-11-28 14:47:27 25 4
gpt4 key购买 nike

我是 iOS 的新手,正在用 JSON 数据制作一个 ExpandableTableView。数据采用嵌套数组的形式。我想将父数组的数据设置为 TableView header 并将子数组的数据设置为 ExpandableTable 元素。我正在通过 structenums 执行 JSONDecoding 并将响应存储在 DataModelClass 中。解码时抛出错误

typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))

没关系,因为我知道我遗漏了一些非常小的东西。我已经经历了很多次,但我无法理解这个问题。

堆栈中有许多类似类型的问题,但没有一个符合我的标准。请帮帮我。

我的JSON是

    [
{
"category_id": "1",
"category_name": "ROLL",
"category_start_time": "10:00:00",
"category_end_time": "22:59:59",
"data": [
{
"id": "301",
"item_code": null,
"item_name": "CHICKN ROLL",
"main_item_id": "1",
"item_price": null,
"tax_id": "0",
"tax_per": "0",
"tax_amount": "0",
"item_net_price": "180",
"sub_item_price": "0",
"sub_tax_amount": "0",
"sub_item_net_price": "0",
"created_date": "2018-02-28 12:20:53",
"created_by": null,
"image_name": "",
"image_path": null,
"quantity": null,
"notify_quant": null,
"active": "1",
"today_avilable": "1",
"kot": "1",
"counter_id": "0",
"store_id": "1"
}
]
}
]

模型类是

    import Foundation

class AllStoreItems {
var category_id: String
var category_name: String
var category_start_time: String
var category_end_time: String
var data: [data]
var expanded: Bool

init(category_id: String, category_name: String, category_start_time: String, category_end_time: String, data: [data], expanded: Bool = false) {
self.category_id = category_id
self.category_name = category_name
self.category_start_time = category_start_time
self.category_end_time = category_end_time
self.data = data
self.expanded = expanded
}

}

class ItemsData {
var id: String
var item_code: String
var item_name: String
var main_item_id: String
var item_price: String
var tax_id: String
var tax_per: String
var tax_amount: String
var item_net_price: String
var sub_item_price: String
var sub_tax_amount: String
var sub_item_net_price: String
var created_date: String
var created_by: String
var image_name: String
var image_path: String
var quantity: String
var notify_quant: String
var active: String
var today_avilable: String
var kot: String
var counter_id: String
var store_id: String

init(id: String, item_code: String, item_name: String, main_item_id: String, item_price: String, tax_id: String, tax_per: String, tax_amount: String, item_net_price: String, sub_item_price: String, sub_tax_amount: String, sub_item_net_price: String, created_date: String, created_by: String, image_name: String, image_path: String, quantity: String, notify_quant: String, active: String, today_avilable: String, kot: String, counter_id: String, store_id: String) {
self.id = id
self.item_code = item_code
self.item_name = item_name
self.main_item_id = main_item_id
self.item_price = item_price
self.tax_id = tax_id
self.tax_per = tax_per
self.tax_amount = tax_amount
self.item_net_price = item_net_price
self.sub_item_price = sub_item_price
self.sub_tax_amount = sub_tax_amount
self.sub_item_net_price = sub_item_net_price
self.created_date = created_date
self.created_by = created_by
self.image_name = image_name
self.image_path = image_path
self.quantity = quantity
self.notify_quant = notify_quant
self.active = active
self.today_avilable = today_avilable
self.kot = kot
self.counter_id = counter_id
self.store_id = store_id
}
}

我的结构和枚举是

import Foundation

struct AllItem: Decodable {
var category_id: String
var category_name: String
var category_start_time: String
var category_end_time: String
var data: [data]

enum AllItem: String {
case category_id = "category_id"
case category_name = "category_name"
case category_start_time = "category_start_time"
case category_end_time = "category_end_time"
case data = "data"
}
}

struct data: Decodable {
var id: String
var item_code: String
var item_name: String
var main_item_id: String
var item_price: String
var tax_id: String
var tax_per: String
var tax_amount: String
var item_net_price: String
var sub_item_price: String
var sub_tax_amount: String
var sub_item_net_price: String
var created_date: String
var created_by: String
var image_name: String
var image_path: String
var quantity: String
var notify_quant: String
var active: String
var today_avilable: String
var kot: String
var counter_id: String
var store_id: String

enum data: String {
case id = "id"
case item_code = "item_code"
case item_name = "item_name"
case main_item_id = "main_item_id"
case item_price = "item_price"
case tax_id = "tax_id"
case tax_per = "tax_per"
case tax_amount = "tax_amount"
case item_net_price = "item_net_price"
case sub_item_price = "sub_item_price"
case sub_tax_amount = "sub_tax_amount"
case sub_item_net_price = "sub_item_net_price"
case created_date = "created_date"
case created_by = "created_by"
case image_name = "image_name"
case image_path = "image_path"
case quantity = "quantity"
case notify_quant = "notify_quant"
case active = "active"
case today_avilable = "today_avilable"
case kot = "kot"
case counter_id = "counter_id"
case store_id = "store_id"
}

}

我的 ViewController 是

class CustomItemTableView: UITableViewCell {

@IBOutlet weak var textLabelOne: UILabel!
@IBOutlet weak var textLabelTwo: UILabel!

}

class AllItemsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, AllItemsHeaderViewDelegate {

@IBOutlet weak var headerStoreLogoIV: UIImageView!
@IBOutlet weak var tableView: UITableView!

var storeId: String = ""
var storeCatId: String = ""
var storeName: String = ""
var storeLogoLink: String = ""

@IBOutlet weak var storeImage: UIImageView!
@IBOutlet weak var storeNameLabel: UILabel!


let mainUrl = BaseURL()

var items = [AllStoreItems]()
var subItems = [ItemsData]()

override func viewDidLoad() {
super.viewDidLoad()
ExpandItemsApi()
let imgUrl: String = mainUrl.MainUrl + "logo/" + storeLogoLink
let imgUrlStr: String = imgUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
//let imgUrl2: URL = URL(string: imgUrlStr)!

//let imgUrl3 = URLRequest(url: imgUrl2!)

storeNameLabel.text = storeName
// storeNames.text = storeName
// storeCategory.text = storeCatId
// storeIds.text = storeId
// imgLink.text = storeLogoLink

storeImage.downloadedFrom(link: imgUrlStr)

}

@IBAction func backButton(_ sender: Any) {
self.dismiss(animated: false, completion: nil)
}

func ExpandItemsApi() {

let myActivityIndicator = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)

myActivityIndicator.center = view.center
myActivityIndicator.hidesWhenStopped = false
myActivityIndicator.startAnimating()
view.addSubview(myActivityIndicator)

let itemsUrl = URL(string: mainUrl.MainUrl + "viewmaincat")
var itemUrls = URLRequest(url: itemsUrl!)
itemUrls.httpMethod = "POST"

itemUrls.addValue("application/json", forHTTPHeaderField: "content-type")
itemUrls.addValue("application/json", forHTTPHeaderField: "Accept")

let storeDetails = ["store_id": storeId] as [String: String]

do {
itemUrls.httpBody = try JSONSerialization.data(withJSONObject: storeDetails, options: .prettyPrinted)
}catch let error {
toastNeck(message: "\(error)")
myActivityIndicator.stopAnimating()
myActivityIndicator.hidesWhenStopped = true
}

URLSession.shared.dataTask(with: itemUrls) {
(datas, response, error) in
if datas != nil {
do {
let itemDetails = try JSONDecoder().decode(AllItem.self, from: datas!)

self.items.append(AllStoreItems(category_id: itemDetails.category_id, category_name: itemDetails.category_name, category_start_time: itemDetails.category_start_time, category_end_time: itemDetails.category_end_time, data: itemDetails.data))

print(itemDetails.data)
// let subItem = try JSONDecoder().decode(data.self, from: datas!)
// self.subItems.append(ItemsData(id: subItem.id, item_code: subItem.item_code, item_name: subItem.item_name, main_item_id: subItem.main_item_id, item_price: subItem.item_price, tax_id: subItem.tax_id, tax_per: subItem.tax_per, tax_amount: subItem.tax_amount, item_net_price: subItem.item_net_price, sub_item_price: subItem.sub_item_price, sub_tax_amount: subItem.sub_tax_amount, sub_item_net_price: subItem.sub_item_net_price, created_date: subItem.created_date, created_by: subItem.created_by, image_name: subItem.image_name, image_path: subItem.image_path, quantity: subItem.quantity, notify_quant: subItem.notify_quant, active: subItem.active, today_avilable: subItem.today_avilable, kot: subItem.kot, counter_id: subItem.counter_id, store_id: subItem.store_id))
}catch let errors {
self.toastNeck(message: "\(errors)")
print(errors)
DispatchQueue.main.async{
myActivityIndicator.stopAnimating()
myActivityIndicator.hidesWhenStopped = true
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}.resume()

}

func numberOfSections(in tableView: UITableView) -> Int {
return items.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items[section].data.count
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if items[indexPath.section].expanded {
return 50
}else {
return 0
}
}

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 5
}

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let header = AllItemsHeaderView()
header.customInit(title: items[section].category_name, section: section, delegate: self)
return header
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: CustomItemTableView = tableView.dequeueReusableCell(withIdentifier: "customItems") as! CustomItemTableView
cell.textLabelOne.text = items[indexPath.section].data[indexPath.row].item_name
cell.textLabelTwo.text = items[indexPath.section].data[indexPath.row].item_price
return cell
}

func toggleSection(header: AllItemsHeaderView, section: Int) {
items[section].expanded = !items[section].expanded
tableView.beginUpdates()

for i in 0 ..< items[section].data.count {
tableView.reloadRows(at: [IndexPath(row: i, section: section)], with: .automatic)
}
tableView.endUpdates()
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
toastNeck(message: items[indexPath.section].data[indexPath.row].item_name)
}

func toastNeck(message: String) {
DispatchQueue.main.async {
let toastLabel = UILabel(frame: CGRect(x: self.view.frame.size.width/2-100, y: self.view.frame.size.height/2, width: 200, height: 40))
toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.4)
toastLabel.textColor = UIColor.white
toastLabel.textAlignment = NSTextAlignment.center
toastLabel.text = message
toastLabel.layer.cornerRadius = 15
toastLabel.clipsToBounds = true
self.view.addSubview(toastLabel)
UIView.animate(withDuration: 8, animations: {
toastLabel.alpha = 0}, completion: {(isCompleted) in toastLabel.removeFromSuperview()})
}
}
}

如果有人需要更多,请评论...

最佳答案

尝试改变这两行:

let itemDetails = try JSONDecoder().decode(AllItem.self, from: datas!)

self.items.append(AllStoreItems(category_id: itemDetails.category_id, category_name: itemDetails.category_name, category_start_time: itemDetails.category_start_time, category_end_time: itemDetails.category_end_time, data: itemDetails.data))

let itemDetails = try JSONDecoder().decode([AllItem].self, from: datas!)

for item in itemDetails {
self.items.append(AllStoreItems(category_id: item.category_id, category_name: item.category_name, category_start_time: item.category_start_time, category_end_time: item.category_end_time, data: item.data))
}

而且也不需要枚举 AllItemdata 因为属性名称已经与 JSON 键相同。

关于ios - 在 swift 4 和 Xcode 9 中为 ExpandableTableView 解码嵌套的 json 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50132707/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com