Preventative Measures
Years ago, when a computer was as big as a car, instead of being small enough to fit in your pocket, you still had to write code for it. In those days, syntax errors or typos were very common bugs. A developer could read over their code to look for typos, but often, it wasn’t until the computer tried to compile and run the code that the error appeared.
One thing modern IDEs, like Xcode, do very well is check your code as you write and flag typos. An unexpected syntax error when compiling and running is rare. However, many other bugs aren’t as easy to catch until later. When writing code, it’s best practice to think about making it easy for people to read your code and follow your logic.
Descriptive Names & Autocomplete
If you’re coming from working in an interpreted language or haven’t written code in years, you might be in the habit of making identifier names as short as possible. You might be familiar with code like this:
var x = 0
p.bd = "03/15/01"
i = i + 1
This code trades readability for space. When writing web code, you must transfer everything from the server to the browser for execution. Writing the fewest characters to get the job done is important.
Languages like Swift and C are not like that. They’re compiled languages. That means the space you use for naming things has minimal impact on the size of the code running your app. The compiler will compact and optimize your code.
So, when you’re writing, be descriptive. Make the code easy to read. This is what people mean when they say to write self-documenting code.
var pointOnXAxis = 0
personDetail.dateOfBirth = "03/15/01"
loopIndex = loopIndex + 1
This code is identical to the code above and will take the same amount of space in the final compiled program. As you start working with Apple’s APIs, this is one reason that things have long, descriptive names. Of course, it can get a little out of hand. Take, for example, this descriptive but overly long variable in the Foundation API:
ubiquitousSharedItemMostRecentEditorNameComponents
If you’re not a fast typist, working with long, descriptive names for things may sound like torture. It’s going to take you forever to write your app.
Thankfully, Xcode helps with something called autocomplete. As you type code, when you pause in the middle of an identifier, Xcode provides a list of all the things it thinks you might be trying to type. This list puts its best guesses first.
In the image above, Xcode guesses that the recently declared forwardIndex is what you’re trying to type. In case it’s wrong, it guesses that ForEach is also a logical thing to place in this part of the code.
As you get used to working with autocomplete, you can take advantage of how the list filters. Like many lists in Xcode, you don’t have to type the beginning characters to get a match. You do have to match the case, though. Xcode calls this “fuzzy” matching.
Here, Xcode matches foI to forwardIndex. This is particularly helpful when working with long names. Sometimes, you can remember the middle of something but not the beginning. Autocomplete fuzzy matching will still help you find it.
When the list appears, press Enter to put the selected item in the code. You can use the up and down arrow keys to select different items in the list or type a few more characters to help with filtering.
Another place that autocomplete appears is for the properties of structures and objects. In Swift, when an object or structure has properties, the code has the name of the object followed by a period . and then the property’s name. After typing the name of a structure and pressing the ., Xcode again shows a list of what it thinks you want next. In addition to properties, objects and structures also have methods. Those also appear in the list.
Here, with the array of dogImages, Xcode shows the append method first as its best guess. The “M” icon designates that it’s a method. In SwiftUI, modifiers also have an “M”, but they’re just fancy methods. A few lines below, the count property might also go in the code here. The “P” icon lets you know it’s a property defined on dogImages.
There are a few other common icons to help distinguish items in the list:
- S: Structure
- C: Class
- I: Initializer
- T: Type
- •: Keyword
- L: Local variable
- {}: Snippet
Snippets
Autocomplete can do more than complete a single word. It can give you much longer and more complicated completions. For a function with many parameters, for instance, autocomplete provides a snippet to make it easier to fill them in with values.
The modifier foregroundStyle has a few forms with different parameters. They’re all in regular text in the list, meaning those parameters are required. The gray method of foregroundColor(_ color:) with the warning triangle is a deprecated method, meaning that Apple will remove it from Swift in a future release. You can use the deprecated modifier, but you shouldn’t. Once Apple removes it, trying to use it will cause a crash.
The snippet for foregroundStyle completes the code to call the method and has two placeholders for the two parameters. Pressing Tab cycles between the parameters, each with its own autocomplete. Because Xcode knows what type the parameter uses, it only shows items of that type in the list.
There are also snippets for common boilerplate code. For instance, an if-then structure always has the same format. Using the snippet, you can avoid typing all the extra words.
In the image above, the first item in the list is the keyword if, but the second item is the snippet for if-then. Pressing Enter to complete it provides the boilerplate parts of an if-then statement with placeholders.
Xcode is smart enough not to offer the if keyword or if-then snippet in places they aren’t valid. Though the if-then snippet doesn’t save too much typing, some of the other snippets are quite long and save a lot of typing.
You can see all of the snippets in the Snippet Library. You can access the library using the plus button on the top-right of most code windows, the View ▸ Show Library menu, or by pressing Command-Shift-L. From the Snippet Library, double-clicking the name of any snippet inserts into the code at the cursor.
For each snippet, you can see what the placeholders will be, when the snippet will be offered, and what to type so that autocomplete knows you want the snippet. For an if-else snippet, you can see that autocomplete offers it when you start to type ifelse in your code.
You can even add your own snippets to the library. Select some code and then right-click or control-click and choose Create Code Snippet… or use the Editor ▸ Create Code Snippet… menu option. The selected code is copied into the snippet library. Now, you can give it a descriptive name and enter the autocompletion value. To change anything into the snippet to a placeholder, surround it with <# #>.
Comments & Documentation
In addition to using descriptive names to make code easier to read, comments and inline documentation help make logic easier to follow. When using Swift and Xcode, you can make a single-line comment using //. The compiler ignores everything after the // until the end of the line. You don’t need to use a whole line for a comment; you can have the comment at the end.
//This is a comment across a whole line
let maxIndex = 5 // This comment is after the code
Comments in your code are a great way to make notes about what your code is trying to do. Sometimes, you want to write something a little longer. Perhaps you want a little paragraph and links to a blog post to help explain a particularly tricky piece of code. In that case, to keep from typing // at the beginning of each line, you can format your comments like this:
/* This is a long
multi-line comment.
The compiler is going to ignore
everything until the end.
Even this picture of a dog.
_ _
/(. .)\
(*)
*/
Everything between the /* and the */ is ignored as a comment.
When you’ve already typed something and want to make that into a comment, you can select the lines and press Command-/. This also works in reverse when you have many comments you want to un-comment. Select the lines and press Command-/. Commenting and un-commenting out sections of code is a standard tool used in troubleshooting.
Xcode provides a special type of comment that will add your comments to Quick Help and autocomplete for a piece of your code. By typing /// and then your comment above the declaration of a variable, the comment becomes part of Quick Help.
By using /// before the declaration of maxIndex, Xcode places that comment into the description at the bottom of the autocomplete menu. It’ll also appear in the Quick Help inspector.
This becomes more helpful and powerful when you document complicated functions.
/// Use this function to calculate the sum of every number between two numbers.
/// For example, the sum of every number between 1 and 10 is 55
/// 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55
///
/// - Parameters:
/// - minValue: The minimum number in the equation
/// - maxValue: The maximum number in the equation
/// - Returns: The collected sum as a Double
func calculateSum(minValue: Int, maxValue: Int) -> Double {
Here’s a longer and more detailed documentation of a function. Notice how the parameters and return value of the function are formatted. In addition to parameters and return values, you can specify things like copyright, dates, any known bugs, errors the function may throw, and related functions. You’ll find the complete list of keywords in Apple’s Swift GitHub repository.
Like Apple’s, the documentation above renders in the Quick Help inspector.
Warnings & Errors
The last topic you’ll cover in this section about how Xcode helps you with your syntax is the warnings and errors it generates as you type. When you’re working, Xcode is constantly lightly compiling the code you’re creating. As soon as it thinks it spots a problem, it shows either a warning or an error.
Warnings appear as yellow highlights in the line of code. To help make them a little more, perhaps too, prominent, they also appear in four other places on the Xcode interface.
In the image above, you can see the list of all current warnings in the issue navigator. At the top of the window, Xcode shows an indicator if there are warnings in any of the files in the app. Clicking that indicator opens the issue navigator. Clicking any warning in the issue navigator opens the file and highlights the line of code causing the warning.
In a source code file, all warnings and errors appear in the scroll bar. Clicking the indicator on the top right displays a list of all warnings. Selecting one jumps to that warning, like in the issue navigator.
Warnings have either a ! or a • character inside the triangle icon. When you see a •, that means Xcode has a Fix-It for that warning. That means that Xcode will offer one or more updates to the code to fix the warning. To see and apply the fix, click the warning icon in the line and then click the Fix button to tell Xcode to update the code.
As you’re fixing warnings, sometimes they’ll all turn gray. This means Xcode is re-evaluating the code. Any warnings that remain after the evaluation appear as yellow as soon as Xcode is done. Sometimes, Xcode gets stuck. You can force it to re-analyze the code using Product ▸ Analyze or by closing and re-opening your project.
In addition to the warnings that Xcode finds, you can add your own warnings to the code. Many teams use an open-source project SwiftLint that analyzes the code against team-defined rules. You can also explicitly add warnings into code:
#warning("This will appear as a warning")
Adding your own warnings is useful to leave notes to yourself or your teammates. It’s custom to begin many of these warnings with TODO: or FIXME:.
Xcode will build and run code with warnings in it. But it’s a sign that you’re doing something wrong that could cause issues in the future. It’s best to get into the habit of fixing warnings as they appear. Some teams even change the build setting to treat all warnings as errors. Xcode will refuse to build code with errors.
Modern iOS Xcode projects have settings for two compilers. The Clang compiler is for code written in the C language, and the Swift compiler is for Swift code.
Errors share many of the same traits as warnings and appear in all of the same locations in the Xcode interface. However, they appear as a red circle icon instead of a yellow triangle icon. The icon will have either an x or a •. As with warnings, when there’s an • in the icon, Xcode proposes a fix.
Sometimes, as you’re writing code, suddenly multiple errors appear in your file. Often, they’re false positive errors. The way Xcode analyzes the code is to start at the first character of the first line and move to the next. It continues linearly until it gets to the last character in the file. If, along the way, there’s a missing bracket or misplaced comma, Xcode may not notice that something is wrong until it gets to the end of the file.
All of the errors in the image above are false positives because of a missing closing curly bracket near the beginning of the file. When errors suddenly appear in a file, check to see if the last one is something about Expected '}'. If you see that, start at the beginning of the file and look for the missing bracket. Don’t try to fix the error by adding one at the end.