iosswiftproperty-observer

How to call a method once two variables have been set


I am using iOS Swift, and I am trying to understand how to execute a method once the value of two variables have been set up (non-null value) once the requests have finished.

After reading some documentation, I have found out some concepts which are interesting. The first one would be didSet, which works as an observer.

I could call the method using this method by simply using didSet if I would require just one variable

didSet

var myVar: String  0 {
    didSet {
        print("Hello World.")

    }
}

Nevertheless, I also need to wait for the second one myVar2, so it would not work.

I have also found DispatchQueue, which I could use to wait a second before calling the method (the requests that I am using are pretty fast)

DispatchQueue

 DispatchQueue.main.asyncAfter(deadline: .now() + 2, execute:  {
            print("Hello world")
        })

but I consider that this solution is not efficient.

Is there anyway to combine these two variables or requests in order to call a method once they have finishing setting the value?

Update I have tried to replicate David s answer, which I believe is correct but I get the following error on each \.

Type of expression is ambiguous without more context

I copy here my current code

var propertiesSet: [KeyPath<SearchViewController, Car>:Bool] = [\SearchViewController.firstCar:false, \SearchViewController.secondCar:false] {
    didSet {
        if propertiesSet.allSatisfy({ $0.value }) {
            // Conditions passed, execute your custom logic
            print("All Set")
        } else {
            print("Not yet")
        }
    }
}

 var firstCar: Car? {
     didSet {
        propertiesSet[\SearchViewController.firstCar] = true
     }
 }

 var secondCar: Car?  {
     didSet {
        propertiesSet[\SearchViewController.secondCar] = true
     }
 }

The variables are set individually, each one on its own request.


Solution

  • You could make your properties optional and check they both have values set before calling your function.

    var varA: String? = nil {
        didSet {
            if varA != nil && varB != nil {
                myFunc()
            }
        }
    }
    
    var varB: String? = nil {
        didSet {
            if varA != nil && varB != nil {
                myFunc()
            }
        }
    }
    

    Or you can call your function on each didSet and use a guard condition at the start of your function to check that both of your properties have values, or bail out:

    var varA: String? = nil {
        didSet {
            myFunc()
        }
    }
    
    var varB: String? = nil {
        didSet {
            myFunc()
        }
    }
    
    func myFunc() {
        guard varA != nil && varB != nil else { return }
        // your code
    }