2

I am an android developer new to swift 3 programming, I am using Alamofire for making api calls and to avoid tedious json paring I am using AlamofireObjectMapper library. I have a ApiController which has a function to make api calls below is the code for that:

public static func makePostRequest<T: Mappable>(url: String, params: Parameters, networkProtocol: NetworkProtocol, responseClass: T){

    let headers = getHeaders()

    networkProtocol.showProgress()

    Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers)
        .validate()
        .responseObject{
            (response: DataResponse<T>) in

            switch(response.result){
            case .success(_):
                networkProtocol.hideProgress()
                networkProtocol.onResponse(response: response)
                break
            case .failure(_):
                networkProtocol.hideProgress()
                networkProtocol.onErrorResponse(response: response)
                break
            }

    }

Below is my model class:

import ObjectMapper

    class BaseResponse: Mappable {

    required init?(map: Map) {

    }

    func mapping(map: Map) {

    }
}

And below is the function to class make the api call:

public static func callSomeApi(params: Parameters, networkProtocol: NetworkProtocol){
    ApiHelper.makePostRequest(url: AppConstants.URLs.API_NAME, params: params, networkProtocol: networkProtocol, responseClass: BaseResponse)
}

Now the error is in the below line

ApiHelper.makePostRequest(url: AppConstants.URLs.API_NAME, params: params, networkProtocol: networkProtocol, responseClass: BaseResponse)

It says Argument type 'BaseResponse.Type' does not conform to expected type 'Mappable'

Someone please help me resolve this, stuck on this issue for quite a while now.

Syn3sthete
  • 4,151
  • 3
  • 23
  • 41
  • Can you show the code for your 'responseClass'? Also you should name your class ResponseClass. – totiDev May 03 '17 at 08:17
  • Did you copy-paste this code ? `responseClass` should be the name of the class in which the result of the request will be mapped. Replace it with your class name which follows [this format](https://github.com/tristanhimmelman/AlamofireObjectMapper/blob/master/AlamofireObjectMapperTests/AlamofireObjectMapperTests.swift#L327). – Toldy May 03 '17 at 08:23
  • @Toldy I want the class name to be dynamic that's why I want to accept response class name as a parameter – Syn3sthete May 03 '17 at 10:11
  • 1
    Oh sorry, I didn't see that you were taken the class name as a parameter. Then `responseClass` is the name of your variable. `T` is its type. Change `` to ``, and change `makePostRequest` to `makePostRequest` (because responseObject only accept objects which obeys to mappable protocol) – Toldy May 03 '17 at 10:22
  • @Toldy check my updated question, now I am getting the error as "Use of undeclared type 'Mappable'" – Syn3sthete May 03 '17 at 11:48
  • 1
    Did you add the good imports [like here](https://github.com/tristanhimmelman/AlamofireObjectMapper/blob/master/AlamofireObjectMapperTests/AlamofireObjectMapperTests.swift#L31-L33) ? `Mappable` is defined in ObjectMapper if I remember well – Toldy May 03 '17 at 11:52
  • That was a silly mistake on my part thanks for pointing it out, I was importing 'AlamofireObjectMapper' instead – Syn3sthete May 03 '17 at 11:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/143285/discussion-between-syn3sthete-and-toldy). – Syn3sthete May 03 '17 at 12:42
  • @Toldy moved to chat please check it whenever you are free – Syn3sthete May 03 '17 at 12:54

2 Answers2

2

Heres a reference request using object mapping

import Alamofire
import ObjectMapper
import AlamofireObjectMapper


       func requestUrl<T:Mappable>(url: URLRequestConvertible, withSuccess success:@escaping (_ response: T) -> ()) {
        Utils.addHUD()

        Alamofire.request(url).validate().responseObject { (response :DataResponse<T>) in
            Utils.hideHUD()
            guard response.result.isSuccess else{
                Utils.showAlert(message: (response.result.error?.localizedDescription)!, action: {

                })
                return
            }
            let root:RootClass = response.result.value as! RootClass
            if root.status  == "Fail"{
                Utils.showAlert(message: (root.msg!), action: {

                })
            }else{

                success(response.result.value!)
            }
        }


    }

Heres my class to map

import ObjectMapper


class RootClass : NSObject, Mappable{

    var data : [String : Any]?
    var msg : String?
    var status : String?


    class func newInstance(map: Map) -> Mappable?{
        return RootClass()
    }

    required init?(map: Map){
        super.init()
    }
    private override init(){
        super.init()
    }

    func mapping(map: Map)
    {
        data <- map["data"]
        msg <- map["msg"]
        status <- map["status"]

        }
}
harshal jadhav
  • 5,456
  • 2
  • 18
  • 26
0

There is no need to declare the type of the argument to the block when using the block:

Alamofire.request(url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers)
    .validate()
    .responseData { response in

        switch(response.result){
        case .success(_):
            networkProtocol.hideProgress()
            networkProtocol.onResponse(response: response)
            break
        case .failure(_):
            networkProtocol.hideProgress()
            networkProtocol.onErrorResponse(response: response)
            break
        }

}
Max Pevsner
  • 4,098
  • 2
  • 18
  • 32