Is it possible to iterate over properties of a struct in Swift?
I need to register cells-reuse identifiers in a view controller that makes use of many different cell types (cells are organized in different nib files). So my idea was to put all reuse identifiers and the corresponding nib-files as static tuple-properties (reuseID, nibName) in a struct. But how can I iterate over all of them to register the cells with the tableView?
I already tried something (see my answer below). But is there a more easy way to do this, e.g. without putting every property inside an array?
A struct cannot inherit from another kind of struct, whereas classes can build on other classes. You can change the type of an object at runtime using typecasting. Structs cannot have inheritance, so have only one type.
Although old question, with Swift evolving this question has new answer. I think that you approach is way better for the described situation, however original question was how to iterate over struct properties, so here is my answer(works both for classes and structs)
You can use Mirror Structure Reference. The point is that after calling reflect
to some object you get it's "mirror" which is pretty sparingly however still useful reflection.
So we could easily declare following protocol, where key
is the name of the property and value
is the actual value:
protocol PropertyLoopable { func allProperties() throws -> [String: Any] }
Of course we should make use of new protocol extensions to provide default implementation for this protocol:
extension PropertyLoopable { func allProperties() throws -> [String: Any] { var result: [String: Any] = [:] let mirror = Mirror(reflecting: self) guard let style = mirror.displayStyle where style == .Struct || style == .Class else { //throw some error throw NSError(domain: "hris.to", code: 777, userInfo: nil) } for (labelMaybe, valueMaybe) in mirror.children { guard let label = labelMaybe else { continue } result[label] = valueMaybe } return result } }
So now we can loop over the properties of any class
or struct
with this method. We just have to mark the class as PropertyLoopable
.
In order to keep things static(as in the example) I will add also a singleton:
struct ReuseID: PropertyLoopable { static let instance: ReuseID = ReuseID() }
Whether singleton used or not, we could finally loop over the properties like follows:
do { print(try ReuseID.instance.allProperties()) } catch _ { }
And that's it with looping struct properties. Enjoy swift ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With