Xcode

Overview

Xcode is an IDE from Apple for creating apps for iPhone, iPad, macOS, Apple Watch, and Apple TV.

Starting in Xcode 14, the SDKs for every OS are no longer automatically downloaded when Xcode is installed. Only the iOS and macOS SDKs are downloaded, not watchOS or tvOS. This makes it faster to install Xcode. Additionally SDKs can be downloaded after Xcode is installed.

Resources

Paul Hudson provided an excellent summary of the new features added in Xcode 14 at What's New in Xcode 14?.

Panels

The Xcode user interface contains many panels that are described below:

AreaLocationPurposeToggle With
Navigatorleftdisplay files, search results, and moreView ... Navigators ... {Hide|Show Navigator} or cmd-zero
Editorcenter leftview and edit code and data in selected filesnone
Canvascenter rightview and interact with PreviewsEditor ... Canvas or cmd-option-return
Minimaprightdisplay zoomed out view of entire fileEditor ... Minimap or cmd-ctrl-shift-m
Inspectorrightview and editing details about selected itemView ... Inspectors ... {Hide|Show Inspector} or cmd-option-zero
Debugbottomdisplay print output and moreView ... Debug Area ... {Hide|Show Debug Area} or cmd-shift-y

The Navigator panel is used to navigate between specific kinds of resources. It appears on the left side of the Xcode window. This can be toggled between showing and hiding by pressing cmd-0 or tapping the following button on the left side of the title bar:

Xcode toggle Navigator panel

The Navigator panel displays the following nine icon buttons at the top:

Inspector

The Inspector panel is used to modify properties of the selected item. It appears on the right side of the Xcode window. This can be toggled between showing and hiding by pressing cmd-option-0 or tapping the following button on the right side of the title bar:

Xcode toggle Inspector panel

Files

To open a file within a project in an editor pane, select File ... Open Quickly... (or press cmd-shift-o), enter part of the file name (at least three characters), and click the file within the list that appears. This also works with any kind of name including types, variables, functions, structs, classes, properties, and methods. It even works with framework types.

Project Files

Xcode projects are described by a file with the .xcodeproj file extension which is short for "Xcode Project". These are actually "packages" (rather than files) that contain directories and files. To see this, right-click on a .xcodeproj file in the Finder and select "Show Package Contents". The typical contents include:

When files are added to a project directory from outside of Xcode (such as in the Finder or a Terminal window) it is necessary to select File ... Add Files... in Xcode in order to add entries in the .xcodeproj file so they are seen as belonging to the project.

When deleting files under a project directory, it is best to do so from Xcode rather than the Finder or a Terminal window. This updates the .xcodeproj file so the files are no longer seen as belonging to the project.

Editor

Xcode provides a specialized editor for some file types. Examples include project files (.xcodeproj) and Property List (PLIST) files (such as Info.plist and Localizable.stringsdict).

For many text-based file formats such as Swift (.swift) and Objective-C files (.m and .h) a text editor is used.

Code entered in an editor pane is checked for errors while typing. Saving is not required.

Lines with errors are indicated with red bars in the right gutter. By default these contains the number of errors on the line, an error icon (circle containing an "X"), and the first error message. Click anywhere in the red bar to fully display all the error messages. Sometimes errors contain a "Fix" button that can be clicked to automatically fix the error.

To hide the first error message, only displaying the number of errors and the error icon, select Xcode ... Settings ... General ... Issues ... Show Minimized. With this setting, click anywhere on a red bar, to see the text for all the errors on the line.

To see basic documentation of a name in code, option-click it. For more detail, click the "Open in Developer Documentation". Alternatively, click the circled question mark at the top of the Inspector. The Inspector will then display help for anything name under the cursor in the Code Editor.

Command-click a name to display a context menu that can include the following options:

Note that the "Extract Subview" option and the "Embed in *" options only appear a preview is displayed and a view name is command-clicked.

In the past there was a "Rename..." option in this menu. It was moved to Editor ... Refactor ... Rename.

Sticky Headers

When scrolling down through code, the first line of each type and function definition that encloses the code being viewed sticks at the top of the editor window to provide context.

