我无法在swift 3中实现模型类?

时间:2017-10-04 11:48:10

标签: ios swift3

以下是用于为我的模型类编写的代码。我在这一行中遇到错误let objArr = jsonObj["items"] as? [[String:Any]]任何人都可以帮我解决问题,在属性类中我只需要获取密钥的特定值,例如"attribute_code": "image"。然后我需要在同一个字典中获取value键值对

let url = "http://www.json-generator.com/api/json/get/ceEBeRUkWG?indent=2"
func newCategoryJsonWithURL() {
        let url = URL(string: newCategoryUrl)!
        let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
            if error != nil { print(error!); return }
            do {
                if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
                    let objArr = jsonObj["items"] as? [[String:Any]]
                    self.items = objArr.map{item(dict: $0)}
                    DispatchQueue.main.async {
                    }
                }
            } catch {
                print(error)
            }
        }
        task.resume()
    }
struct item {

    let name : String
    let sku : Any
    let id : Int
    let attributeSetId : Int
    let price : Int
    let status : Int
    let visibility : Int
    let typeId: String
    let createdAt : Any
    let updatedAt : Any
    let customAttribute = [Attribute]()


    init(dict : [String:Any]) {
        if let childrenList = dict["custom_attributes"] as? [[String: AnyObject]] {
            var result = [Attribute]()
            for obj in childrenList {
                result.append(Attribute(json: obj))
            }
            self.customAttribute = result
        } else {
            self.customAttribute = [Attribute]()
        }

        self.name = dict["name"] as? String ?? ""
        self.sku = dict["sku"] as? Any ?? ""
        self.id = dict["id"] as? Int ?? 0
        self.attributeSetId = dict["attribute_set_id"] as? Int ?? 0
        self.price = dict["price"] as? Int ?? 0
        self.status = dict["status"] as? Int ?? 0
        self.visibility = dict["visibility"] as? Int ?? 0
        self.typeId = dict["type_id"] as? String ?? ""
        self.createdAt = dict[""] as? Any ?? ""
        self.updatedAt = dict[""] as? Any ?? ""
    }
}
struct Attribute {

    let attributeCode : String
    let value : String

    init(json : [String:Any]) {
        self.attributeCode = json["attribute_code"] as? String ?? ""
        self.value = json["value"] as? String ?? ""
    }
}

这是如下图所示的错误

enter image description here

2 个答案:

答案 0 :(得分:1)

我已经解决了你的问题。并尝试找出解决方案。

到目前为止,我所做的是,从传入的JSON结构中创建一个蓝色的模型类。

请查看以下代码。

    import UIKit

class ViewController: UIViewController {

    var objModel : ModelClass?
    var tableView : UITableView!
    var totalRecords : Int = 100
    var isLoadMore : Bool = false

    override func viewDidLoad() {
        super.viewDidLoad()

        self.title = "JSON Demo"

        tableView = UITableView()
        tableView.delegate = self
        tableView.tableFooterView = UIView()
        tableView.dataSource = self
        tableView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(tableView)
        NSLayoutConstraint.activate([
            tableView.topAnchor.constraint(equalTo: self.view.topAnchor),
            tableView.rightAnchor.constraint(equalTo: self.view.rightAnchor),
            tableView.leftAnchor.constraint(equalTo: self.view.leftAnchor),
            tableView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor),
            ])
        self.makeAPICall(isLoadMoreRequest: false)
        let btnLoadMore = UIBarButtonItem(title: "Load More", style: .plain, target: self, action: #selector(self.onLoadMore(sender:)))
        self.navigationItem.rightBarButtonItem = btnLoadMore
        btnLoadMore.isEnabled = false
    }

    @objc func onLoadMore(sender:UIBarButtonItem) {
        self.makeAPICall(isLoadMoreRequest: true)
    }

    @objc func makeAPICall(isLoadMoreRequest:Bool) {

        UIApplication.shared.isNetworkActivityIndicatorVisible = true

        let strURL = "http://www.json-generator.com/api/json/get/ceEBeRUkWG?indent=2"
        guard let url = URL(string: strURL) else { return }
        self.navigationItem.rightBarButtonItem?.isEnabled = false
        if isLoadMoreRequest {
            self.isLoadMore = true
        } else {
            self.isLoadMore = false
        }
        let task = URLSession.shared.dataTask(with: url, completionHandler: { [weak self] data, response, error in
            guard let this = self else { return }
            if isLoadMoreRequest {
                this.isLoadMore = false
            }
            guard let _data = data else {
                if let err = error {
                    print(err.localizedDescription)
                }
                this.navigationItem.rightBarButtonItem?.isEnabled = true
                DispatchQueue.main.async {
                    UIApplication.shared.isNetworkActivityIndicatorVisible = false
                }
                return
            }
            let jsonString = try? JSONSerialization.jsonObject(with: _data, options: JSONSerialization.ReadingOptions.mutableContainers)
            guard let jsonDict = jsonString as? [String:AnyObject] else { return }
            if !isLoadMoreRequest {
                this.objModel = ModelClass(dict: jsonDict)
            } else {
                let arr = jsonDict["items"] as? NSArray ?? []
                this.objModel?.addMoreItems(items: arr)
            }
            DispatchQueue.main.async {
                this.navigationItem.rightBarButtonItem?.isEnabled = true
                this.tableView.reloadData()
                UIApplication.shared.isNetworkActivityIndicatorVisible = false
            }
        })
        task.resume()
    }
}

