Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Equivalent to a JS array of objects in Swift. My current implementation throws an error 'property initializers run before self'. Is this possible?

I want my users to loop through an interface where they see a picture and can press a button to generate a sound that belongs to the picture.

To do that, I am trying to build a data structure in Swift that holds two key-value pairs so that I can call the value of each property at the current index of wherever my user happens to be.

One of the properties is an image with a UIImage value and the other is a sound with a string value. After trying several things, the best I could come up with is the below implementation but that throws the following error at each of the variables in my animals variable. Error: Cannot use instance member 'bird' within property initializer; property initializers run before 'self' is available.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

When I declare the animals variable with local scope, i.e. inside a function, it works fine. But I need that variable to have global scope. I’ve been searching quite a bit and have to admit I don’t completely understand the error that’s been thrown.

Can anyone point out what I am doing wrong?

Code in XCode:

class element {
    let image : UIImage
    let sound : String
    init (image : UIImage, sound : String) {
            self.image = image
            self.sound = sound
        }
}

let monkey = element(image : UIImage(named: "Baviaan")!, sound : "monkey")
let donkey = element(image : UIImage(named: "Donkey")!, sound : "donkey")
let horse = element(image : UIImage(named: "Horse")!, sound : "horse")
let lion = element(image : UIImage(named: "Leeuw")!, sound : "lion")
let elephant = element(image : UIImage(named: "Olifant")!, sound : "elephant")
let sheep = element(image : UIImage(named: "Sheep")!, sound : "sheep")
let dog = element(image : UIImage(named: "Tekkel")!, sound : "dog")
let chicken = element(image : UIImage(named: "toktok")!, sound : "chicken")
let bird = element(image : UIImage(named: "birds")!, sound : "bird")

var animals = [bird,chicken,dog,donkey,elephant,horse,lion,monkey,sheep]

Pic of error:

screenshot of problem

>Solution :

This kind of a global variable is bad practice. Don’t do that. A better way is a static property

struct Element {
    let image : UIImage
    let sound : String

    static let animals = [
        Element(image: UIImage(named: "Baviaan")!, sound: "monkey"),
        Element(image: UIImage(named: "Donkey")!, sound: "donkey"),
        Element(image: UIImage(named: "Horse")!, sound: "horse"),
        Element(image: UIImage(named: "Leeuw")!, sound: "lion"),
        Element(image: UIImage(named: "Olifant")!, sound: "elephant"),
        Element(image: UIImage(named: "Sheep")!, sound: "sheep"),
        Element(image: UIImage(named: "Tekkel")!, sound: "dog"),
        Element(image: UIImage(named: "toktok")!, sound: "chicken"),
        Element(image: UIImage(named: "birds")!, sound: "bird")
   ]
}

or shorter

struct Element {
    let image : UIImage
    let sound : String
    
    static let animals = [
        ("Baviaan", "monkey"), ("Donkey", "donkey"),
        ("Horse", "horse"), ("Leeuw", "lion"),
        ("Olifant", "elephant"), ("Sheep", "sheep"),
        ("Tekkel", "dog"), ("toktok", "chicken"), ("birds", "bird")]
        .map{Element(image: UIImage(named: $0.0)!, sound: $0.1)}
}

You get the animals with

Element.animals
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading