I have the following function in Swift 3
func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
{
ordersStore.fetchOrders { (orders: () throws -> [Order]) -> Void in
do {
let orders = try orders()
completionHandler(orders)
} catch {
completionHandler([])
}
}
}
_ completionHandler argument in fetchOrders mean?(orders: () throws -> [Order]) mean? PS : I am new to iOS and Swift
The SWIFT code is a Business Identification Code (BIC) assigned to banks by SWIFT as an easy cross-border payment solution. For any transaction this bank makes on an international level, the SWIFT code is used. The purpose of the code is to act as an international digital language to conveniently conduct payments overseas.
SWIFT is key to the way most traditional banks process international transfers, as they know they can rely on the standards and security used within the SWIFT payment and messaging network.
Is a SWIFT/ BIC code the same as a sort code? Nope, sort codes aren’t the same as SWIFT codes. Sort codes are 6-digit codes that help British and Irish banks to identify bank branches for domestic payments (payments within a country). Do all banks use BIC/ SWIFT codes?
The financial cousin to SWIFT is IBAN – the International Bank Account Number. This is another code often needed to send money overseas. While the SWIFT code stands as a kind of international bank ID, the IBAN represents the accounts within a bank.
There's quite a lot in here, so we'll break it down one piece at a time:
func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
fetchOrders.completionHandler) and returns nothing._ indicates that there is no "external name" of the first parameter. That is, you do not have to label it (in fact, you cannot). (For subtle reasons that don't really matter here, I believe the author made a mistake using _ there, and I would not have done that.)completionHandler is the "internal name," what the parameter is called inside the function.completionHandler is (_ orders: [Order]) -> Void. We'll break that down now.
[Order] (array of Order) and returns Void. Informally this means "returns nothing" but literally means it returns the empty tuple ()._ orders: syntax is in practice a comment. In principle the _ is an external name (but that's the only legal external name for a closure), and orders is an internal name, but in reality, closures parameters do not have names in any meaningful way, so this is purely informational.orders tells us nothing more than [Order], I would have omitted it, and made the type just ([Order]) -> Void.Now we'll turn to the next line:
ordersStore.fetchOrders { (orders: () throws -> [Order]) -> Void in
fetchOrders method on ordersStore. We can tell from this code that fetchOrders takes a closure parameter. This is called "trailing closure" syntax in Swift, and is why I would not have used the _ for our closure. With trailing closure syntax, the external name of the parameter is not needed.{ orders in, but then the reader would probably have been surprised by this somewhat unusual code.
orders that takes nothing and returns [Order] or throws an error. Basically this is a way to say that fetchOrders might fail.throws system, which does not have a natural way to express an asynchronous action that might fail. This is one way to fix it; you pass a throwing (i.e. a possibly failing) function. I don't favor this approach, I favor using a Result enum for this case because I think it scales better and avoids possible unintended side effects, but that's a debatable point (and the Swift community hasn't really decided how to deal with this common problem).This all leads us to:
do {
let orders = try orders()
completionHandler(orders)
} catch {
completionHandler([])
}
orders closure is evaluated. (This is very important; if orders has side effects, this is when they occur, which may be on a different queue than was intended. That's one reason I don't favor this pattern.) If the closure succeeds, we return its result, otherwise we return [] in the catch below.
throws approach is slightly silly, because it's silently flattened into [] without even a log message. If we don't care about the errors, then failure should have just returned [] to start with and not messed with throws. But it's possible that other callers do check the errors.completionHandler closure with our result, chaining this back to our original caller.This do/catch block could have been more simply written as:
let completedOrders = try? orders() ?? []
completionHandler(completedOrders)
This makes it clearer that we're ignoring errors by turning it into an optional, and avoids code duplication of the call to completionHandler.
(I just add the extra let binding to make the code a little easier to read; it isn't needed.)
The completionHandler argument means that the expected parameter (named completionHandler) must be a function that takes a list of Order objects and does not return any value.
completionHandler is the a variable name. In this specific example, this variable is a callback. You know is a callback function because (orders: [Order]) -> Void is it's data type; in this particular case, said data type is a function that receives an array of Order objects in a variable _orders and doesn't have a return value (the Void part).
TL;DR:
Order as a parameter and acts as a callback.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With