David
David

Reputation: 2440

Optional argument identifiers in Swift

I'm learning iOS and Swift development and have a question about function argument identifiers. This is the signature for UIButton.setText as it appears when Xcode suggests the type-ahead:

// Xcode type-ahead signature:
sender.setTitle(title: String?, forState: UIControlState)

And when I copy and paste that it inserts some more information, like this:

// Actual signature from documentation:
sender.setTitle(<#title: String?#>, forState: <#UIControlState#>)

My usage is like this:

sender.setTitle("Hello World", forState: UIControlState.Normal)

As you can see, the forState argument identifier is required, but the title identifer is not. How can I determine this from Xcode's type-ahead method signature suggestion? Does the ? in title: String? denote the identifier as optional? If not, what does that do?

Upvotes: 0

Views: 2677

Answers (2)

rob mayoff
rob mayoff

Reputation: 385500

… the forState argument identifier is required, but the title identifer is not. How can I determine this from Xcode's type-ahead method signature suggestion?

Here's what the template looks like on-screen:

setTitle template

Notice that the first placeholder contains title: String?, while the second placeholder only contains UIControlState (and does not contain forTitle:). This is how you know that the first argument doesn't require a keyword, but the second argument does. This also makes your tab key automatically select the right amount of text to replace. (You can also use Navigate > Jump to Next Placeholder control/, if tab doesn't work.)

Your pasted copy looks like this:

sender.setTitle(<#title: String?#>, forState: <#UIControlState#>)

The <# ... #> is how Xcode represents a placeholder. Notice again that the first argument, including keyword, is inside <# ... #>, but the second placeholder excludes the keyword forState: and only includes the type UIControlState.

You can use this syntax to create placeholders in your own custom snippets. You just type <# and #> into the snippet. As soon as you finish typing #>, Xcode will convert the annotated text to a placeholder. Demonstration:

snippet demonstration

The ? after String indicates an optional string. It's syntactic sugar for Optional<String>. You can learn more about Optional by reading the section titled “Optionals” in The Swift Programming Language.

Upvotes: 3

rickster
rickster

Reputation: 126107

There are a couple of ways to tell:

  1. Swift's rule for parameter labels in methods is that the first parameter label is omitted when calling and te rest are required. This mimics convention from Objective-C where the method name and first parameter label run together — setTitle already references a title, so it'd sound funny if it read setTitle(title:.... Like in ObjC, Swift method calls should read like sentences.

  2. When you select the method in autocomplete, Xcode leaves placeholders for the text you're supposed to replace with your own code. Those show up as blue ovals in Xcode, but they're actually just text delimited by <# #> as you can see from when you pasted it into your question.

    The parts of the autocomplete text that are placeholders are things you need to fill in to complete the method call; the parts not in placeholders are the required syntax for calling that method. In your example, title: is inside the placeholder for the first parameter, so you don't write it when calling the method, and forState: is not in a placeholder, so you do write it when calling the method.

Upvotes: 1

Related Questions