【问题标题】:Dynamic key with object mapper带有对象映射器的动态键
【发布时间】:2019-12-27 18:38:24
【问题描述】:

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

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

整月上传的文档以月份名称为键返回,其所有文档列表为值。我的回复是这样的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"
            },
       { ….}   
        ]
    }
}

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

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)

【问题讨论】:

    标签: ios json swift objectmapper


    【解决方案1】:

    不需要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!)")
        }
    }
    

    【讨论】:

    • @riddhi 我用另一个修复更新了答案。请尝试。
    • 不能用 JSONString 定义 GroupResponse 对象。你的语法是什么?
    • 如果你有JSON,使用if let r = GroupResponse.init(JSON: yourJSON), let result = r.results {
    • 如果您使用 ObjectMapper,您可以使用使用 PropertyWrappers 在 ObjectMapper 上编写的 BetterMappable (github.com/PhonePe/BetterMappable) 减少大量样板代码。您需要使用 Swift 5.1 才能使用它。
    • @Srikanth,看起来很有希望。希望您注意未来的兼容性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多