Lance Samaria Lance Samaria - 23 days ago 6
Swift Question

Swift Closure Expression

I have to download some names into an array but I don't know exactly how many names will get downloaded. Only after all the names are downloaded I need a custom function to run.

I used a closure to call the custom function but what happens is once the first name is downloaded, my custom function is getting called immediately, then the second name is downloaded, then the custom function is called again etc.

I need the custom function to get called only after all the names are downloaded into the array, not after each name is downloaded. Where am I doing something wrong at?

This is what I'm getting:

Mable
This should only print once not three times
Marlene
This should only print once not three times
Moses
This should only print once not three times


This is what I want:

Mable
Marlene
Moses
This should only print once not three times


If possible, i would like the issue to be resolved inside: addAllNamesToArrayThenRunClosure

Code:

//There actually can be 1 or 100 names but I just used 3 for the example
var randomNames = ["Mable", "Marlene", "Moses"]
var nameArray = [String]()

func addAllNamesToArrayThenRunClosure(name: String, completionHandler: (success:Bool)->()){
nameArray.append(name)
print(name)

let flag = true
completionHandler(success:flag)
}

func customFunction(){
print("This should only print once not three times")
}

for name in randomNames{
addAllNamesToArrayThenRunClosure(name){

//Shouldn't this run only after the array is filled?
(success) in
if success == true{
customFunction()
}
}
}

Answer

addAllNamesToArrayThenRunClosure actually only adds a single name, and you call it once per name. If you call your completion handler in there, it'll be called ... once per name. You need to redesign this so the closure is called after all the names are added.

Here's how I would do it:

//There actually can be 1 or 100 names but I just used 3 for the example
var randomNames = ["Mable", "Marlene", "Moses"]
var globalNames = [String]()

func add(names: [String], completionHandler: ( _ success: Bool) -> Void) {
    globalNames.append(contentsOf: names)

    completionHandler(true)
}

add(names: randomNames) { success in
    if success {
        print("Finished")
    }
}