Reputation: 16971
I'd like to (statically) define a global Swift typealias
according to launch arguments.
Swift lets me do that with with constants:
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
How can I achieve the same thing with typealiases? I'd like to do something like:
struct FakeAPIClient {
}
struct ProductionAPIClient {
}
private var isUITesting: Bool {
return NSProcessInfo.processInfo().arguments.contains("UI-TESTING")
}
typealias Client = isUITesting ? FakeAPIClient : ProductionAPIClient
But this doesn't compile. Is there a way to achieve this?
Upvotes: 0
Views: 459
Reputation: 32928
You cannot do this. The type alias is computed at compile time, when your project is built, while what you're trying to do happens at run time. At run time all type aliases are set in place.
For your use-case of UI testing, a better solution would be to make use of protocols, and instantiate the object you need based on the launch argument:
protocol ClientProtocol {
}
struct FakeAPIClient: ClientProtocol {
}
struct ProductionAPIClient: ClientProtocol {
}
func createClient() -> ClientProtocol {
return isUITesting ? FakeAPIClient() : ProductionAPIClient()
}
Instead of using the type alias you'd use the protocol wherever you need in your application.
Note. createClient
is a so called factory function, and can be used in multiple scenarios, not only this one of UI testing. For example you could have an API client based on AFNetworking
and one based on NSURLSession
and easily switch between the two with a simple flag change.
Upvotes: 3