Created
September 27, 2019 16:16
-
-
Save Winchariot/113e40e34c77a203d5252ed11e383f52 to your computer and use it in GitHub Desktop.
Generic interface to service that can return many different types
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//I am some 3P service. I can be asked for many different types of values. | |
class ValueMaker { | |
static func makeBool() -> Bool { return true } | |
static func makeInt() -> Int { return 3 } | |
} | |
//I am a 1P abstraction over that service. | |
// I want to save effort in the rest of my codebase by exposing 1 func for getting values, | |
// instead of needing a different func for each possible type our 3P service can vend. So I use a func with a generic return type. | |
func genericMaker<T: TypeEmittedByOur3PService>() -> T? { | |
//I switch on T.self because my behavior needs to vary with T | |
switch T.self { | |
case is Bool.Type: | |
return ValueMaker.makeBool() as? T | |
case is Int.Type: | |
return ValueMaker.makeInt() as? T | |
default: | |
return nil | |
} | |
} | |
//Then, because we constrained T in the func genericMaker definition, we can add protocol conformance to various types | |
// to tell Xcode what values we're allowed to ask our 1P abstraction for. | |
protocol TypeEmittedByOur3PService { } | |
extension Bool: TypeEmittedByOur3PService { } | |
extension Int: TypeEmittedByOur3PService { } | |
//genericMaker knows which T to use merely by the explicit type declared on these initializations | |
let goodBool: Bool? = genericMaker() | |
let goodInt: Int? = genericMaker() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment