Reputation: 586
I am Using AlamofireObjectMapper i need to make a func that take a Generic parameter like that :
func doSomething < T : BaseMappable > (myCustomClass : T)
{
Alamofire.request("url", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: APIKeys().AuthorizedHeader).responseObject(completionHandler: { ( response :DataResponse<T>) in
let data = response.result.value
if let array = data?.objects
{
for ar in array
{
self.allPromotions.append(ar)
}
}
})
}
but iam getting error :
Use of undeclared type 'myCustomClass' edit as you guys answer me in the comments i put fixed the error but i got another error when iam trying to call this method
i called the method like that
doSomething(myCustomClass: Promotions)
but i got another error
Argument type 'Promotions.Type' does not conform to expected type 'BaseMappable'
and here's my Promotions class
import ObjectMapper
class Promotions : Mappable {
var id:Int?
var workshop_id:Int?
var title:String?
var desc:String?
var start_date:String?
var expire_date:String?
var type:String?
var objects = [Promotions]()
required init?(map: Map){
}
func mapping(map: Map) {
id <- map["id"]
workshop_id <- map["workshop_id"]
title <- map["title"]
desc <- map["desc"]
start_date <- map["start_date"]
expire_date <- map["expire_date"]
type <- map["type"]
objects <- map["promotions"]
}
}
How can i fix that
Upvotes: 13
Views: 18514
Reputation: 169
You need to pass as argument the type of Generic Type T. Try changing
myCustomClass : T
by
myCustomClass : T.Type
The result would look like:
Swift 4:
func doSomething<T>(myCustomClass : T.Type) where T : BaseMappable
{
Alamofire.request("url", method: .get, parameters: nil, encoding: JSONEncoding.default, headers: APIKeys().AuthorizedHeader).responseObject(completionHandler: { ( response :DataResponse<T>) in
let data = response.result.value
if let array = data?.objects
{
for ar in array
{
self.allPromotions.append(ar)
}
}
})
}
Then, you should call the method:
doSomething(myCustomClass: Promotions.self)
Upvotes: 13
Reputation: 711
Here is the solution using Alamofire
, ObjectMapper
and PromiseKit
,
User Mappable
object.
class User: Mappable {
var id: Int!
var userName: String!
var firstName: String?
var lastName: String?
required init?(map: Map) {
}
// Mappable
func mapping(map: Map) {
id <- map["id"]
userName <- map["userName"]\
firstName <- map["firstName"]
lastName <- map["lastName"]
}
}
Class template based function
func sendRequest<T: Mappable>(_ url: URLConvertible, method: HTTPMethod = .get, parameters: Parameters? = nil, encoding: ParameterEncoding = URLEncoding.default, headers: HTTPHeaders? = nil, responseObject: T.Type) -> Promise<T> {
return Promise { resolve, reject in
Alamofire.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers)
.responseJSON() { response in
switch response.result {
case .success(let data):
let json = JSON(data as Any)
let dataObj = json["data"].object
let resObj = Mapper<T>().map(JSONObject: dataObj)
resolve(resObj!)
case .failure(_):
reject(self.generateError(message: nil))
}
}
}
}
Usage
Define in utility class
func loginWith(userName: String, and password: String) -> Promise<User> {
let apiPath = "localhost:3000"
let parameters: Parameters = [
"email": userName,
"password": password
]
return sendRequest(apiPath, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: nil, responseObject: User.self)
}
Use in view controllers
loginWith(userName: name, and: password)
.then { response -> Void in
// response is `User` type object!!!
}
.catch { error in
// show error message
}
.always {
// do something like hide activity indicator
}
Upvotes: 2
Reputation: 1066
Just pass the Promotions.self as the parameter.
doSomething(myCustomClass: Promotions.self)
This'll overcome the error that you are getting in the function call.
Upvotes: 6
Reputation: 54706
myCustomClass is just the name of the input parameter to doSomething
. The name of the generic type is T
, so DataResponse should be DataResponse<T>
.
Upvotes: 1