How could I create a function with a completion handler in Swift?
Say you have a download function to download a file from network, and want to be notified when download task has finished.
typealias CompletionHandler = (success:Bool) -> Void
func downloadFileFromURL(url: NSURL,completionHandler: CompletionHandler) {
// download code.
let flag = true // true if download succeed,false otherwise
completionHandler(success: flag)
}
// How to use it.
downloadFileFromURL(NSURL(string: "url_str")!, { (success) -> Void in
// When download completes,control flow goes here.
if success {
// download success
} else {
// download fail
}
})
Hope it helps.
I had trouble understanding the answers so I'm assuming any other beginner like myself might have the same problem as me.
My solution does the same as the top answer but hopefully a little more clear and easy to understand for beginners or people just having trouble understanding in general.
To create a function with a completion handler
func yourFunctionName(finished: () -> Void) {
print("Doing something!")
finished()
}
to use the function
override func viewDidLoad() {
yourFunctionName {
//do something here after running your function
print("Tada!!!!")
}
}
Your output will be
Doing something
Tada!!!
Hope this helps!
Simple Example:
func method(arg: Bool, completion: (Bool) -> ()) {
print("First line of code executed")
// do stuff here to determine what you want to "send back".
// we are just sending the Boolean value that was sent in "back"
completion(arg)
}
How to use it:
method(arg: true, completion: { (success) -> Void in
print("Second line of code executed")
if success { // this will be equal to whatever value is set in this method call
print("true")
} else {
print("false")
}
})
Swift 5.0 + , Simple and Short
example:
Style 1
func methodName(completionBlock: () -> Void) {
print("block_Completion")
completionBlock()
}
Style 2
func methodName(completionBlock: () -> ()) {
print("block_Completion")
completionBlock()
}
Use:
override func viewDidLoad() {
super.viewDidLoad()
methodName {
print("Doing something after Block_Completion!!")
}
}
Output
block_Completion
Doing something after Block_Completion!!
We can use Closures for this purpose. Try the following
func loadHealthCareList(completionClosure: (indexes: NSMutableArray)-> ()) {
//some code here
completionClosure(indexes: list)
}
At some point we can call this function as given below.
healthIndexManager.loadHealthCareList { (indexes) -> () in
print(indexes)
}
Please refer the following link for more information regarding Closures.
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html