Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop viewWillAppear from completing until a function has finished

I'm pretty new to IOS Application Development.

I'm trying to stop viewWillAppear from finishing until after my function has finished working. How do I do that?

Here's viewWillAppear:

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    checkFacts()

    if reset != 0 {
        print("removing all bird facts")
        birdFacts.removeAll()
    }
}

func checkFacts() {
    let date = getDate()
    var x: Bool = true
    var ind: Int = 0
    print("count is ", birdFacts.count)
    while ind < birdFacts.count {
        print("accessing each bird fact in checkFacts")
        let imageAsset: CKAsset = birdFacts[ind].valueForKey("birdPicture") as! CKAsset
        let image = UIImage(contentsOfFile: imageAsset.fileURL.path!)
        print(image)
        if image == nil {
            if (birdFacts[ind].valueForKey("sortingDate") != nil){
                print("replacing fact")
                print("accessing the sortingDate of current fact in checkFacts")
                let sdate = birdFacts[ind].valueForKey("sortingDate") as! NSNumber
                replaceFact(sdate, index: ind)
            }
            /*else {
                birdFacts.removeAll()
                print("removing all bird facts")
            }*/

        }
        ind = ind + 1
        print(ind)
    }
    self.saveFacts()
    let y = checkRepeatingFacts()
    if y {
        print("removing all facts")
        birdFacts.removeAll()
        //allprevFacts(date, olddate: 0)
    }
}

checkFacts references 2 others functions, but I'm not sure they're relevant here (but I will add them in if they are and I'm mistaken)

like image 885
Alex Avatar asked Feb 12 '26 11:02

Alex


1 Answers

Instead of trying to alter or halt the application's actual lifecycle, why don't you try using a closure?

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(true)

    checkFacts(){ Void in
        if self.reset != 0 {
            print("removing all bird facts")
            birdFacts.removeAll()
        }
    }
}

func checkFacts(block: (()->Void)? = nil) {
    let date = getDate()
    var x: Bool = true
    var ind: Int = 0
    print("count is ", birdFacts.count)
    while ind < birdFacts.count {
        print("accessing each bird fact in checkFacts")
        let imageAsset: CKAsset = birdFacts[ind].valueForKey("birdPicture") as! CKAsset
        let image = UIImage(contentsOfFile: imageAsset.fileURL.path!)
        print(image)
        if image == nil {
            if (birdFacts[ind].valueForKey("sortingDate") != nil){
                print("replacing fact")
                print("accessing the sortingDate of current fact in checkFacts")
                let sdate = birdFacts[ind].valueForKey("sortingDate") as! NSNumber
                replaceFact(sdate, index: ind)
            }
            /*else {
                birdFacts.removeAll()
                print("removing all bird facts")
            }*/

        }
        ind = ind + 1
        print(ind)
    }
    self.saveFacts()
    let y = checkRepeatingFacts()
    if y {
        print("removing all facts")
        birdFacts.removeAll()
        //allprevFacts(date, olddate: 0)
    }

    // CALL CODE IN CLOSURE LAST //
    if let block = block {
        block()
    }
}

According to Apple Documentation:

Closures are self-contained blocks of functionality that can be passed around and used in your code.

Closures can capture and store references to any constants and variables from the context in which they are defined.

So by defining checkFacts() as: func checkFacts(block: (()->Void)? = nil){...} we can optionally pass in a block of code to be executed within the checkFacts() function.

The syntax block: (()->Void)? = nil means that we can take in a block of code that will return void, but if nothing is passed in, block will simply be nil. This allows us to call the function with or without the use of a closure.

By using:

if let block = block {
    block()
}

we can safely call block(). If block comes back as nil, we pass over it and pretend like nothing happened. If block is not nil, we can execute the code contained within it, and go on our way.

One way we can pass our closure code into checkFacts() is by means of a trailing closure. A trailing closure looks like this:

checkFacts(){ Void in
    if self.reset != 0 {
        print("removing all bird facts")
        birdFacts.removeAll()
    }
}

Edit: Added syntax explanation.

like image 188
ZGski Avatar answered Feb 15 '26 00:02

ZGski



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!