我是Swift的新手,当了很多年的目标C开发人员。我很难理解类型铸造是如何与仿制药一起工作的。
我有两个功能,就是用Alamofire +可编码和Alamofire + ObjectMapper进行对象映射。就像这样:
public func performRestOperationWithDecodable<ResponseClass: Decodable>(
_ restOperationType: NetworkServiceRestOperationType,
pathUrl: URLConvertible,
parameters: Parameters,
encoding: ParameterEncoding,
savedAuthType: NetworkServiceAuthType,
activityIndicator: ActivityIndicatorProtocol?,
successBlock: @escaping (_ responseObject: DataResponse<ResponseClass>) -> Void,
errorBlock:@escaping (_ error: Error, _ validResponse: Bool) -> Void) {
let restConfiguration = self.setupRestOperation(
savedAuthType: savedAuthType,
pathUrl: pathUrl,
activityIndicator: activityIndicator)
Alamofire
.request(
restConfiguration.url,
method: .get,
parameters: parameters,
encoding: encoding,
headers: restConfiguration.headers)
.validate(
contentType: Constants.Network.DefaultValidContentTypeArray)
.responseDecodableObject(
queue: self.dispatchQueue,
keyPath: nil,
decoder: JSONDecoder(),
completionHandler: { (responseObject: DataResponse<ResponseClass>) in
self.completionRestOperation(
responseObject: responseObject,
activityIndicator: activityIndicator,
successBlock: successBlock,
errorBlock: errorBlock)
})
}public func performRestOperationWithObjectMapper<ResponseClass: BaseMappable>(
_ restOperationType: NetworkServiceRestOperationType,
pathUrl: URLConvertible,
parameters: Parameters,
encoding: ParameterEncoding,
savedAuthType: NetworkServiceAuthType,
activityIndicator: ActivityIndicatorProtocol?,
successBlock: @escaping (_ responseObject: DataResponse<ResponseClass>) -> Void,
errorBlock: @escaping (_ error: Error, _ validResponse: Bool) -> Void) {
let restConfiguration = self.setupRestOperation(
savedAuthType: savedAuthType,
pathUrl: pathUrl,
activityIndicator: activityIndicator)
Alamofire
.request(
restConfiguration.url,
method: .get,
parameters: parameters,
encoding: encoding,
headers: restConfiguration.headers)
.validate(
contentType: Constants.Network.DefaultValidContentTypeArray)
.responseObject(
queue: self.dispatchQueue,
keyPath: nil,
mapToObject: nil,
context: nil,
completionHandler: { (responseObject: DataResponse<ResponseClass>) in
self.completionRestOperation(
responseObject: responseObject,
activityIndicator: activityIndicator,
successBlock: successBlock,
errorBlock: errorBlock)
})
}每个函数都有一个符合所使用映射器所需的适当协议的泛型类型(可解码用于可编码,可映射用于ObjectMapper)。这些有趣的事情就像预期的一样。现在,我正在尝试编写第三个函数,它具有第三个泛型类型,但不符合任何协议,并根据配置参数强制转换到适当的泛型。就像这样:
public func performRestOperation<ResponseMappedClass :AnyObject>(
_ restOperationType: NetworkServiceRestOperationType,
pathUrl: URLConvertible,
parameters: Parameters = [:],
encoding: ParameterEncoding = URLEncoding.queryString,
savedAuthType: NetworkServiceAuthType,
activityIndicator: ActivityIndicatorProtocol?,
successBlock: @escaping (_ responseObject: ResponseMappedClass) -> Void,
errorBlock: @escaping (_ error: Error, _ validResponse: Bool) -> Void) {
if self.canDoRestOperation(errorBlock: errorBlock) != true {
return
}
switch self.mappingType {
case .Codable:
self.performRestOperationWithDecodable(
restOperationType,
pathUrl: pathUrl,
parameters: parameters,
encoding: encoding,
savedAuthType: savedAuthType,
activityIndicator: activityIndicator,
successBlock: { (responseObject: DataResponse<ResponseMappedClass>) in
let response: ResponseMappedClass = responseObject.result.value!
successBlock(response)
} as! (DataResponse<ResponseMappedClass & Decodable>) -> Void,
errorBlock: { (error: Error, validResponse: Bool) in
errorBlock(error, validResponse)
})
case .ObjectMapper:
// TODO
break
}
}使用说明:as! (DataResponse<ResponseMappedClass & Decodable>) -> Void,我尝试将“泛型”类类型ResponseMappedClass转换为同一个类,但使用Codable支持。但这条指令并没有编译:
非协议、非类类型“ResponseMappedClass”不能在协议约束类型中使用。
在所有这些过程之后,各种泛型将表示相同的类,例如SomeModelObject,将来实现Codable、Mappable或其他东西,所以编译时通常的类型替换仍然必须工作。
有什么建议吗?在斯威夫特完全不可能做到吗?
发布于 2018-01-31 18:09:38
我认为不可能将泛型类型与协议结合使用。编译器不将它们视为类或协议类型。还有一点是代码有问题,您正在使用self.mappingType来判断它是Decodable类型还是Mapable类型。如果是self.mappingType == .Codable,但ResponseMappedClass没有确认Decodable协议呢?我能告诉你的是功能超载。创建3个功能:
public func performRestOperation<ResponseMappedClass: AnyObject>(...) where ResponseMappedClass: Decodable {
}
public func performRestOperation<ResponseMappedClass: AnyObject>(...) where ResponseMappedClass: BaseMappable {
}
public func performRestOperation<ResponseMappedClass: AnyObject>(...) {
}在最后一个只是抛出一个错误。根据泛型参数类型,将调用正确的funcion。
发布于 2018-02-08 12:15:25
(DataResponse<ResponseMappedClass & Decodable>) 我认为您做错的是ResponseMappedClass是一个类,而Decodable是一个协议。而且不能将类和协议类型组合在一起。
所以,这个错误和它说的完全一样。
非协议、非类类型“ResponseMappedClass”不能在协议约束类型中使用。
像这样的东西会工作,因为这两种类型都是协议。
as! (DataResponse<Codable & Decodable>) -> Voidhttps://stackoverflow.com/questions/48546636
复制相似问题