To scroll to a sticky header, click it.

Multiple Editor Panes

To open a file in a new split pane, hold down the option key and click the file in the Project Navigator. If the file is already open, to open another view of the file in a new split pane press cmd-ctrl-t or hold down the option key and click the existing editor tab.

To choose editor window where the file will be opened, hold down the option and shift keys and click the file in the Navigator. Then release the keys, hover over where the file should be opened. Potential locations are highlighted as you hover. Click when the desired location is highlighted.

Alternatively, click the button the upper-right that is a rectangle containing a vertical line and a "+" to open a split pane containing the same file in the the currently editor pane.

To open a new split below the current one instead of to the right, open down the option key before clicking the button.

The dropdown menu to the left of this button enables toggling the display of the Canvas area and much more.

Matching Braces

To find the matching brace for a given brace, hold down the command key and hover over a brace. Alternatively, click after either brace to highlight the matching brace. When Vim Mode is enabled, this only works in insert mode.

To select all the code in matching braces, including the braces, double-click either one of them.

Code Completion

Xcode provides great intellisense and code completion.

When accepting a function completion, only non-dimmed arguments are included. To also include the dimmed arguments, hold down the option key before selecting a completion. To include a selected subset of the arguments, type the beginning of each of their names in a single string and press return. For example, .frame(mina gives .frame(minWidth: , alignment: ).

For function calls, press tab after entering each argument to advance to the next argument. If the last argument is a closure, press return to automatically turn it into a trailing closure.

Spell Checking

To configure Xcode to check spelling while typing, select Edit ... Format ... Spelling and Grammar ... Check Spelling While Typing. A faint red line will be displayed under all misspelled words.

Code Folding

To enable code folding, select Xcode ... Settings ... Text Editing and check the checkbox for "Code folding ribbon".

To fold the code in any construct (function, argument list, struct, class, ...), click the corresponding section in the code folding ribbon.

To unfold code, click the ">" in the code folding ribbon or double-click "..." in the code.

To enable code folding,

Multiple Cursors

To get multiple cursors so the same changes can be made in multiple locations simultaneously:

Replacing a Rectangular Selection

Rename All in Scope

One approach is to use refactoring as follows:

Another approach is to use "Edit All in Scope" as follows:

Refactoring

To rename all occurrences of a variable:

To move an expression into a new variable:

This will move the expression to become the value of a new variable and replace the extracted expression with a reference to the variable. The new variable will be a let constant, but this can be changed to a var manually.

To extract multiple lines of code to a new method:

This will move the selected code to a new method with the given name and replace the selected code with a call to the method. The new method will have an access level of fileprivate, but this can be changed manually. If the extracted code needs data present at the call site, the new method will have parameters for it and the supplied call will pass the required data.

To generate a memberwise initializer for a struct or class, right-click the its name and select Refactor ... Generate Memberwise Initializer. The new initializer will be preceded by the internal keyword which can be removed manually if desired.

To change a type to conform to the Equatable protocol, right-click the its name and select Refactor ... Add Equatable Conformance. This changes the type to inherit from Equatable and adds a static == method that returns true if all the properties are equal.

There are more context-sensitive Refactor menu options that are less frequently used.

For more on Xcode refactoring, see Xcode refactoring options explained with examples from SwiftLee.

Sorting

By default Xcode does not have the ability to sort selected lines.

WARNING! The following does not work in Xcode 14!

The ability to sort selected lines can be added using the extension xcsort.

Once installed:

Back in Xcode, select a range of lines to sort and select Editor ... xcsort ... Sort Lines.

Console

The bottom section is not visible by default. Drag the status row at the bottom up to expose it.

The bottom section has two subsections. The left side of the bottom section is for the debugging. The right side of the bottom section is for the console output such as that from print function calls.

Click the trashcan icon in the lower-right to clear the output. The output from print calls only appears when running in the debug mode.

Xcode used to support debug mode in Previews, but now it is only supported in the Simulator.

To make the console area appear automatically when new text is written to it, select Xcode ... Settings ... Behaviors ... Generates output, click the "Show" checkbox, and select "Variables & Console View".

Playgrounds

Playgrounds are great for experimenting with the Swift programming language.

To create and use a Playground:

Xcode is slow at evaluating a playground. It can take several seconds after saving a change for it to identify syntax errors and run the code.

Playgrounds treat files under “Sources” as separate, unnamed modules. To expose things defined in those files to the main playground code, declare them as public. They do not need to be "imported".

Projects

To develop an app:

To open an existing app, select File ... Open Recent ... {project-path} or select File ... Open, navigate to the project directory, and click "Open". Another way to open an existing Xcode project is to double-click its .xcodeproj file.

Code Formatting

To fix Swift code indentation in Xcode, select the lines to be fixed (cmd-a for all) and press ctrl-i which is the keyboard shortcut for Editor ... Structure ... Re-Indent. The default code indentation is four spaces. Chained method calls that appear on separate lines are indented, but those chained onto trailing closures are not.

Surrounding existing code with a new block automatically indents the surrounded code when the closing brace is typed.

Other options for Swift code formatting include SwiftFormat and swift-format.

SwiftFormat can be run as a command-line tool or an Xcode extension

To install SwiftFormat for command-line usage, enter brew install swiftformat. To format a .swift file, enter swiftformat file-name.swift. To format all the .swift files in the current directory, enter swiftformat *.swift.

To install SwiftFormat as an Xcode extension:

To format all the lines in the current file, press the assigned keyboard shortcut or select Editor ... SwiftFormat ... Format File.

There is currently no way within Xcode to format files on save. However, this can be configured using an Automator script and a System Preferences keyboard shortcut. The steps to configure this are described at Xcode Format and Save.

Code Generation

Xcode offers code completion of function/method calls. Optional arguments appear dimmed. Navigate to a proposed completion with the up and down arrow keys and press the return key to select it. When a completion with optional arguments is selected, those will not be included by default. To include them, hold down the option before pressing return.

Xcode will hide some code completions and indicate this with the text "+n more" at the end of a suggested completions. To reveal them, press the right arrow key.

To include them, hold down the option key before selecting the completion. Xcode can generate code for the memberwise initializer of a struct or class. Just type init and accept the completion. Then customize the provided code as needed.

Some code completions generate code that processes arrays. For example, type "lplay" and choose the List(players) { player... completion. This generates the following code, perhaps choosing to use some existing String property such as name:

List(players) { player in
Text(player.name)
}

Xcode can generate implementations of protocol implementations. For example, in a struct that conforms to the Codable protocol, type encode and accept the completion. Then customize the provided code as needed.

Documentation Generation

To generate DocC documentation for the current project select Product ... Build Documentation. This can take a couple of minutes to complete. When it does, a dialog will open that contains lists of all the classes, structs, functions, and enums defined by the project. Click a name to see details about it. Use the filter input at the top to filter the documentation to values containing specific text.

Supposedly the generated documentation can be exported to GitHub for viewing outside of Xcode, but it's not clear how to do that.

Pragma Marks

Each section of a source file can be preceded by a special comment called a "pragma mark". The syntax is // MARK: - SectionName where SectionName is typically something like Nested Types, Constants, Properties, Initializers, or Methods. Xcode will display these section names in the Minimap and in the dropdown of source file elements at the top of the Editor pane. The - in the comment is optional and causes a horizontal line to be drawn above the section name.

To toggle display of the Minimap, select Editor ... Minimap or press cmd-ctrl-M.

Building

To build a project, select Product ... Build or press cmd-b.

To hear sounds that indicate whether the build was successful or failed, select Xcode ... Settings ... Behaviors. Then select "Succeeds, check "Play sound", and select a sound. Repeat for "Fails" and select a different sound.

To see how long it takes each build to complete after the text "Build Succeeded" in the title bar, enter the following command in a terminal window:

defaults write com.apple.dt.Xcode ShowBuildOperationDuration -bool YES

To customize build settings, select the top item in the Project Navigator, select a target, click the "Build Settings" tab, and make changes.

For details on the available build settings, see Xcode Build Settings.

Clean Builds

Occasionally it is useful to delete all generated files and start over. To do this, select Product ... Clean Build Folder or press cmd-shift-k.

Running

To run an app:

To run the current app on a real iOS device:

To configure a device to run apps wirelessly:

To run the current app on a device wirelessly:

Previews

Previews allow testing a single view outside of the Simulator or a real device.

Previews are always live meaning they update automatically when code changes are saved. However, previews still sometimes need to be resumed by either clicking the "Resume" button or pressing cmd-option-p.

To toggle between showing and hiding the preview area, press cmd-option-return.

Calls to the print function are ignored when running a preview. To enable this, right-click on the play button in the canvas and select "Debug Preview". TODO: This must have moved in Xcode 14 and I can't find it!

A new "variants" button appears as the third button at the bottom of the preview area. Clicking this offers the options to show one of "Color Scheme Variants" (Light and Dark), "Orientation Variants" (Portrait, Landscape left, and Landscape right), and "Dynamic Text Variants" (X Small through XXX Large and AX 1 through AX 5)

If a preview defines multiple views, they are presented in separate tabs in the preview area. TODO: How are the tab titles specified?

Debugging

To see an outline of the frame of each view, run the app in a Simulator or real device and select Debug ... View Debugging ... Show View Frames to toggle it on. Select it again to toggle it off. This is much easier than modifying code to border view modifiers.

To open the debug area, select View ... Debug Area ... Show Debug Area, press cmd-shift-y, or drag the bottom bar up. There are two sides to the debug area. The left size displays variable names and values. Variable values can also be seen by hovering over their names in the editor area. The right side displays print function output.

Set breakpoints by clicking on source file line numbers.

Xcode breakpoint

Run the app and click the debugger buttons shown below. The app runs in debug mode by default because the default scheme "Run" settings has "Build Configuration" set to "Debug".

Xcode debugger buttons

App Icons

To add app icons:

SF Symbols

Access to SF Symbols is now built into Xcode. To access it, press cmd-shift-l or click the "+" in the upper-left and click the circled star. Type part of a symbol name in the input at the top to filter the list of symbols. Click a symbol name to see the symbol and a list of OSes where it is supported. Double-click a symbol name to insert it at the cursor location or drag it to the desired location inside a container view. This will insert Image(systemName: "{symbol-name}").

Source Control (Git)

Xcode has excellent built-in support for source control (aka version control) using Git. There are two main places where Git operations are initiated, the "Source Control" menu and the "Source Control Navigator". To access the "Source Control Navigator", select the second navigator tab or press cmd-2.

To allow Xcode to access your GitHub account:

Project Navigator

When a project has a Git repository, the list of files in the Project Navigator indicates their source control status with the following letters on the trailing edge of the file names:

Local Repositories

When a new Xcode project is created, there is an option to create a local Git repository for it. In the final dialog that is displayed when creating a new project (where the parent directory is selected), check the checkbox to "Create Git repository on my Mac".

If this is not done when the project is created, Xcode can create a local Git repository later. With the project open in Xcode, select Source Control ... New Git Repository... In the dialog that appears, click the "Create" button. This automatically creates the first commit containing all the existing files on a branch named "main".

To refresh the Git status shown for files in the Project Navigator, perhaps because their status has been changed outside of Xcode, select Source Control ... Refresh File Status.

To delete a local repository:

.gitignore File

All Swift project Git repositories should have a .gitignore file in their root directory that specifies files that should be committed to the repository. This file is not automatically created. This file can be obtained from gitignore.io.

Remote Repositories

To clone a remote GitHub repository:

Approach #1:

Approach #2:

To create a remote GitHub repository from a local Git repository:

To fetch new branches from the remote repository, select Source Control ... Fetch Changes.

To pull changes in a remote repository into the local repository:

To push changes committed in the local repository to the remote repository:

To view a remote Git repository that is known to Xcode:

To delete a remote Git repository that is known to Xcode:

Branches

The current branch is displayed in the Xcode title bar on the left side below the project name.

To see a list of all existing branches:

To create a new branch:

To switch to a different branch:

To merge one branch to another:

To delete a branch:

Uncommitted Changes

To see the Git status of all files in the project:

There are two ways to see uncommitted changes for the file in the current text editor pane:

Approach #1:

Approach #2:

To discard uncommitted changes in the current source file:

To discard all uncommitted changes:

Commits

To commit changes:

To see the changes in a previous commit:

Stashes

To stash uncommitted changes:

To see a list of existing stashes:

To apply stashed changes to the current branch:

To delete a stash:

Pull Requests

To create a pull request:

To view a pull request in the GitHub web UI:

To merge a pull request:

To close a pull request without merging it:

Tags

To tag a commit:

To push tags to a remote repository:

Reset

There is no option in Xcode to perform a git reset in order to remove some commits from the history. This must be done from the command-line or in another Git-aware tool.

Themes

To choose a different theme, select Xcode ... Settings ... Themes. From here you can add, delete, and select themes. I like the "Classic (Dark)" theme. This only affects editor windows. To change the entire Xcode UI to use a dark theme regardless of the system setting, select Xcode ... Settings ... General and select "Dark" from the Appearance dropdown.

Column Marker

To add a vertical line at a given column width, select Xcode ... Settings ... Text Editing, check "Page guide column at:", and choose a column number. The indentation amount and type (spaces vs. tabs) can also be specified here.

Code Folding

To enable code folding, select Xcode ... Settings ... Text Editing ... Display ... Code Folding Ribbon. This adds a code folding ribbon on the left side of editor panes. Click in the ribbon to fold the code at the corresponding line. To unfold, click again or double-click the ellipsis in the code.

Vim Support

To enable use of many Vim key bindings, select Editor ... Vim Mode. Dot commands and keyboard macros are not yet supported.

Duplicating Files

To duplicate a source file, select it in the Navigator and click File ... Duplicate. Oddly the context sensitive menu that is displayed when a file in the Navigator is right clicked does not include this option. Alternatively, hold down the option key and drag a file to a different group or within the same group.

App Name

To give the app a different name from the project:

New Files

To create a new file within a project, select File ... New ... File... or press cmd-n. This will display a dialog that prompts for a file type followed by another that prompts for the file name and directory where it should be saved.

When a new .swift file is created, by default it includes comment lines at the top like these where several placeholders are replaced:

//
// ___FILENAME___
// ___PACKAGENAME___
//
// Created by ___FULLUSERNAME___ on ___DATE___.
// ___COPYRIGHT___
//

Header Comments

To prevent Xcode from adding the comment lines above to new files, edit the file /Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File Templates/Multiplatform/Source/Swift File.xctemplate/__FILEBASENAME__.swift and delete the line //___FILEHEADER__ and the blank line that follows.

Mapping Files to Targets

Targets in an Xcode project are things that can be executed such as an iOS app, a watchOS app, unit tests, and UI tests.

By default files are only accessible from their associated target. If an app has multiple targets and a source file should be shared between them, select the file in the Navigator, open the Inspector on the right, and check the checkboxes for each target that should have access to the file.

Schemes

A "scheme" defines a target to build, the configuration settings to use when building it, and a set of tests to run after the target is built.

Every project begins with a default scheme whose name matches the project name.

To access the schemes of a project, click the project name in the top center (just to the left of the device dropdown). This opens a dropdown menu that contains a menu item for each existing scheme and the following options:

Schemes are defined by six phases that include Build, Run, Test, Profile, Analyze, and Archive.

The Build phase specifies:

The Run phase specifies many things including:

The screenshot below shows changing the language and region which affects those values when the app is run in the Simulator or on a device.

Xcode scheme language and region

The Test phase specifies:

The Profile phase specifies:

The Analyze phase only specifies whether a Debug or Release build configuration should used. TODO: What does this phase do?

The Archive phase specifies the archive name and whether a Debug or Release build configuration should used. An "archive" is a file that can be submitted to TestFlight and the App Store.

Hot Reload

While Previews usually automatically update when changes to a project file are saved, this behavior is inconsistent. Also, some app features are not supported when running in a preview.

For these reasons it would be great if apps running in the Simulator could automatically build and reload when changes to a project file are saved. By default Xcode does not do this automatically, but it can be configured.

Krzysztof Zabłocki describes a way to implement this in his article Hot Reloading in Swift. This uses his Inject package. The solution involves installing an app that watches specified directories for file changes. When a file change is detected, it is rebuilt and injected into the app without rebuilding the entire app. The updated version of the app is then loaded into the Simulator.

The one-time steps are:

  1. Browse the GitHub repo InjectionIII and download the file InjectionIII.app.zip. The file InjectionIII.app will appear in the Downloads directory.
  2. Drag the downloaded app to the Applications directory.
  3. Double-click the app to run it. This is a menu bar app that adds an icon. This app MUST BE RUNNING for hot reloading to work! Clicking the icon opens a menu of options. Verify that "File Watcher" is selected.

The per-project steps are:

  1. Open an iOS project in Xcode.
  2. Select File ... Add Packages...
  3. Enter "Inject" in the search input or paste the URL "https://github.com/krzysztofzablocki/Inject".
  4. Select "Inject" in the list of matching packages.
  5. Click the "Add Package" button.
  6. Click the next "Add Package" button.
  7. Select the top item in the Navigator.
  8. Select the main target.
  9. Click the "Build Settings" tab.
  10. Enter "Other Linker Flags" in the filter input.
  11. Expand the "Other Linking Flags" row.
  12. For the value of the "Debug" row, paste -Xlinker -interposable
  13. Open the ContentView.swift file.
  14. Add import Inject
  15. Add the property @ObservedObject private var iO = Inject.observer
  16. Chain a call to .enableInjection() at the end of what body returns.
  17. Click the InjectionIII menu bar icon and select "Open Project". If the menu bar icon is not present, double-click the InjectionIII app to launch it.
  18. Select the directory that contains the .xcodeproj project file.
  19. Click the "Select Project Directory" button.
  20. Run the project in the Simulator.

Note that the added code does not need to be removed before releasing the app to production because it does nothing unless it is run in debug mode.

If the directory being watched is nested inside the Desktop or Documents directory, another dialog map appear requesting permission to access files in those directories. https://github.com/johnno1962/InjectionIII/releases?v=1.0.20

If you override the cmd-s keybinding to run something like "SwiftFormat - Format File" and also save changes, pressing it will not trigger the Simulator to update. In this case the Simulator will update if you active any other app besides Xcode. See this issue.

It seems that some changes do not get injected into the running app. For example changes to property initial values do not take effect. See this issue. In the code below, hot reload will not pick up a change to the value of the name property.

Keyboard Shortcuts

Xcode supports a large number of keyboard shortcuts, many of which were described in the previous sections. The following table summarize the most commonly used keyboard shortcuts.

Visibility of UI Parts

ActionKey
show quick actionscmd-shift-a
show file navigatorcmd-1
show local changes navigatorcmd-2
show symbols navigatorcmd-3
show find navigatorcmd-4
show issues navigatorcmd-5
show tests navigatorcmd-6
show debug navigatorcmd-7
show breakpoints navigatorcmd-8
show reports navigatorcmd-9
toggle navigator panelcmd-0
toggle inspector panelcmd-option-0
toggle debug areacmd-shift-y
activate consolecmd-shift-c
toggle toolbarcmd-option-t
toggle full screencmd-ctrl-f
toggle preview displaycmd-option-return
toggle minimapcmd-ctrl-shift-m
toggle authors (who last edited each line and when)cmd-ctrl-shift-a
open developer documentationcmd-shift-0
open librarycmd-shift-l
toggle editor focuscmd-ctrl-shift-return

"Show Quick Actions" was added to the "Tools" menu in Xcode 15. It has perhaps the most important keyboard shortcut, cmd-shift-a. Pressing that opens a dialog that can run any menu command. Type part of the command to filter the list. For example, to run the "Clean Build Folder" command from the "Tools" menu, press cmd-shift-a, type "cle", and press return.

When the editor area is split, toggle focusing on just the split that has focus by selecting View ... Editor ... Focus and restore the splits by selecting View ... Editor ... Hide Focus. Alternatively press cmd-ctrl-shift-return to toggle focus or click the buttons in the upper-left of each editor split that contain an arrow pointing southwest and an arrow pointing northeast. When the button has a blue background it means editor splits are hidden.

To add and customize keyboard shortcuts, select Xcode ... Settings ... Key Bindings. Location a command whose keyboard shortcut is to be changed, double-click the "Key" column of that row, and press the desired keyboard shortcut. If the new keyboard shortcut is already in use, a warning will be displayed.

Build/Run

ActionKey
restart previewcmd-option-p
buildcmd-b
build and runcmd-r
cleancmd-shift-k
clear consolecmd-k
ActionKey
go to previous locationcmd-ctrl-left or tap "<" button in upper-left
go to next locationcmd-ctrl-right or tap ">" button in upper-left
switch to next file tabcmd-}
switch to previous file tabcmd-{
go back to previously viewed filecmd-ctrl-left-arrow
go forward to previously viewed filecmd-ctrl-right-arrow
move focus to next panecmd-option-`
open jump menuctrl-6

The jump menu displays a list of all the types, properties, and methods defined in the current source file. If the file contains pragma mark comments (// MARK: - {section-name}) then the list will be divided into sections with those names. Clicking a name scrolls to that definition and highlights it. To make it easier to find a particular item in the list, type part of its name.

Find/Replace

ActionKey
find in filecmd-f
find next in filecmd-g
find previous in filecmd-shift-g
find and replace in filecmd-option-f
find and replace next in filecmd-option-g
find in projectcmd-shift-f
find next in projectcmd-shift-g
find and replace in projectcmd-option-shift-f
rename refactorcmd-ctrl-e

Code Formatting

Code formatting can happen automatically when changes are saved by following the direction at SwiftFormat.

ActionKey
re-indent current line or selected linesctrl-i
increase line indentcmd-]
decrease line indentcmd-[

Code Folding

ActionKey
fold codecmd-option-left
unfold codecmd-option-right
fold all functions and methodscmd-option-shift-left
unfold all functions and methodscmd-option-shift-right

Source Control

ActionKey
git commitcmd-option-c
git pullcmd-option-x

Miscellaneous

ActionKey
context menu for options like "Embed in VStack"cmd-click
increase font sizecmd-plus
decrease font sizecmd-minus
open filecmd-o
open new split pane for file in focused editorcmd-ctrl-t
fuzzy file finder (open quickly)cmd-shift-o
toggle commenting current or selected linescmd-/

Snippets

Snippets are commonly used lines of code that can be quickly inserted. To insert a snippet, entering part of its name, selecting from the matching options, and press the return key.

There are many predefined snippets and custom snippets can be defined.

To see the existing snippets, select View ... Show Library, click the "+" in the upper-right, or press cmd-shift-l. Then click the "{}" button at the top center.

Many snippets contain placeholders for text to be inserted. After inserting a snippet, the cursor will be positioned at the first placeholder. After entering text for a placeholder, press the return key followed by the tab key to move to the next placeholder.

To create a new snippet:

To add placeholders in a snippet, add placeholder names surrounded by "<#" and "#>". The placeholder text will be replaced by a highlighted version of the placeholder name. Unfortunately, using the same placeholder name multiple times within a snippet does not cause them to be replaced by the same text.

The literal expressions #file, #fileID, #function, #line, and #column can be used to provide context in print output. For example:

print("\(#fileID) \(#function) <#variable#> =", <#variable#>)

To edit an existing snippet, select it in the Library and click the "Edit" button in the lower-right.

To delete an existing snippet, select it in the Library and click the "Delete" button in the lower-left.

Snippets I have defined include:

CompletionExpands To
logeprint("\(#fileID) \(#function) entered
logvprint("\(#fileID) \(#function) <#variable#> =", <#variable#>)
spv@State private var

Using a New Swift Version

See How to use a pre-release Swift version in Xcode.

Xcode Issues

While using Xcode is generally fine, it does have a few issues.