首页 > json > 如何在RestKit中使用“addAttributeMappings”添加实体类的对象(DTO的值)?

如何在RestKit中使用“addAttributeMappings”添加实体类的对象(DTO的值)? (How to add objects of entity class(DTO's value) using “addAttributeMappings” in Rest)

问题

我的json响应不仅包含字符串,还包含DTO数组。对象映射没有以正确的格式发生。

json响应机构:

{
  "id": null,
  "componentName": "Home Loan",
  "dynamicTableDetailDTOList": [
    {
      "id": 1,
      "fieldName": "username",
      "fieldType": "string",
      "isJoin": false,
      "joinType": null,
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 30,
      "label": "Name",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    },
    {
      "id": 2,
      "fieldName": "age",
      "fieldType": "integer",
      "isJoin": false,
      "joinType": null,
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 2,
      "label": "Age",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    },
    {
      "id": 3,
      "fieldName": "Gender",
      "fieldType": "radio",
      "isJoin": false,
      "joinType": [
        {
          "displayId": 0,
          "Value": "Male"
        },
        {
          "displayId": 1,
          "Value": "Female"
        }
      ],
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 30,
      "label": "Gender",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    },
    {
      "id": 4,
      "fieldName": "education",
      "fieldType": "combo",
      "isJoin": false,
      "joinType": [
        {
          "displayId": 0,
          "Value": "Btech"
        },
        {
          "displayId": 1,
          "Value": "Mca"
        },
        {
          "displayId": 2,
          "Value": "Mba"
        },
        {
          "displayId": 3,
          "Value": "Mcom"
        }
      ],
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 30,
      "label": "Education",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    }
  ]
}

下面给出的是我的实体模型。(请注意,dynamicTableDetailDTOList是DTO的数组):

class LoanDetailModel: NSObject {

    var id:Any?
    var componentName = ""
    var dynamicTableDetailDTOList:[DynamicTableDetailDTOList] = []
}

class DynamicTableDetailDTOList: NSObject {

    var id:Int?
    var fieldName:String = ""
    var fieldType:String = ""
    var isJoin:Bool?
    var length:Int?
    var label:String = ""
    var isrequired:Bool?
    var searchable:Bool?
}

在我的ViewController中调用了一个回调方法,

override func viewDidLoad() {
    super.viewDidLoad()

    let loanDetailService = LoanDetailService()
    loanDetailService.getLoanDetails(success: { (model) in
        self.loanDetailModel = model!
        self.loanDetailTable.reloadData()
    })
    { (errorString) in
        let alert = UIAlertController(title: "Alert",
                                      message: errorString,
                                      preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

在LoanDetailService类中,实现与服务调用相关的所有代码:

func getLoanDetails(success: @escaping((_ loanDetailModel: LoanDetailModel?) -> ()),
                    failure: @escaping ((_ error:String) -> ())) {

    // Define mappings
    let postMapping: RKObjectMapping = RKObjectMapping(for: LoanDetailModel.self)
    postMapping.addAttributeMappings(from: ["id", "componentName", "dynamicTableDetailDTOList"])


    // Define response decriptor
    let statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClass.successful)
    let resDescriptor = RKResponseDescriptor(mapping: postMapping, method: RKRequestMethod.GET, pathPattern: nil, keyPath: nil, statusCodes: statusCodes)

    // Create object manager
    let url = URL(string: baseURL)
    let jsonPlaceholderManager = RKObjectManager(baseURL: url)
    jsonPlaceholderManager?.addResponseDescriptor(resDescriptor)
    RKObjectManager.setShared(jsonPlaceholderManager)

    // Perform GET request
    RKObjectManager.shared().getObjectsAtPath(appendedURL, parameters: nil, success: { (operation, mappingResult) -> Void in
        let loanDetailModel: LoanDetailModel = mappingResult!.firstObject as! LoanDetailModel
        success(loanDetailModel)

    }) { (operation, error) -> Void in
        failure((error?.localizedDescription)!)
    }

}

如何对我的实体模型进行更改?

解决方法

以下解决了我的问题:

在LoanDetailServiceClass中,

func getLoanDetails(success: @escaping((_ loanDetailModel: LoanDetailModel?) -> ()),
                failure: @escaping ((_ error:String) -> ())) {

    // Define mappings
    let postMapping: RKObjectMapping = RKObjectMapping(for: LoanDetailModel.self)
    postMapping.addAttributeMappings(from: ["id","componentName"])

    let dTOListMapping: RKObjectMapping = RKObjectMapping(for: DynamicTableDetailDTOList.self)
    dTOListMapping.addAttributeMappings(from: ["fieldName",
                                               "fieldType",
                                               "label"])
    postMapping.addRelationshipMapping(withSourceKeyPath: "DynamicTableDetailDTOList" ,
                                       mapping: dTOListMapping)

    // Define response decriptor
    let statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClass.successful)
    let resDescriptor = RKResponseDescriptor(mapping: postMapping, method: RKRequestMethod.GET, pathPattern: nil, keyPath: nil, statusCodes: statusCodes)

    // Create object manager
    let url = URL(string: baseURL)
    let jsonPlaceholderManager = RKObjectManager(baseURL: url)
    jsonPlaceholderManager?.addResponseDescriptor(resDescriptor)
    RKObjectManager.setShared(jsonPlaceholderManager)

    // Perform GET request
    RKObjectManager.shared().getObjectsAtPath(appendedURL, parameters: nil, success: { (operation, mappingResult) -> Void in
        let loanDetailModel: LoanDetailModel = mappingResult!.firstObject as! LoanDetailModel
        success(loanDetailModel)

    }) { (operation, error) -> Void in
        failure((error?.localizedDescription)!)
    }
}

问题

My json response contains not only strings, but also array of DTO. Object mapping is not happening in the right format.

json response body :

{
  "id": null,
  "componentName": "Home Loan",
  "dynamicTableDetailDTOList": [
    {
      "id": 1,
      "fieldName": "username",
      "fieldType": "string",
      "isJoin": false,
      "joinType": null,
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 30,
      "label": "Name",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    },
    {
      "id": 2,
      "fieldName": "age",
      "fieldType": "integer",
      "isJoin": false,
      "joinType": null,
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 2,
      "label": "Age",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    },
    {
      "id": 3,
      "fieldName": "Gender",
      "fieldType": "radio",
      "isJoin": false,
      "joinType": [
        {
          "displayId": 0,
          "Value": "Male"
        },
        {
          "displayId": 1,
          "Value": "Female"
        }
      ],
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 30,
      "label": "Gender",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    },
    {
      "id": 4,
      "fieldName": "education",
      "fieldType": "combo",
      "isJoin": false,
      "joinType": [
        {
          "displayId": 0,
          "Value": "Btech"
        },
        {
          "displayId": 1,
          "Value": "Mca"
        },
        {
          "displayId": 2,
          "Value": "Mba"
        },
        {
          "displayId": 3,
          "Value": "Mcom"
        }
      ],
      "joinTable": null,
      "joinField": null,
      "displayField": null,
      "defaultValue": null,
      "length": 30,
      "label": "Education",
      "isrequired": true,
      "searchable": null,
      "dynamicTable": null
    }
  ]
}

Below given is my entity model. (Please note that dynamicTableDetailDTOList is an array of DTO) :

class LoanDetailModel: NSObject {

    var id:Any?
    var componentName = ""
    var dynamicTableDetailDTOList:[DynamicTableDetailDTOList] = []
}

class DynamicTableDetailDTOList: NSObject {

    var id:Int?
    var fieldName:String = ""
    var fieldType:String = ""
    var isJoin:Bool?
    var length:Int?
    var label:String = ""
    var isrequired:Bool?
    var searchable:Bool?
}

In my ViewController a call back method is called,

override func viewDidLoad() {
    super.viewDidLoad()

    let loanDetailService = LoanDetailService()
    loanDetailService.getLoanDetails(success: { (model) in
        self.loanDetailModel = model!
        self.loanDetailTable.reloadData()
    })
    { (errorString) in
        let alert = UIAlertController(title: "Alert",
                                      message: errorString,
                                      preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

In LoanDetailService class, where all the code related to service call is implemented :

func getLoanDetails(success: @escaping((_ loanDetailModel: LoanDetailModel?) -> ()),
                    failure: @escaping ((_ error:String) -> ())) {

    // Define mappings
    let postMapping: RKObjectMapping = RKObjectMapping(for: LoanDetailModel.self)
    postMapping.addAttributeMappings(from: ["id", "componentName", "dynamicTableDetailDTOList"])


    // Define response decriptor
    let statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClass.successful)
    let resDescriptor = RKResponseDescriptor(mapping: postMapping, method: RKRequestMethod.GET, pathPattern: nil, keyPath: nil, statusCodes: statusCodes)

    // Create object manager
    let url = URL(string: baseURL)
    let jsonPlaceholderManager = RKObjectManager(baseURL: url)
    jsonPlaceholderManager?.addResponseDescriptor(resDescriptor)
    RKObjectManager.setShared(jsonPlaceholderManager)

    // Perform GET request
    RKObjectManager.shared().getObjectsAtPath(appendedURL, parameters: nil, success: { (operation, mappingResult) -> Void in
        let loanDetailModel: LoanDetailModel = mappingResult!.firstObject as! LoanDetailModel
        success(loanDetailModel)

    }) { (operation, error) -> Void in
        failure((error?.localizedDescription)!)
    }

}

How do I make changes with respect to my entity model?

解决方法

The below solved my issue :

In LoanDetailServiceClass,

func getLoanDetails(success: @escaping((_ loanDetailModel: LoanDetailModel?) -> ()),
                failure: @escaping ((_ error:String) -> ())) {

    // Define mappings
    let postMapping: RKObjectMapping = RKObjectMapping(for: LoanDetailModel.self)
    postMapping.addAttributeMappings(from: ["id","componentName"])

    let dTOListMapping: RKObjectMapping = RKObjectMapping(for: DynamicTableDetailDTOList.self)
    dTOListMapping.addAttributeMappings(from: ["fieldName",
                                               "fieldType",
                                               "label"])
    postMapping.addRelationshipMapping(withSourceKeyPath: "DynamicTableDetailDTOList" ,
                                       mapping: dTOListMapping)

    // Define response decriptor
    let statusCodes = RKStatusCodeIndexSetForClass(RKStatusCodeClass.successful)
    let resDescriptor = RKResponseDescriptor(mapping: postMapping, method: RKRequestMethod.GET, pathPattern: nil, keyPath: nil, statusCodes: statusCodes)

    // Create object manager
    let url = URL(string: baseURL)
    let jsonPlaceholderManager = RKObjectManager(baseURL: url)
    jsonPlaceholderManager?.addResponseDescriptor(resDescriptor)
    RKObjectManager.setShared(jsonPlaceholderManager)

    // Perform GET request
    RKObjectManager.shared().getObjectsAtPath(appendedURL, parameters: nil, success: { (operation, mappingResult) -> Void in
        let loanDetailModel: LoanDetailModel = mappingResult!.firstObject as! LoanDetailModel
        success(loanDetailModel)

    }) { (operation, error) -> Void in
        failure((error?.localizedDescription)!)
    }
}
相似信息