Eric
Eric

Reputation: 16971

defining swift typealiases according to launch arguments

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

Answers (1)

Cristik
Cristik

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

Related Questions