I wonder if it's possible to obtain a Swift type dynamically. For example, say we have the following nested structs:
struct Constants {
struct BlockA {
static let kFirstConstantA = "firstConstantA"
static let kSecondConstantA = "secondConstantA"
}
struct BlockB {
static let kFirstConstantB = "firstConstantB"
static let kSecondConstantB = "secondConstantB"
}
struct BlockC {
static let kFirstConstantC = "firstConstantBC"
static let kSecondConstantC = "secondConstantC"
}
}
It's possible to get value from kSeconConstantC from a variable). Like:
let variableString = "BlockC"
let constantValue = Constants.variableString.kSecondConstantC
Something akin to NSClassFromString
, maybe?
No, it's not possible yet (as a language feature, at least).
What you need is your own type registry. Even with a type registry, you wouldn't be able to get static
constants unless you had a protocol for that:
var typeRegistry: [String: Any.Type] = [:]
func indexType(type: Any.Type)
{
typeRegistry[String(type)] = type
}
protocol Foo
{
static var bar: String { get set }
}
struct X: Foo
{
static var bar: String = "x-bar"
}
struct Y: Foo
{
static var bar: String = "y-bar"
}
indexType(X)
indexType(Y)
typeRegistry // ["X": X.Type, "Y": Y.Type]
(typeRegistry["X"] as! Foo.Type).bar // "x-bar"
(typeRegistry["Y"] as! Foo.Type).bar // "y-bar"
A type registry is something that registers your types using a custom Hashable
type (say a String
or an Int
). You can then use this type registry to reference registered types using custom identifiers (a String
, in this case).
Since Any.Type
by itself isn't all that useful, I constructed an interface Foo
through which I could access a static constant bar
. Because I know that X.Type
and Y.Type
both conform to Foo.Type
, I forced a cast and read the bar
property.