带有对象映射器的动态键

Dynamic key with object mapper

我在 Swift 4 中写作,使用 viper 结构和 ObjectMapper 将我的 JSON 响应映射到我的模型。

我正在尝试用动态键映射这个相当复杂的 JSON 响应,并希望得到一些关于我做错了什么的反馈。

整月上传的文档为return,以月份名称为键,其所有文档列表为值。我的回复是这样的 json:

{  
    "results": {
        "2019-08": [
            {
                "id": 2,
                "user_id": 7,
                "document": "1566282328atlassian-git-cheatsheet1.pdf",
                "name": "atoz",
                "order": 0,
                "is_edit": 0,
                "edit_json": "",
                "created_at": "2019-08-20 06:25:28",
                "updated_at": "2019-08-20 06:25:28",
                "date": "2019-08",
                "url": "http://35.154.206.145/storage/pdf/1566282328atlassian-git-cheatsheet1.pdf"
            },
        { ….}                
        ],
  "2019-07": [
            {
                "id": 2,
                "user_id": 7,
                "document": "1566282328atlassian-git-cheatsheet1.pdf",
                "name": "atoz",
                "order": 0,
                "is_edit": 0,
                "edit_json": "",
                "created_at": "2019-08-20 06:25:28",
                "updated_at": "2019-08-20 06:25:28",
                "date": "2019-08",
                "url": "http://35.154.206.145/storage/pdf/1566282328atlassian-git-cheatsheet1.pdf"
            },
       { ….}   
        ]
    }
}

我的模型class是这样在mapper模型中获取数据的class

import ObjectMapper

struct GroupResponse: Mappable {

    init?(map: Map) {}

    var results: [String: DocumentObject]?

    mutating func mapping(map: Map) {
        results   <- map["results"]
    }
}

class DocumentObject: Mappable{

    internal var months: [String: [DocumentListObject]]?

    required init?(map: Map) {}

    func mapping(map: Map) {
        for (monthKey, monthValue) in map.JSON as! [String: [String: Any]] {
            let month = DocumentListObject()
            months?[monthKey] = [month]
        }
    }
}

class DocumentListObject {

     var id:Int?
     var user_id:Int?
     var document:String?
     var name:String?
     var order:Int?
     var is_edit:Bool?
     var edit_json:String?
     var date:String?
     var url:String?
}

这有什么问题,在 api 响应

中找到它时我得到 nil 并崩溃
if let json = data as AnyObject? {
                let arrayResponse = json as! NSDictionary

                let arrayObject = Mapper<GroupResponse>().mapDictionary(JSON: arrayResponse as! [String : [String : Any]]) // I got crash here
                print(arrayObject)

不需要DocumentObject。试试这个,

struct GroupResponse: Mappable {

    init?(map: Map) {}

    var results: [String: [DocumentListObject]]?

    mutating func mapping(map: Map) {
        results   <- map["results"]
    }
}

还有,你忘了让DocumentListObject符合Mappable。请更新如下,

class DocumentListObject: Mappable {

    var id:Int?
    var user_id:Int?
    var document:String?
    var name:String?
    var order:Int?
    var is_edit:Bool?
    var edit_json:String?
    var date:String?
    var url:String?

    required init?(map: Map) {}

    func mapping(map: Map) {
        id   <- map["id"]
        user_id   <- map["user_id"]
        document   <- map["document"]
        name   <- map["name"]
        order   <- map["order"]
        is_edit   <- map["is_edit"]
        edit_json   <- map["edit_json"]
        date   <- map["date"]
        url   <- map["url"]
    }
}

用法:

        let data = """
{
    "results": {
        "2019-08": [
            {
                "id": 2,
                "user_id": 7,
                "document": "1566282328atlassian-git-cheatsheet1.pdf",
                "name": "atoz",
                "order": 0,
                "is_edit": 0,
                "edit_json": "",
                "created_at": "2019-08-20 06:25:28",
                "updated_at": "2019-08-20 06:25:28",
                "date": "2019-08"
            }
          ]
       }
}
"""

        if let r = GroupResponse.init(JSONString: data), let result = r.results {
            for (key, value) in result {
                print("Key: \(key)" )
                print("DocumentName: \(value.first!.document!)")
            }
        }
// prints
Key: 2019-08
DocumentName: 1566282328atlassian-git-cheatsheet1.pdf

当您从响应中获得 JSON 时,请使用以下示例来解析 GroupResponse。

let json = your JSON (of type [String: Any]) object retrieved from the API
if let r = GroupResponse.init(JSON: json), let result = r.results {
    for (key, value) in result {
        print("Key: \(key)" )
        print("DocumentName: \(value.first!.document!)")
    }
}