Skip to content

Instantly share code, notes, and snippets.

@Winchariot
Created September 27, 2019 16:16
Show Gist options
  • Save Winchariot/113e40e34c77a203d5252ed11e383f52 to your computer and use it in GitHub Desktop.
Save Winchariot/113e40e34c77a203d5252ed11e383f52 to your computer and use it in GitHub Desktop.
Generic interface to service that can return many different types
//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