extension ViewController : UITableViewDelegate, UITableViewDataSource {

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        guard let obj = self.objModel else { return }
        guard let lastCell = self.tableView.indexPathsForVisibleRows?.last else { return }
        if (lastCell.row + 1 >= obj.items.count) && (totalRecords > obj.items.count) && !isLoadMore {
            self.makeAPICall(isLoadMoreRequest: true)
        }
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let obj = self.objModel else { return 0 }
        return obj.items.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell\(indexPath.section)")
        guard let arr = self.objModel?.items else { return UITableViewCell() }
        let obj = arr[indexPath.row]

        cell.textLabel?.text = obj.name + " " + indexPath.row.description
        cell.detailTextLabel?.text = obj.price.description

        return cell
    }
}

struct ModelClass {
    var items : [MDL_Item]
    var total_count : Int
    var search_criteria : MDL_Search_Criteria

    mutating func addMoreItems(items:NSArray) {
        for obj in items {
            self.items.append(MDL_Item(dict: obj as? [String:AnyObject] ?? [:]))
        }
    }

    init(dict:[String:AnyObject]) {
        total_count = dict["total_count"] as? Int ?? 0

        let _dict = dict["search_criteria"] as? [String:AnyObject] ?? [:]
        search_criteria = MDL_Search_Criteria(dict: _dict)

        let arr = dict["items"] as? NSArray ?? []
        var _arr = [MDL_Item]()
        for obj in arr {
            _arr.append(MDL_Item(dict: obj as? [String:AnyObject] ?? [:]))
        }
        items = _arr
    }
}

struct MDL_Item {
    var id : Int
    var created_at : String
    var attribute_set_id : Int
    var sku  : String
    var custom_attributes : [MDL_Attribute]
    var price : Int
    var type_id : String
    var updated_at : String
    var visibility : Int
    var status : Int
    var name : String

    init(dict:[String:AnyObject]) {

        id = dict["id"] as? Int ?? 0
        attribute_set_id = dict["attribute_set_id"] as? Int ?? 0
        price = dict["price"] as? Int ?? 0
        visibility = dict["visibility"] as? Int ?? 0
        status = dict["status"] as? Int ?? 0

        created_at = dict["created_at"] as? String ?? ""
        sku = dict["sku"] as? String ?? ""
        type_id = dict["type_id"] as? String ?? ""
        updated_at = dict["updated_at"] as? String ?? ""
        name = dict["name"] as? String ?? ""

        let arr = dict["custom_attributes"] as? NSArray ?? []
        var _arr = [MDL_Attribute]()
        for obj in arr {
            _arr.append(MDL_Attribute(dict: obj as? [String:AnyObject] ?? [:]))
        }
        custom_attributes = _arr
    }
}

struct MDL_Attribute {
    var attribute_code : String
    var value : String
    init(dict:[String:AnyObject]) {
        attribute_code = dict["attribute_code"] as? String ?? ""
        value = dict["value"] as? String ?? ""
    }
}

struct MDL_Search_Criteria {
    var filter_groups : [MDL_Filter_Group]
    init(dict:[String:AnyObject]) {
        let arr = dict["filter_groups"] as? NSArray ?? []
        var _arr = [MDL_Filter_Group]()
        for obj in arr {
            _arr.append(MDL_Filter_Group(dict: obj as? [String:AnyObject] ?? [:]))
        }
        self.filter_groups = _arr
    }
}

struct MDL_Filter_Group {
    var filters : [MDL_Filter]
    init(dict:[String:AnyObject]) {
        let arr = dict["filters"] as? NSArray ?? []
        var _arr = [MDL_Filter]()
        for obj in arr {
            _arr.append(MDL_Filter(dict: obj as? [String:AnyObject] ?? [:]))
        }
        self.filters = _arr
    }
}

struct MDL_Filter {
    var condition_type : String
    var field : String
    var value : String

    init(dict:[String:AnyObject]) {
        condition_type = dict["condition_type"] as? String ?? ""
        field = dict["field"] as? String ?? ""
        value = dict["value"] as? String ?? ""
    }
}

答案 1 :(得分:0)

请检查:

var items :[item] = []
func newCategoryJsonWithURL() {
    let url = URL(string: newCategoryUrl)!
    let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
        if error != nil { print(error!); return }
        do {
            if let jsonObj = try JSONSerialization.jsonObject(with: data!) as? [String:Any] {
                let objArr = jsonObj["items"] as? [[String:Any]]
                for i in 0..<objArr!.count {
                    self.items.append(item(dict: objArr![i]))
                }
                DispatchQueue.main.async {

                    let itemsCount = self.items.count
                    for i in 0..<itemsCount {
                        let customAttribute = self.items[i].customAttribute
                        for j in 0..<customAttribute.count {
                            if customAttribute[j].attributeCode == "image" {
                                print("customAttribute value", customAttribute[j].value)
                            }
                        }
                    }
                }
            }

        } catch {
            print(error)
        }
    }
    task.resume()
}