0

For my APIManager.swift

        APIManager.manager.request(urlEncoded, method: useMethod, parameters: params, encoding: requestEncoding, headers: headers)
            .validate(statusCode: 200..<300)
            .responseJSON { response in
            switch response.result {
            case .success(let json):
                ///
            case .failure(let error):
                ///
            }
        }

And my api json response

{
    "code": 200,
    "status": "success",
    "response_data": {
        "name": "testing"
    }
}

my model

struct TesterModel: Codable {
    var name: String
}

I need to map object with codeable protocol but map only on reponse_data field from api response. How to map it from .responseJSON ?

Nawin Poolsawad
  • 227
  • 2
  • 13
  • Custom `init(from: Decoder)` for `TesterModel` to let you skip the top level `response_data`? – Larme Jul 01 '21 at 07:49
  • @Larme can u give me some example code? – Nawin Poolsawad Jul 01 '21 at 08:22
  • Alamofire can decode JSON directly with the `responseDecodable` modifier. In any case you have to specify the struct representing the root object. – vadian Jul 01 '21 at 08:58
  • `response_data` value can be different if I read correctly another comment? So you could have `TesterModel2` , `TesterModel3` etc? If so, a Generic type on a high level wrapper might do the work. See https://stackoverflow.com/questions/49529208/ios-generic-type-for-codable-property-in-swift and use the `responseDecodable` to specify your expected output: `Wrapper.self` etc? – Larme Jul 01 '21 at 08:59

2 Answers2

1

You can use "CodingKeys" for specific fields

enum CodingKeys

Like this:

struct Landmark: Codable {
    var name: String
    var foundingYear: Int
    var location: Coordinate
    var vantagePoints: [Coordinate]
    
    enum CodingKeys: String, CodingKey {
        case name = "title"
        case foundingYear = "founding_date"
        
        case location
        case vantagePoints
    }
}

Also for decoding you can use JSONDecoder()

guard let response = try? JSONDecoder().decode(Landmark, data) else { return nil }

See More Here Apple Documentation

0

You can create another model like this:

struct APIResponse: Codable {
    var code: Int
    var status: String
    var responseData: TesterModel
}

struct TesterModel: Codable {
    var name: String
}

And then you can just do that:

APIManager.manager.request(urlEncoded, method: useMethod, parameters: params, encoding: requestEncoding, headers: headers)
            .validate(statusCode: 200..<300)
            .responseJSON { response in
            switch response.result {
                guard let data = response.data else {
                    return
                }
                do {
                    let result = try JSONDecoder().decode(APIResponse.self, from: data)
                }
                catch {
                    
                }
        }
Victor Morei
  • 180
  • 4
  • I have multiple responsedata type and I have a error case like `code` be 400. This way is not properly I think. Thank u for your reply. – Nawin Poolsawad Jul 01 '21 at 08:21