我想(静态地)根据启动参数定义一个全局Swift typealias
。
Swift让我用常量做到这一点:
protocol Client {
}
struct FakeAPIClient: Client {
}
struct ProductionAPIClient: Client {
}
private var isUITesting: Bool {
return NSProcessInfo.processInfo().arguments.contains("UI-TESTING")
}
let APIClient: Client.Type = isUITesting ? FakeAPIClient.self : ProductionAPIClient.self
我怎么能用typealiases做同样的事情?我想做点什么:
struct FakeAPIClient {
}
struct ProductionAPIClient {
}
private var isUITesting: Bool {
return NSProcessInfo.processInfo().arguments.contains("UI-TESTING")
}
typealias Client = isUITesting ? FakeAPIClient : ProductionAPIClient
但是这不能编译。有没有办法实现这个目标?
答案 0 :(得分:4)
你不能这样做。类型别名在编译时计算,当您的项目构建时,您尝试执行的操作在运行时进行。在运行时,所有类型别名都已设置到位。
对于UI测试的用例,更好的解决方案是使用协议,并根据启动参数实例化您需要的对象:
protocol ClientProtocol {
}
struct FakeAPIClient: ClientProtocol {
}
struct ProductionAPIClient: ClientProtocol {
}
func createClient() -> ClientProtocol {
return isUITesting ? FakeAPIClient() : ProductionAPIClient()
}
您可以在应用程序中的任何位置使用协议,而不是使用类型别名。
注意。 createClient
是一个所谓的工厂函数,可以在多个场景中使用,而不仅仅是这个UI测试。例如,您可以拥有一个基于AFNetworking
的API客户端和一个基于NSURLSession
的API客户端,并可以通过简单的标志更改在两者之间轻松切换。