Alvin
Alvin

Reputation: 539

Swift Generic Callback

I am currently learning on how to implement a generic function. I am trying to create a function that will return a callback with generic type

Here is my code

static func performPOST<T: DomainEntity>(action: Module, completion: @escaping (CallbackResponse, DomainObjectWrapper<T>?) -> Void) {

     //logic implementation at first

     switch action { 
          case .getMenuItem:
          self.alamofireManager.request(urlRequest, encoding: URLEncoding.default, headers: headers).responseObject { (response: DataResponse<DomainObjectWrapper<MenuItemDO>>) in
                var validateRequestResponse = RestHelper.validateRequestResponse(response: response)
                let responseObject = validateRequestResponse.responseObject

                if validateRequestResponse.isSuccess {}
                else {
                    if let errorMessage = responseObject?.error {
                        validateRequestResponse.message = errorMessage
                    }
                    else if let warningMessage = responseObject?.warning {
                        validateRequestResponse.message = warningMessage
                    }
                }
                callbackResponse = RestHelper.bindValidateRequestResponse(validateRequestResponse: validateRequestResponse)
                completion(callbackResponse, responseObject)
            }
          case .makeSales: break
          case .attendance: break
     }
}

I am getting this error from the Xcode. It won't let me compile.

completion(callbackResponse, responseObject) <<-- This Line

Cannot convert value of type 'DomainObjectWrapper<MenuItemDO>?' to expected argument type 'DomainObjectWrapper<_>?'

Here is my other classes

public class DomainObjectWrapper<T: Mappable>: Mappable {
     public var data = [T]()
}

public class DomainEntity: Mappable {
     public var id = UUID().uuidString
     public var isDeleted = false
}

public class MenuItemDO: DomainEntity {
     public var categoryId: String?
     public var categoryName: String?
}

Can anybody guide me on what I am missing?

Thanks

Upvotes: 0

Views: 1590

Answers (2)

Recently I made an ok solution for generic parameter functions. Here's an example for the command pattern. This way you could use this pattern receiving a callback with generic parameter.

protocol ParameterCommand {
    func execute(with parameter: Any)
}

protocol CallbackCommand: ParameterCommand {
    associatedtype CallBackParameterType
    func execute(with callback: @escaping (CallBackParameterType) -> Void)
}

extension CallbackCommand {
    func execute(with parameter: Any) {
        if let parameter = parameter as? (CallBackParameterType) -> Void {
            execute(with: parameter)
        }
    }
}

Upvotes: 0

Sweeper
Sweeper

Reputation: 270980

because there will be lots of API call that will return DomainObjectWrapper. So i guess creating a generic function will help me to avoid redundant code. Thanks

If that's the case, then you would use DataResponse<DomainObjectWrapper<T>> instead of DataResponse<DomainObjectWrapper<MenuItemDO>> in the closure parameter of the Alamofire call:

static func performPOST<T: DomainEntity>(action: Module, completion: @escaping (CallbackResponse, DomainObjectWrapper<T>?) -> Void) {

     //logic implementation at first

     switch action { 
          // this line
          self.alamofireManager.request(urlRequest, encoding: URLEncoding.default, headers: headers).responseObject { (response: DataResponse<DomainObjectWrapper<T>>) in // <----- this line
                var validateRequestResponse = RestHelper.validateRequestResponse(response: response)
                let responseObject = validateRequestResponse.responseObject

                if validateRequestResponse.isSuccess {}
                else {
                    if let errorMessage = responseObject?.error {
                        validateRequestResponse.message = errorMessage
                    }
                    else if let warningMessage = responseObject?.warning {
                        validateRequestResponse.message = warningMessage
                    }
                }
                callbackResponse = RestHelper.bindValidateRequestResponse(validateRequestResponse: validateRequestResponse)
                completion(callbackResponse, responseObject)
            }
     }
}

Upvotes: 1

Related Questions