tristanhimmelman/AlamofireObjectMapper

Is there a way to pass a generic Type at runtime?

Closed this issue · 5 comments

I'm using AlamofireObjectMapper to deserialize json responses from APIs, but I am struggling to write a generic function where I can pass an object at runtime.
If I have 3 objects A, B, C, right now I have to create 3 functions to deserialize in A, B, C.
I would like to only have 1 function that accept as a parameter the object type and pass it to the object mapper.

I've tried with Mirroring, and using the generic T, but I always get the error "is not a type".

some examples:

 func test<T>(cls: T.Type){

        let x = Mirror(reflecting: cls)
        Alamofire.request(.POST, endpoint).responseObject { (response:  Response<x, NSError>) in

            guard response.result.error == nil
                else {
                    return
            }
        }
    }

 func test<T>(cls: T.Type){

        Alamofire.request(.POST, endpoint).responseObject { (response:  Response<cls, NSError>) in

            guard response.result.error == nil
                else {
                    return
            }
        }
    }

Any hint? Thanks

I think all you're missing is that T must implement Mappable. Something like this should work:

func test<T: Mappable>(obj: T.Type){
        Alamofire.request(.POST, endpoint).responseObject { (response: Response<[T], NSError>) in

        }
    }

True, that was easy, I should have investigated more. Thanks a lot.

I think all you're missing is that T must implement Mappable. Something like this should work:

func test<T: Mappable>(obj: T.Type){
        Alamofire.request(.POST, endpoint).responseObject { (response: Response<[T], NSError>) in

        }
    }

How to implement this generic with Alamofire 4 ?

Here is my code :

static func baseNetworkRequest<T: Mappable>(_ responseObject: T.Type, _ urlStr: String, _ method: HTTPMethod, _ params: Parameters?, _ encoding: ParameterEncoding, _ header: HTTPHeaders?) {
        
        Alamofire.request(urlStr, method: method, parameters: params, encoding: encoding, headers: header).responseJSON { (response: DataResponse<T>) in
            
        }
    }

The error :

Cannot convert value of type '(DataResponse) -> ()' to
expected argument type '(DataResponse) -> Void'

I want to return a generic in DataResponse instead of Any Please advise.

@nizzam I am dealing with the same issue.Did you find a way to do it with Alamofire 4. thanks.

Here what I'm doing.

/// For `API-Result`
enum APIResult<T> {
    case Success(T)
    case ErrorCallback(ErrorResponse)
    case FailureCallback(ErrorFailure)
}

func handleResponse<T: Codable>(result: Result<Response, MoyaError>,
                                entity: T.Type,
                                completion: @escaping(APIResult<T>)->Void) {
    
    switch result {
    case let .success(response):
        do {
            if response.statusCode == 200 {
                let decodedData = try response.map(T.self)
                print("*****************************************************")
                print("Success :", decodedData)
                completion(.Success(decodedData))
                
            } else {
                print("*****************************************************")
                print("Status Code : ", response.statusCode)
                print("Response : ", String(data: response.data, encoding: .utf8) ?? "Failed to read response data")
                completion(.ErrorCallback(handleError(response: response)))
            }

        } catch {
            completion(.ErrorCallback(handleError(response: response)))
        }
        
    case let .failure(error):
        completion(.FailureCallback(error))
    }
}