Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does () mean in Swift?

Tags:

swift

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([])
      }
    }
  }
  1. What does _ completionHandler argument in fetchOrders mean?
  2. What does (orders: () throws -> [Order]) mean?

PS : I am new to iOS and Swift

like image 823
Jaseem Abbas Avatar asked Oct 05 '16 12:10

Jaseem Abbas


People also ask

What is a swift code?

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.

What is swift and how does it work?

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?

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?

What is the difference between Iban and Swift?

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.


Video Answer


3 Answers

There's quite a lot in here, so we'll break it down one piece at a time:

func fetchOrders(_ completionHandler: (_ orders: [Order]) -> Void)
  • This is a function called fetchOrders.
  • It has one parameter (completionHandler) and returns nothing.
  • The first _ 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.)
  • The completionHandler is the "internal name," what the parameter is called inside the function.
  • The type of completionHandler is (_ orders: [Order]) -> Void. We'll break that down now.
    • This value is a closure that takes an [Order] (array of Order) and returns Void. Informally this means "returns nothing" but literally means it returns the empty tuple ().
    • The _ 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.
    • I believe this is a poor use of the closure parameter commenting system. Since 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
  • This calls the 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.
  • The author has provided type information here that probably wasn't necessary, but we can explore it anyway. This could likely have been written as just { orders in, but then the reader would probably have been surprised by this somewhat unusual code.
    • We have been passed a closure called orders that takes nothing and returns [Order] or throws an error. Basically this is a way to say that fetchOrders might fail.
    • The author is working around an awkwardness in Swift's 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([])
  }
  • This is where the 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.
    • In this particular case, the 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.
  • In either case, we call the 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.)

like image 101
Rob Napier Avatar answered Oct 10 '22 17:10

Rob Napier


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.

like image 39
Thorsten Dittmar Avatar answered Oct 10 '22 18:10

Thorsten Dittmar


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:

  1. it's the variable name, of type:
  2. function which receives an array of Order as a parameter and acts as a callback.
like image 26
Christopher Francisco Avatar answered Oct 10 '22 17:10

Christopher Francisco