我正在开发一个库Restofire,其中我想保留一个配置对象。我想在配置对象中有一个ResponseSerializer,但事情是ResponseSerializer是通用的。
public struct Configuration<M> {
/// The Default `Configuration`.
static let defaultConfiguration = Configuration<AnyObject>()
/// The base URL. `nil` by default.
public var baseURL: String!
/// The `ResponseSerializer`
public var responseSerializer: ResponseSerializer<M, NSError> = AlamofireUtils.JSONResponseSerializer()
/// The logging, if enabled prints the debug textual representation of the
/// request when the response is recieved. `false` by default.
public var logging: Bool = false
}
我使用baseUrl Configuration.defaultConfiguration.baseUrl = "http://httpbin.org/"
我有一个带有associatedType要求的协议,它使用defaultConfiguration作为默认实现。但是我需要将通用AnyObject更改为associatedType Model,以便配置对象的responseSerializer返回Model类型。
public protocol Configurable {
associatedtype Model
/// The Restofire configuration.
var configuration: Configuration<Model> { get }
}
public extension Configurable {
/// `Restofire.defaultConfiguration`
// Cannot convert return expression of Configuration<AnyObject> to return type Configuration <Self.Model>
public var configuration: Configuration<Model> {
return Restofire.defaultConfiguration
}
}
我收到错误Cannot convert return expression of Configuration<AnyObject> to return type Configuration <Self.Model>
如何使用Model而不是AnyObject进行转发?
我还有一个继承自Configurable
的协议Requestablepublic protocol Requestable: Configurable {
/// The type of object returned in response.
associatedtype Model
/// The base URL.
var baseURL: String { get }
/// The path relative to base URL.
var path: String { get }
/// The request parameters.
var parameters: AnyObject? { get }
/// The logging.
var logging: Bool { get }
/// The Response Serializer
var responseSerializer: ResponseSerializer<Model, NSError> { get }
}
// MARK: - Default Implementation
public extension Requestable {
/// `configuration.BaseURL`
public var baseURL: String {
return configuration.baseURL
}
/// `nil`
public var parameters: AnyObject? {
return nil
}
/// `configuration.logging`
public var logging: Bool {
return configuration.logging
}
/// `configuration.responseSerializer`
var responseSerializer: ResponseSerializer<Model, NSError> {
return configuration.responseSerializer
}
}
https://github.com/Restofire/Restofire/compare/Add/DefaultResponseSerializer
的RealCode我可以直接在下面做,但用户将无法使用配置对象进行设置。
// MARK: - Default Implementation
public extension Requestable {
/// `configuration.responseSerializer`
var responseSerializer: ResponseSerializer<Model, NSError> {
return AlamofireUtils.JSONResponseSerializer()
}
}
还有其他办法吗?
答案 0 :(得分:1)
你想做的事是不可能的。这是因为Swift中强大的类型安全系统。
您希望将configuration
限制为关联类型Model
,但您还希望提供默认配置。这里的问题是您的默认配置无法保证其泛型类型与Model
的类型相同。
Swift类型系统不允许您将<AnyObject>
作为<Model>
类型传递,因为它无法确保该对象实际上属于Model
类型。< / p>
当你做出符合Configurable
的内容并声明Model
的类型时,你会说,&#34;我的配置必须使用我给出的类型。&#34 ; defaultConfiguration
无法保证,因此无法以这种方式使用。
通过查看代码,您可以使用它来确定要使用的responseSerializer
的类型。但是,如果您使用不同的Configurable
个对象,它们都需要不同的responseSerializer
,因此它们都不能使用默认配置。
我花了很多时间思考这个问题,而且我没有看到任何解决方法。你将不得不以某种方式改变你的设计。
如果您将responseSerializer
移至Configurable
协议,则可以使Configuration
非通用。在这种情况下,您可以在responseSerializer
上的协议扩展中创建Configurable
。如果您需要使用responseSerializer
配置独立于Configurable
对象,那么无论您在何处使用它,都必须创建responseSerializer<AnyObject, NSError>
。我不熟悉您图书馆的整个设计和意图,所以我不确定这是否适用于您想要实现的目标。
我可以确定地告诉你的一件事是你的设计必须改变才能使用defaultConfiguration
。