skip to Main Content

I want to use variable names in dot notation in Swift.

I’m wrestling with trying to make sense of JSON in Swift, and having a really hard time doing things that are so easy in JS (like cycling through objects, etc).

I have variables of custom types:

var questionConfiguration: QuestionConfiguration
var priorityConfiguration: PriorityConfiguration

Each of these types has an attribute, displayOrder, I want to access this dynamically. I have tried various things, including the following (i is a variable of type Int):

var configs = [self.questionConfiguration, self.priorityConfiguration]
print([configs[i]].displayOrder)
var configs = ["questionConfiguration", "priorityConfiguration"]
print([configs[i]].displayOrder)

How can I achieve this?

EDIT:

struct QuestionConfiguration: Codable {
    var displayOrder: Int
}

struct PriorityConfiguration: Codable {
    var displayOrder: Int
}

2

Answers


  1. You can create a protocol for same property name then you can access it easily

    protocol SameProp {
        var displayOrder: Int {get set}
    }
    
    class QuestionConfiguration : SameProp {
         var displayOrder : Int = 4
    }
    
    class PriorityConfiguration : SameProp {
         var displayOrder : Int = 6
     }
    
    var questionConfiguration: QuestionConfiguration = QuestionConfiguration()
    var priorityConfiguration: PriorityConfiguration = PriorityConfiguration()
    
    var configs = [questionConfiguration, priorityConfiguration] as [SameProp]
    for elements in configs{
        print(elements.displayOrder) // will print 4 and 6
    }
    
    Login or Signup to reply.
  2. Swift is very particular about data types and I suspect you are experiencing challenges because of it.

    When you do this:

    var configs = [self.questionConfiguration, self.priorityConfiguration]

    In Swift, all the elements in an array have to have the same type. You’ve not given Swift any hints about what types this array should contain so the compiler has to infer a type. QuestionConfiguration and PriorityConfiguration are two different types. So the compiler is likely to infer that configs is of type [Any] also called Array<Any>.

    Then you try something like this:

    configs[i].displayOrder (not sure why your code has the extra brackets)

    But configs[i] is inferred to be of type Any and that type doesn’t have a displayOrder property so the compiler complains.

    You need to tell the compiler that these types share some properties. One way to do that would be to add a protocol that describes what they share:

    protocol DisplayOrderable {
      var displayOrder: Int { get }
    }
    
    
    struct QuestionConfiguration: DisplayOrderable, Codable {
        var displayOrder: Int
    }
    
    struct PriorityConfiguration: DisplayOrderable, Codable {
        var displayOrder: Int
    }
    

    then you could use

    var configs: [any DisplayOrderable] = [self.questionConfiguration, self.priorityConfiguration]
    

    And configs[i].displayOrder should work.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search