I am using AlamoFire for my API calls, and have something like this all over my project:
static func login(userName: String, password: String) -> User {
let parameters = ["userName": userName , "password": password]
let user = User()
Alamofire.request(.POST, "myserver.com/login", parameters: parameters, encoding: .JSON)
.validate()
.responseObject { (response: Response<User, NSError>) in
switch response.result {
case .Success(let value):
user.valueHandle?(value)
case .Failure(let error):
user.errorHandle?(error)
}
}
return user
}
(see https://stackoverflow.com/a/37949671/406322 on how I came up with the above code).
The problem is that I have a lot of objects other than User and there is code repetition with only the type of the object different, so I'm trying to create a generic method, something like this:
static func sendRequest<T>(method: Alamofire.Method, urlString: String, parameters: [String: AnyObject]?) -> T {
let response : T
Alamofire.request(method, urlString, parameters:parameters)
.validate()
.responseObject { (response: Response<T, NSError>) in
switch response.result {
case .Success(let value):
response.valueHandle?(value)
case .Failure(let error):
response.errorHandle?(error)
}
}
return response
}
But Swift is complaining:
Cannot convert value of type '(Response<T, NSError>) -> ()' to expected argument type 'Response<_, NSError> -> Void'
This is so I can do something like this:
User.swift
static func login(userName: String, password: String) -> User {
let parameters = ["userName": userName, "password": password]
return sendRequest<User>(.GET, "http://myserver.com/users", parameters)
}
and in my calling code:
User.login(txtUserName.text!, password: txtPassword.text!)
.success { (value) in
var user = value as! User
//do something with user
}
.error { (error) in
//show error
}
What am I not doing right?
you can use a BaseObject to do this easy :
class BaseUser: ResponseObjectSerializable {
var valueHandle : ((BaseUser)->())?
var errorHandle : ((NSError)->())?
required init?(response: NSHTTPURLResponse, representation: AnyObject) {
}
}
func sendRequest<T:BaseUser>(method: Alamofire.Method, urlString: String, parameters: [String: AnyObject]?) -> T {
let res : T
Alamofire.request(method, urlString, parameters:parameters)
.validate()
.responseObject { (response: Response<T, NSError>) in
switch response.result {
case .Success(let value):
res.valueHandle?(value)
case .Failure(let error):
res.errorHandle?(error)
}
}
return res
}
class
can hold the handle ,and with the baseobj you don't need to write them again and again by using protocol