I am trying to analyze type information in Swift 2.0 - and store it in a static structure - but am stuck. The most promising approach is to create a mirror for an instance - which would be done once on demand, assuming a default init - and to look at the subjectType of the mirror elements.
My questions are:
- How to unwrap optional types ( e.g.
Optional<String>
). I would like to have theString
part as a type. - How to determine generic array types, e.g.
Array<Foo>
.
Parsing the string is silly and it's probably not possible..
Other questions related to arrays: If a have the element type, how do i create a new instance?
To make it clearer. I need the type information for higher level algorithms such as mappers - object mappers, json mappers, widget mappers, etc. - that require information on the type of involved objects trying to be type safe or by inserting appropriate conversions, if needed.
Think of a property Int
that needs to be mapped to a Int?
property which should not raise an exception.
The code so far fills a BeanDescriptor
class that contains an array of PropertyDescriptor
's that should store all required information
Something like:
class PropertyDescriptor {
// instance data
var bean: BeanDescriptor;
var name: String;
var type: Any.Type;
var optional = false
// more data for arrays, e.g. elementType...
...
}
Code so far to analyze a class is:
// create a default instance
let instance = create(); // we need a NSObject though! darn...
let mirror = Mirror(reflecting: instance)
if let displayStyle = mirror.displayStyle {
if displayStyle == .Class {
for case let (label?, value) in mirror.children {
let property = analyzeProperty(label, value: value)
properties[property.name] = property;
} // for
}
}
and the called function
func analyzeProperty(name : String, value: Any) -> PropertyDescriptor {
let mirror : Mirror = Mirror(reflecting: value)
var type = mirror.subjectType
var optional = false
// no way..this sucks!
if (type == String?.self) {
type = String.self // uhhhh
optional = true
}
else if ... // lots other literal types, ...
return PropertyDescriptor(bean: self, name: name, type: type, optional: optional)
}
But this will not cover other optional classes Money?
as well as other information with respect to arrays, e.g. Array<Money>
, or Array<Money?>
where i would detect an array type and would have to determine the element type