![](/img/trans.png)
[英]How to pass protocol with associated type (generic protocol) as parameter in Swift?
[英]Trying to pass Generic type as parameter in Swift
我正在使用AlamofireObjectMapper我需要创建一个带有这样的Generic参数的函数:
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)
}
}
})
}
但我得到错误:
使用未声明的类型'myCustomClass' 编辑,因为你们在评论中回答我我修复了错误但是当我试图调用这个方法时我得到了另一个错误
我这样称呼方法
doSomething(myCustomClass: Promotions)
但我有另一个错误
参数类型'Promotions.Type'不符合预期类型'BaseMappable'
这是我的促销课程
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"]
}
}
我该如何解决这个问题
只需将Promotions.self作为参数传递即可。
doSomething(myCustomClass: Promotions.self)
这将克服您在函数调用中遇到的错误。
您需要将Generic Type T的类型作为参数传递。尝试更改
myCustomClass : T
通过
myCustomClass : T.Type
结果如下:
斯威夫特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)
}
}
})
}
然后,您应该调用该方法:
doSomething(myCustomClass: Promotions.self)
myCustomClass只是doSomething
的输入参数的名称。 泛型类型的名称是T
,因此DataResponse应该是DataResponse<T>
。
这是使用Alamofire
, ObjectMapper
和PromiseKit
的解决方案,
用户可Mappable
对象。
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"] } }
基于类模板的功能
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)) } } } }
用法
在实用程序类中定义
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)
}
在视图控制器中使用
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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.