1.
Checking Your Tools
Written by Audrey Tam
You’re eager to dive into this book and create your first iOS app. If you’ve never used Xcode before, take some time to work through this chapter. You want to be sure your tools are working and learn how to use them efficiently.
Getting started
To develop iOS apps, you need a Mac with Xcode installed. If you want to run your apps on an iOS device, you need an Apple ID. And if you have an account on GitHub or similar, you’ll be able to connect to that from Xcode.
macOS
To use the SwiftUI canvas, you need a Mac running Catalina (v10.15) or later. To install Xcode, your user account must have administrator status.
Xcode
To install Xcode, you need 29 GB free space on your Mac’s drive.
➤ Open the App Store app, then search for and GET Xcode. This is a large download so it takes a while. Plenty of time to fix yourself a snack while you wait. Or, to stay in the flow, browse Chapter 12, “Apple App Development Ecosystem”.
➤ When the installation finishes, OPEN it from the App Store page:
Note: You probably have your favorite way to open a Mac application, and it will work with Xcode, too. Double-click it in Applications. Or search for it in Spotlight. Or double-click a project’s .xcodeproj file.
The first time you open Xcode after installation, you’ll see this window: Install additional required components?:
➤ Click Install and enter your Mac login password in the window that appears. This takes a little while, about enough time to make a cup of tea or coffee.
➤ When this installation process finishes, you might have to open Xcode again. The first time you open Xcode, you’ll see this Welcome window:
If you don’t want to see this window every time you open Xcode, uncheck “Show this window when Xcode launches”. You can manually open this window from the Xcode menu Window ▸ Welcome to Xcode or press Shift-Command-1. And, there is an Xcode menu item to perform each of the actions listed in this window.
Creating a new Xcode project
You’ll create a new Xcode project just for this chapter. The next chapter provides a starter project that you’ll build on for the rest of Section 1.
➤ Click Create a new Xcode project. Or, if you want to do this without the Welcome window, press Shift-Command-N or select File ▸ New ▸ Project… from the menu.
A large set of choices appears:
➤ Select iOS ▸ App and click Next. Now, you get to name your project:
- For Product Name, type FirstApp.
- Skip Team for now.
- For Organization Identifier, type the reverse-DNS of your domain name. If you don’t have a domain name, just type something that follows this pattern, like org.audrey. The grayed-out Bundle Identifier changes to your-org-id.FirstApp. When you submit your app to the App Store, this bundle identifier uniquely identifies your app.
- For Interface, select SwiftUI.
- For Life Cycle, select SwiftUI App.
- For Language, select Swift.
- Uncheck the checkboxes.
➤ Click Next. Here’s where you decide where to save your new project.
Note: If you forget where you saved a project, you can find it by selecting File ▸ Show in Finder from the Xcode menu.
➤ If you’re saving this project to a location that is not currently under source control, click the Source Control checkbox to create a local Git repository. Later in this chapter, you’ll learn how to connect this to a remote repository.
➤ Click Create. Your new project appears, displaying ContentView.swift in the editor pane.
Looks like there’s a lot going on! Don’t worry, most iOS developers know enough about Xcode to do their job, but almost no one knows how to use all of it. Plus Apple changes and adds to it every year. The best (and only) way to learn it is to jump in and start using it.
Ready, set, jump!
A quick tour of Xcode
You’ll spend most of your time working in a .swift file:
The Xcode window has three main panes: Navigator, Editor and Inspectors. When you’re viewing a SwiftUI View file in the Editor, you can view the preview canvas side-by-side with the code. When the app is running, the Debug Area opens below the Editor.
You can hide or show the navigator with the toolbar button just above it, and the same for the inspectors. The debug area has a hide button in its own toolbar. You can also hide any of these three panes by dragging its border to the edge of the Xcode window.
And all three have keyboard shortcuts:
- Hide/show Navigator: Command-0
- Hide/show Inspectors: Option-Command-0
- Hide/show Debug Area: Shift-Command-Y
Note: There’s a handy cheat sheet of Xcode keyboard shortcuts in the assets folder for this chapter. Not a complete list, just the ones that many people use.
Navigator
The Navigator has nine tabs. When the navigator pane is hidden, you can open it directly in one of its tabs by pressing Command-1 to Command-9:
- Project: Add, delete or group files. Open a file in the editor.
- Source Control: View Git repository working copies, branches, commits, tags, remotes and stashed changes.
- Symbol: Hierarchical or flat view of the named objects and methods.
- Find: Search tool.
- Issue: Build-time and runtime errors and warnings.
- Test: Create, manage and run unit and UI tests.
- Debug: Information about CPU, memory, disk and network usage while your app is running.
- Breakpoint: Add, delete, edit and manage breakpoints.
- Report: View or export reports and logs generated when you build and run the project.
The Filter field at the bottom is different for each tab. For example, the Project Filter lets you show only the files you recently worked on. This is very handy for projects with a lot of files in a deeply nested hierarchy.
Editor
When you’re working in a code file, the Editor shows the code and a Minimap. The minimap is useful for long code files with many properties and methods. You can hover the cursor over the minimap to locate a specific property, then click to go directly to it. You don’t need it for the apps in this book, so you may want to hide it via the button in the upper right corner of the editor.
When you’re working in a SwiftUI file, Option-Command-Return shows or hides the preview canvas.
The editor has browser features like tab and go back/forward. Keyboard shortcuts for tabs are the same as for web browsers: Command-T to open a new tab, Shift-Command-[ or ] to move to the previous or next tab, Command-W to close the tab and Option-click a tab’s close button to close all the other tabs. The back/forward button shows a list of previous/next files, but the keyboard shortcuts are Control-Command-right or -left arrow.
Inspectors
The Inspectors pane has three or four tabs, depending on what’s selected in the Project navigator. When this pane is hidden, you can open it directly in one of its tabs by pressing Option-Command-1 to Option-Command-4:
- File: Name, Full Path, Target Membership.
- History: Source Control log.
- Quick Help: Short form of Developer Documentation if you select a symbol in the editor.
- Attributes: Properties of the symbol you select in the editor.
The fourth tab appears when you select a file in the Project navigator. If you select a folder, you get only the first three tabs.
This quick tour just brushes the surface of what you can do in Xcode. Next, you’ll use a few of its tools while you explore your new project.
Navigation preferences
In this book, you’ll use keyboard shortcuts to examine and structure your code. Unlike the fixed keyboard shortcuts for opening navigator tabs or inspectors, you can set preferences for which shortcut does what. To avoid confusion while working through this book, you’ll set your preferences to match the instructions you’ll see.
➤ Press Command-, to open Preferences. In the Navigation tab, set:
- Command-click on Code to Selects Code Structure
- Option-click on Code to Shows Quick Help
- Navigation Style to your choice of Open in Tabs or Open in Place.
ContentView.swift
The heart of your new project is in ContentView.swift, where your new project opened. This is where you’ll lay out the initial view of your app.
➤ If ContentView.swift isn’t in the editor, select it in the Project navigator.
The first several lines are comments that identify the file and you, the creator.
import
The first line of code is an import
statement:
import SwiftUI
This works just like in most programming languages. It allows your code to access everything in the built-in SwiftUI module. See what happens if it’s missing.
➤ Click on the import
statement, then press Command-/.
You commented out the import
statement, so compiler errors appear, complaining about View
and PreviewProvider
.
➤ Press Command-Z to undo.
Below the import
statement are two struct
definitions. A structure is a named data type that encapsulates properties and methods.
struct ContentView
The name of the first structure matches the name of the file. Nothing bad happens if they’re different, but most developers follow and expect this convention.
struct ContentView: View {
var body: some View {
Text("Hello, world!")
.padding()
}
}
Looking at ContentView: View
, you might think ContentView
inherits from View
, but Swift structures don’t have inheritance. View
is a protocol, and ContentView
conforms to this protocol.
The required component of the View
protocol is the body
computed property, which returns a View
. In this case, it returns a Text
view that displays the usual “Hello, world!” text.
Swift Tip: If there’s only a single code statement, you don’t need to explicitly use the
return
keyword.
The Text
view has a padding
modifier — an instance method of View
— that adds space around the text. You can see it in this screenshot:
This also shows the Quick Help inspector for Text
. If you don’t want to use screen real estate for this inspector, Option-click Text
in the code editor to see the same information in a pop-up window. Clicking Open in Developer Documentation opens a window with more information.
➤ Select the Text
view in either the code editor or the canvas, then select the Attributes inspector. Click in the Add Modifier field and wait a short while until the modifiers menu appears:
Scrolling through this list goes on and on and on.
This inspector is useful when you want to add several modifiers to a View
. If you just need to add one modifier, Control-Option-click the view to open the Attributes inspector pop-up window.
struct ContentView_Previews
Below ContentView
is a ContentView_Previews
structure.
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The ContentView_Previews
structure is what appears in the canvas on the right of the code editor. Again, see what happens if it’s missing.
➤ Select the five lines of ContentView_Previews
and press Command-/.
Without ContentView_Previews
, there’s nothing in the canvas.
➤ Press Command-Z to undo or, if the five lines are still selected, press Command-/ to uncomment them.
For most apps, ContentView.swift is just the starting point. Often, ContentView
just defines the app’s organization, orchestrating several subviews. And usually, you’ll define these subviews in separate files.
Creating a new SwiftUI View file
Everything you see in a SwiftUI app is a View
. Apple encourages you to create as many subviews as you need, to avoid redundancy (DRY or Don’t Repeat Yourself) and organize your code to keep it manageable. The compiler takes care of creating efficient machine code, so your app’s performance won’t suffer.
➤ In the Project navigator, select ContentView.swift and type Command-N. Alternatively, right-click ContentView.swift then select New File… from the menu.
Xcode Tip: A new file appears in the project navigator below the currently selected file. If that’s not where you want it, drag it to where you want it to appear in the project navigator.
The new file window displays a lot of options! The one you want is iOS ▸ User Interface ▸ SwiftUI View. In Chapter 5, “Organizing Your App’s Data”, you’ll get to create a Swift File.
Naming a new SwiftUI view
➤ Select SwiftUI View then click Next. The next window lets you specify a file name. By default, the name of the new view will be the same as the file name. You’ll define the ByeView
in this file, so replace SwiftUIView with ByeView.
Swift Tip: Swift convention is to name types (like
struct
) with UpperCamelCase and properties and methods with lowerCamelCase.
This window also lets you specify where (in the project) to create your new file. The default location is usually correct: in this project, in this group (folder) and in this target.
➤ Click Create to finish creating your new file.
The template code for a SwiftUI view looks almost the same as the ContentView
of a new project.
import SwiftUI
struct ByeView: View {
var body: some View {
Text("Hello, world!")
}
}
struct ByeView_Previews: PreviewProvider {
static var previews: some View {
ByeView()
}
}
Like ContentView
, the view’s body contains Text("Hello, world!")
, but there’s no padding.
Using your new SwiftUI view
Next, edit your new view’s Text
view string to look like this:
Text("Bye bye, World!")
Now, in ContentView.swift, in the code editor, delete the Text
view, then type bye. Xcode suggests some auto-completions:
Notice you don’t have to type the correct capitalization of ByeView
.
Xcode Tip: Descriptive names for your types, properties and methods is good programming practice, and auto-completion is one way Xcode helps you do the right thing. You can also turn on spell-checking from the Xcode menu: Edit ▸ Format ▸ Spelling and Grammar ▸ Check Spelling While Typing.
Select ByeView from the list, then add parentheses, so the line looks like this:
ByeView()
You’re calling the initializer of ByeView
to create an instance of the view.
➤ Click Resume or press Option-Command-P to refresh the preview:
You’ll create many new SwiftUI view files and Swift files to develop the apps in this book.
What else is in your project?
The Project navigator lists several files and folders.
- FirstAppApp.swift: This file contains the code for your app’s entry point. This is what actually launches your app.
@main
struct FirstAppApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
The @main
attribute marks FirstAppApp
as the app’s entry point. You might be accustomed to writing a main()
method to actually launch an app. The App
protocol takes care of this.
The App
protocol requires only a computed property named body
that returns a Scene
. And a Scene
is a container for the root view of a view hierarchy.
For an iOS app, the default setup is a WindowGroup
scene containing ContentView()
as its root view. A common customization is to set different root views, depending on whether the user has logged in.
In an iOS app, the view hierarchy fills the entire display. In a macOS or iPadOS app, WindowGroup
can manage multiple windows.
- Assets.xcassets: Store your app’s images and colors here. AppIcon is a special image set for all the different sizes and resolutions of your app’s icon.
- Info.plist: This configuration property list contains information needed to launch your app. Many of the names are environment variables derived from the options you set when you created the project. Here you can find things like the app name and version number.
- Preview Content: If your views need additional code and sample data or assets while you’re developing your app, store them here. They won’t be included in the final distribution build of your app.
- Products: This is where Xcode stores your app after you build and run the project. A project can contain other products, like a Watch app or a framework.
In this list, the last two items are groups. Groups in the Project navigator appear to be folders, but they don’t necessarily match up with folders in Finder. In particular, there’s no Products folder in your project in Finder.
➤ In the Project navigator, select Products ▸ FirstApp.app, then show the File inspector:
FirstApp.app isn’t anywhere near your project files! It’s in your home directory’s hidden Library folder.
Note: Don’t rename or delete any of these files or groups. Xcode stores their path names in the project’s build settings and will flag errors if it can’t find them.
You’ll learn how to use these files in the rest of this book.
Xcode Preferences
Xcode has a huge number of preferences you can set to make your time in Xcode more productive.
Themes
You’ll be spending a lot of time working in the code editor, so you want it to look good and also help you distinguish the different components of your code. Xcode provides several preconfigured font and color themes for you to choose from or modify.
➤ Press Command-, to open Preferences, then select the Themes tab:
Go ahead and explore these. You can customize them or create your own. I’ll wait here. ;]
Matching delimiters
SwiftUI code uses a lot of nested closures. It’s really easy to mismatch your braces and parentheses. Xcode helps you find any mismatches and tries to prevent these errors from happening.
➤ In Preferences, select Text Editing ▸ Editing:
Most of the Code Completion items are super helpful. Although you can copy and paste code from this book, you should try to type the code as much as possible to learn how these aids work.
Here’s a big hint that something’s wrong or you’re typing in the wrong place: You’re expecting Xcode to suggest completions while you type, but nothing (useful) appears. When this happens, it’s usually because you’re outside the closure you need to be in.
➤ Now select the Text Editing ▸ Display tab. Check Code folding ribbon and, if you like to see them, Line numbers:
So what’s a code folding ribbon? Between the line numbers and the code, you see darker gray vertical bars. Hover your cursor over one, and it highlights the start and end braces of that closure:
Other ways to see matching delimiters:
- Option-hover over {, (, [ or a closing delimiter: Xcode highlights the start and end delimiters.
- Double-click a delimiter: Xcode selects the delimiters and their contents.
➤ Now click the bar (ribbon) to collapse (fold) those lines of code:
This can be incredibly useful when you’re trying to find your way around some complex deeply-nested code.
➤ Click the ribbon to unfold the code.
Adding accounts
You can access some Xcode features by adding login information for your Apple ID and source control accounts.
➤ In Preferences, select Accounts:
➤ Add your Apple ID. If you have a separate paid Apple Developer account, add that too.
To run your app on a device, you’ll need to select a Team. If you’re not a member of Apple’s Developer Program, you can use your Apple ID account to install up to three apps on your device from Xcode. The app works for seven days after you install it.
To add capabilities like push notifications or Apple Pay to your app, you need to set Team to a Developer Program account.
Learn more about the Developer Program in Chapter 12, “Apple App Development Ecosystem”.
- If you have an account at Bitbucket, GitHub or GitLab, add it here if you want to push your project’s local git repository to a remote repository.
Bitbucket, GitHub and GitLab accounts require a personal access token. Click the link to open the site’s token-creation page.
➤ To set up a remote repository, open the Source Control navigator (Command-2), then click the settings button and select New “FirstApp” Remote…:
➤ Select your options, then click Create:
And here it is:
Running your project
So far, you’ve relied on Preview to see what your app looks like. In the next chapter, you’ll use Live Preview to interact with your app. But some features don’t work in Live Preview, so then you need to build and run your app on a simulator. And some things will only work on an iOS device. Plus, it’s fun to have something on your iPhone that you built yourself!
The Xcode toolbar
First, a quick tour of the toolbar:
Xcode Tip: Press Option-Command-T to show or hide the toolbar. If this keyboard shortcut conflicts with another app, select the command from the Xcode View menu.
So far, you’ve only used the buttons at either end of the toolbar, to show or hide the navigator or inspector panes.
Working from left to right after the navigation pane button:
- Run button: Build and run (Command-R) the project.
- Stop button: Stop (Command-.) the running project.
- Scheme menu: This button’s label is the name of the app. Select, edit or manage schemes. Each product has a scheme. FirstApp has only one product, so it has only one scheme.
- Run destination menu: This menu defaults to its last item, currently iPod touch. Select a connected device or a simulated device to run the project.
- Activity view: A wide gray field that shows the project name, status messages and warning or error indicators.
- Library button: Label is a + sign. Opens the library of views, modifiers, code snippets and media and colors stored in Assets. Option-click this button to keep the library open.
-
Code review button: If this project has a local git repository, this button shows a
diff
of the current version of the current file and the most recent committed version. You can choose earlier committed versions from a menu.
Now that you know where the controls are, it’s time to use some of them.
Choosing a run destination
Apple sells a lot of different iPhone models, plus iPads and even an iPod Touch. They’re all different sizes, and some have a notch. How do you know if your app looks good on every screen size?
You don’t need a complete collection of iOS devices. Xcode has several Developer Tools, and one of them is Simulator. The run destination menu lets you choose from a list of simulated devices.
➤ Click the run destination button and select iPhone 12 Pro.
➤ Refresh the preview of ContentView
or ByeView
:
The preview uses the run destination device by default. You can create more than one preview and set each to a different device with the previewDevice
modifier.
For example:
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView()
ContentView()
.previewDevice("iPhone SE (2nd generation)")
}
}
}
The preview usually looks the same as your app running on a simulated or real device, but not always. If you feel the preview doesn’t match what your code is laying out, try running it on a simulator.
Note: To zoom in or out on the preview canvas, use the + or - buttons in the canvas toolbar.
Build and run
➤ Click the run button or press Command-R.
The first time you run a project on a simulated device, it starts from an “off” state, so you’ll see a loading indicator. Until you quit the Simulator app, this particular simulated device is now “awake”, so you won’t get the startup delay even if you run a different project on it.
After the simulated device starts up, the app’s launch screen appears. For FirstApp, this is just a blank screen. You’ll learn how to set up your own launch screen in Chapter 16, “Adding Assets to Your App”.
And now, your app is running!
There’s not much happening in this app, but the debug toolbar appears below the editor window. For this screenshot, I showed the debug area, selected the Debug tab in the navigator pane, then selected the CPU item.
Not stopping
Here’s a trick that will make your Xcode life a little easier.
➤ Don’t click the stop button. Yes, it’s enabled. But trust me, you’ll like this. :]
➤ In ByeView.swift, replace “Bye bye” with “Hello again”:
Text("Hello again, World!")
➤ Click the run button or press Command-R.
Up pops this message:
➤ Don’t click Stop, although that will work: The currently running process will stop, and the new process will run. And this will happen every time you forget to stop the app. It takes just a moment, but it jars a little. Every time. And it’s easy to get rid of.
➤ Check Do not show this message again, then click Stop.
The app loads with your new change. But that’s not what I want to show you.
➤ One more time: Click the run button or press Command-R.
No annoying message, no “doh!” moment, ever again! You’re welcome. ;]
Running your apps on an iOS device
Sometimes, your app doesn’t look or behave quite right on the simulated device. Running it on a real device is the final word: It might look just as you expect, or it might agree with the preview and simulator that you’ve got more work to do.
Also, there are features like motion and camera that you can’t test in a simulator. For these, you must install your app on a real device.
Apple does its best to protect its users from malicious apps. Part of this protection is ensuring Apple knows who is responsible for every app on your device. Before you can install your app from Xcode onto your device, you need to select a team (your Apple ID), to get a signing certificate from Apple.
➤ In the project page, select the target. In the Signing & Capabilities tab, check Automatically manage signing, then select your account from the Team menu:
After some activity spinning, you’ll see a Provisioning Profile and a Signing Certificate. Xcode has created these and stored the certificate in your Mac’s keychain.
Note: The Bundle Identifier of your project uses your organization name because you created it as a new project. The other apps in this book have starter projects with com.raywenderlich as the organization. If you want to run these apps on an iOS device, you need to change the organization name in the bundle ID to something that’s uniquely yours. This is because one of the authors has already signed the app with the original bundle ID, and you’re not a member of our teams.
To run this book’s apps on your iOS device, it must have iOS 14 installed. If it’s not the absolute latest update, select the project, then set its iOS Deployment Target to match your device.
➤ Connect your device to your Mac with a cable. Use an Apple cable, as other-brand cables might not work for this purpose.
Note: If your account is a paid Apple Developer account, you won’t need to do the next several steps. Running your app on your device will just work.
The first time you connect a device to your Mac, the device will ask Trust This Computer?
➤ Tap Trust, then enter the device passcode when prompted.
➤ Select your device from the run destination menu: It appears at the top, above the simulators:
➤ Unlock your device, then build and run your project. Keep your device screen active until the app launches on your device.
This is the first time you’re running an app on a device, so there are several extra steps that Apple makes you perform, mainly trying to make sure nothing nasty installs itself on your device.
➤ First, you need to allow codesign to access the certificate that Xcode stored in your keychain:
➤ Enter your password, then click Always Allow.
Next, you’ll see FirstApp’s app icon appear on the screen of your device, but this error message appears on your Mac:
Of the three possible reasons, it’s the last one that’s holding things up: its profile has not been explicitly trusted by the user. Apple really doesn’t want just anyone installing potentially malicious apps on your device. You have to say it’s OK. The problem is, there’s not much here to tell you what to do.
➤ Well, the app icon is on your device’s screen, so why not tap it to see what happens?
You can allow using these apps in Settings is a pretty minimal hint, but open Settings to see what’s there. You’ll probably never guess where to look, so here are the relevant screenshots:
➤ Tap General. Scroll down to Device Management — you can just see the start of your certificate name. Tap this item.
➤ Tap Apple Development…, then tap Trust “Apple Development… and finally, tap Trust.
You won’t need to do this again unless you delete all your apps from this device.
➤ Now close Settings and tap the FirstApp icon:
Underwhelming? Yes, well, it’s the thought that counts. ;]
What matters is, you’re now all set up to run your own projects on this device. When you really want to get something running right away, you won’t have to stop and deal with any of this Trust business.
In the following chapters, you’ll create a much more interesting app.
Key points
- The Xcode window has Navigator, Editor and Inspectors panes, a Toolbar and a Debug Area, plus a huge number of Preferences.
- You can set some navigation keyboard shortcuts in Preferences, to match the instructions in this book.
- The template project defines an
App
that launches withContentView
, which displays “Hello, world!” in aText
view. - You can view Quick Help documentation in an inspector or by using a keyboard shortcut. Or, you can open the Developer Documentation window.
- When you create a new SwiftUI view file, give it the same name as the
View
you’ll create in it. - Xcode’s auto-completion, delimiter-matching, code-folding and spell-checking help you avoid errors.
- You can choose one of Xcode’s font and color themes, modify one or create your own.
- You can run your app on a simulated device or create previews of specific devices.
- You must add an Apple ID account in Xcode Preferences to run your app on an iOS device.
- The first time you run your project on an iOS device, Apple requires you to complete several “Trust” steps.