Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to loop over struct properties in Swift?

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?

like image 300
blackjacx Avatar asked Dec 04 '14 10:12

blackjacx


People also ask

Can structure be inherited in Swift?

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.


1 Answers

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 ;)

like image 58
hris.to Avatar answered Sep 18 '22 08:09

hris.to