Search code examples
jsonrestkitdtoaddattributerkobjectmapping

How to add objects of entity class(DTO's value) using "addAttributeMappings" in RestKit?


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?


Solution

  • 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)!)
        }
    }