In this tutorial, we’re going to take a look at the most important aspects of Xcode. You’ll get a tour around Xcode, so you can get up to speed with Swift programming and iOS app development. It’s Xcode 101!
Here’s what we’ll get into:
Xcode is the Mac app that you use to build apps for iOS, macOS, tvOS and watchOS. You use Swift programming, and the many tools inside Xcode, to build applications for iPhone, iPad, Mac, Apple TV, and more.
Xcode is an IDE, an Integrated Development Environment, which essentially means that Xcode includes many additional tools for development. A few examples are: a debugger, source control, device management, iPhone Simulator, profiling tools, Interface Builder, documentation, and much more.
Minimum system requirements for Xcode:
Xcode only runs on macOS, which means you need a Mac if you want to build iOS apps with Xcode. Xcode won’t run on iPad. A few alternatives for Windows/PC are available, but they’re far from ideal.
The next step in this tutorial, is installing Xcode. Let’s get to it!
Quick Tip: You can find the max. latest version of Xcode that your Mac can run, by cross-referencing the min macOS to run in this wiki with Hardware compatibility in this wiki. With this approach, you can also figure out for which iOS versions you’ll be able to build.
†: Xcode takes up a lot of storage, but the basic install is 8 GB. On top of that, Xcode will store SDKs, debug symbols, “derived data”, iPhone Simulator files, and more.
It’s easiest to download and install Xcode via the Mac App Store. Here’s how:
You can also install older versions of Xcode. This is especially helpful if your Mac isn’t supported by Xcode. Here’s how you do that:
Quick Tip: Don’t want to use the App Store app? Check out mas-cli/mas, a command-line interface for the Mac App Store. You can search, install and update apps – from the Mac App Store – via the Terminal command line!
Xcode is upgraded once a year, around Sept-Oct, at the same time the new major version of iOS is released. Every update of Xcode brings improvements, new features, bug fixes, and access to the latest SDKs. Throughout the year, a number of smaller updates to Xcode are made, including updates for Swift.
A notable newcomer in Xcode is SwiftUI. With SwiftUI, you can declare the User Interfaces (UIs) of your iOS apps, and their behavior. It’s the new way to build UIs – and it changes how we think about building User Interfaces for iOS apps.
An exciting aspect of SwiftUI is that you can use Swift programming to build User Interfaces. Here’s a quick example:
struct ContentView: View {
var body: some View {
Text("Hello worl!")
}
}
The above code declares a view, which will put that well-known Hello worl! text on screen. Up to this point, you’d create a Storyboard-based view controller to show anything on screen in your iOS app. You can build those view controllers with Interface Builder (see below).
Coding a UI with code is novel and exciting, but it’s also slated to be more productive. On top of that, you can now commit UI code with Git — without merge conflicts — and that wasn’t possible before.
SwiftUI is new, and although it’s publicly released as production software, it’ll need to go through an adoption phase before becoming the new defacto standard to build UIs. It’s likely that SwiftUI will see an adoption curve similar to Swift in 2014, i.e. slow but steady growth.
Until SwiftUI takes over Storyboard-based UIs, it’s important to learn to work with view controllers and storyboards, as well as with SwiftUI. Moreover, SwiftUI integrates well with existing UIKit-based views and libraries, which means that UIKit-based views remain relevant for considerable time. It’s smart to learn both approaches.
We’ve got plenty of tutorials about both:
Let’s take a look at Xcode! First, make sure you’ve started Xcode on your Mac. You’re greeted with Xcode’s Welcome Screen:
Here’s what you can choose to do:
Next, when you open an iOS app project in Xcode, you see something like this:
Let’s go over the Xcode UI one by one. First, we’ve got 4 major areas in Xcode:
Xcode’s UI also has a few other useful bits and bobs, such as:
Next up in this tutorial, we’re going to look at a few parts of Xcode in more detail…
This tutorial is chock-full of jargon and specific words for specific things in Xcode. I’ve tried my best to name things with their right names, but don’t think for a second that you need to say “Project Navigator” when you really want to say “file browser” or “that file thing on the left”. Life’s too short for matching socks! You make your own damn rules.
One of the major tools within Xcode is Interface Builder. As its name implies, you use Interface Builder to create User Interfaces for your apps. You create storyboards, connect them with view controllers, and that forms the basis of your app’s User Interface.
Let’s take a look around Interface Builder!
Interface Builder might seem daunting at first, but it’s a simple program considering how powerful it is. We’ve got 3 things you can do with “IB”: build UIs, inspect UI elements, and make adjustments to UI elements.
The Interface Builder UI consists of 3 major areas:
Let’s take a look at those Inspectors. You’ve got 7 of ’em:
You could separate these 7 inspectors into 2 groups, namely:
In the above screenshot, you also see a few miscellaneous items:
Let’s move on to a more hands-on part of this tutorial, namely, how to run your own apps on your iPhone and in iPhone Simulator!
Interface Builder used to be a separate app that you’d run next to Xcode, and I now regard it as a separate app within Xcode. The same goes for Instruments, which is in fact still a separate app…
If you don’t have an iPhone or iPad, iPhone Simulator is the next best thing. It’s an iPhone that you can run on your Mac, right from within Xcode. iPhone Simulator launches quite fast, so it’s ideal for the continual code-and-run development workflow.
Here’s how you run your app in iPhone Simulator:
Xcode will now compile and build your app, install it in iPhone Simulator, and launch the app. You can now use your app inside iPhone Simulator, as if it were a real iPhone!
You can use the mouse to interact with your app, but there’s a few things you should know:
iPhone Simulator has a few useful features, including:
Let’s move on, and figure out how you can run your app on an actual iPhone!
Pro tip: If you’re building an app for production use, don’t merely test your app with iPhone Simulator! Test it on a real iPhone too. It’s a simulator, not an emulator, so there are slight differences, such as performance, timing and architecture (i386 vs. ARM).
Run Your App on Your iPhone/iPad
Running your app on an iPhone is done in the same way as launching it on iPhone Simulator, essentially. You’ll need to take some steps prior, but after that, here’s how you launch your app:
Before you can use your iPhone to debug your app, you’ll need to create a free Apple Developer account. Since Xcode 7, you can sideload your own apps without a paid developer account. All you need is an Apple ID! This tutorial explains exactly how to do that.
If you’ve never used your iPhone with Xcode before, you’ll need to enable it for development. Doing so is simple:
Every time you update your iPhone to a new iOS version, Xcode will need to download so-called debug symbols from your iPhone. When this happens, you’ll see a notice in Xcode’s status bar. These symbols are needed to symbolicate crash reports. Debug symbols can accumulate quite some gigabytes of storage, so if you want to remove them occasionally, check out the ~/Library/Developer/Xcode/DerivedData/ folder on your Mac.
What about coding Swift with Xcode? That’s what we’ll cover next in this tutorial. We’re going to write some Swift code and work with Interface Builder.
Here’s what we’re going to build:
Let’s get started! We’re going to create a new project in Xcode. First, make sure you’ve started Xcode, and then do this:
Great! Your Xcode project has been created. You’ll now see the Build Settings screen in Xcode, which we’ll discuss later on in this tutorial. Let’s build something first.
Open the Main.storyboard file. Interface Builder appears. You’re looking at a view controller. We’re going to add a label to this “VC”. Here’s how:
OK, now reposition the label so it’s right in the center of the view controller. Then, double-click the label to change it’s text. I’m personally not a fan of “Hello, world!” — so pick a text that you like. Some ideas:
Nice! We’re now going to add a button to the view controller. Here’s how:
Next, reposition the label so it’s centered right below the label. Double-click the button and change it’s title to something like “OK!”
Are you familiar with constraints already? Feel free to add Horizontally in Container and Vertically in Container constraints to the label, and Horizontal Centers to the button and label (select both first!), and a Top margin of 8 to the button. Use the Pin and Alignment buttons at Xcode’s bottom-right. Neat-o!
The next step in this tutorial is writing some Swift code. We’re going to bring the label and button to life, so to speak.
First, make sure to open the ViewController.swift file in Xcode. This file includes a class, called ViewController, which is connected to the view controller in the Storyboard — the one we edited just now. We’re going to add an outlet and an action to this view controller.
At the top of the class, inside the first opening squiggly bracket {, add the following code:
@IBOutlet weak var textLabel:UILabel?
This is an outlet property. When we connect it to the storyboard later on, we can change the text inside the label with Swift code. That’s what an outlet is for.
You can designate a property with the @IBOutlet keyword to make it an outlet. Keep in mind that the UI element you want to connect to, and the type of the property need to be the same. In this case, that’s UILabel. (The property is an optional, which is an important concept in Swift.)
OK, next up, add the following function to the class:
@IBAction func onButtonTap()
{
let titles = [
"My hovercraft is full of eels!",
"BOOYAH!",
"Elvis has left the building"
]
textLabel?.text = titles.randomElement()
}
Where do you add this function? Make sure to add it inside the ViewController class, so within its squiggly brackets { }. Also, add the function below the viewDidLoad() function, but not within it. Use the screenshot below to check your work.
What’s going on in that onButtonTap() function? Here’s what:
OK, let’s connect that outlet and action now. First, switch to Main.storyboard in Xcode. Interface Builder opens, once again.
Do this next:
You’ll now see something like the screenshot below. Note the two items – the outlet and the action – in the Connections Inspector, textLabel and onButtonTap. Also note the tiny circles next to all these items, in the inspector. We’re going to connect them to the UI, next.
First, we’re going to connect the textLabel outlet property to the label UI element. This will create the outlet connection. Here’s what you do:
Next, we’re going to do the same thing for the action. Here’s how:
The Touch Up Inside item corresponds to a button tap, so it’s crucial to select that item.
You’re now ready to run your app. First, make sure to select the iPhone Simulator in the top-left of Xcode, and then click the Run button or press Command + R. Your app launches on iPhone Simulator. What happens when you click the button? Did it work OK? Awesome!
What if you don’t want to build an app? Don’t worry! You can code plain Swift with Xcode too. You’ve got 2 alternatives for doing so:
Swift Playgrounds is an app for iPad and macOS that teaches you how to code Swift in a playful, hands-on manner.
You complete all sorts of challenges, learning about functions, loops, conditionals, and more. You can also connect sensors, LEGO and drones to the app, and use them to play and code. And Swift Playgrounds is not just for kids!
Another approach is creating a playground in Xcode. A playground is essentially a Swift file, with a few helpful tools for coding. Why don’t you give it a try?
You’re now presented with an empty Swift file, with some default code.
You can code anything you want in this file. It’s perfect for doodling around with some Swift code, or practicing with syntax, or writing a simple algorithm.
Here, copy-and-paste the following snippet into the editor:
func fibonacci(_ i: Int) -> Int {
if i <= 2 {
return 1
} else {
return fibonacci(i - 1) + fibonacci(i - 2)
}
}
let numbers = Array(1...13).map { fibonacci($0) } print(numbers)
Then, click the Play button at the bottom-left of the editor. The Swift code is compiled and run, and its output appears in the Console below the editor.
The above code recursively calculates a number from the Fibonacci sequence. We’ve defined a function fibonacci(_:), which will return the Fibonacci number based on the index number i. It uses recusion; the function calls itself to return the right result.
Creating a playground in Xcode is perfect for playing a round with Swift code, without the “overhead” of an iOS app project. It’s a great approach to learn more about Swift programming.
Want to learn more? I’ve written a few tutorials that are ideal for playing around with Xcode playgrounds:
The above algorithm we’ve used to calculate Fibonacci numbers is a pure approach, but it’s not efficient. It’ll calculate previous Fibonacci numbers for every iteration of the for loop (“backwards”), even though those numbers don’t change between iterations. A forward algorithm would be more efficient, although it won’t be able to randomly access any number (index) in the sequence. I’ve explained more about the efficiency of programming algorithms in this tutorial: A Beginner’s Guide To Big O Notation
Let’s move onto more serious matters in this tutorial: debugging.
When you’re coding an app, you can expect to spend a fair chunk of time on finding and fixing bugs. What tools does Xcode have to make debugging easier?
Let’s look at a few of these tools one by one.
What’s going on here?
I often call debugging with print() poor man’s debugging, because it’s free and easy. Xcode has a ton of other debugging tools, such as breakpoints, so don’t miss out on those! It’s OK to debug by peppering your code with print() statements, too.
Next up, breakpoints. Here’s how you set them:
A blue arrow appears! You’ve now set a breakpoint on that line. Next time your app runs, and the code hits that line, execution will halt, and you can inspect your app at that exact spot in the code!
In the above screenshot, you can see what happens when a breakpoint is hit. In the left part of the Debug Area, you see the Variables View. It’ll show us the exact values of variables at the breakpoint in the code. You can clearly see variables like article, realm and response. You see those same variables in the code.
On the right, you see the Console. You can actually use the Console as a command-line interface (CLI), i.e. you can type commands and send those to the iPhone/Simulator. In the above screenshot, I’ve used the po command to print out the value of article.title. It’s similar to using print(), except it’s at runtime — which is pretty cool!
On top of the Debug Area you see a bunch of buttons. The outlined buttons (see screenshot) are steppers. You can use them to step through the code. When a breakpoint is hit, you can use the steppers to step in, step over or step out of the code. The most simple one is step over, which will advance the app’s code by one line. You can literally step through the code line by line! If you want to resume normal execution of the app again, click the Play/Resume button next to the steppers.
You can change an app’s breakpoints, i.e. enable/disable them, while your app runs. The next time your code hits a new breakpoint, it’ll halt execution. Want to learn more? Check out this tutorial: Getting Started With Debugging In Xcode
Xcode includes documentation, and documentation tools, right within the IDE. We’ve already seen the Quick Help Inspector in this tutorial, but there’s more!
Let’s take a look at how Xcode helps you document your own code. In the screenshot below, I’ve annotated a Swift function with the following comment block:
/**
This function returns an array of fake articles.
- Returns: An array of fake `Article` objects
*/
Xcode recognizes this function comment – often called a doc block – and understands that I’ve documented what the function does, and what it returns. When you hold the Option key and click on a function, it’ll show a popout window with the available documentation for that function. Like this:
You can use Option-click with any kind of symbol, i.e. functions, types, variables, classes, properties, protocols, etcetera. And it also works for Apple-provided SDKs, APIs and code! Like this:
What if you need in-depth information about a technique, approach or framework? Apple’s Developer Documentation is built into Xcode, so you’ve always got that right at your fingertips.
You can access the Developer Documentation in Xcode like this:
When the docs have opened, you can use the search bar at the top to find what you’re looking for. You can also use the list on the left, which includes tutorial-style guides about various topics. This is quite useful if you’re looking for a general direction, and not for a specific class or function.
Xcode’s documentation can be made available offline, via Xcode’s preferences. You can also find the Developer Documentation online, via developer.apple.com/documentation. A great alternative to Xcode’s built-in documentation is Dash, which organizes your developer docs in one useful tool, and it’s offline.
We’ll continue this tutorial with a few smaller areas of Xcode worth pointing out. The first one is the Organizer, and it’s cousin Devices & Simulators. You can reach both via the Window menu in Xcode.
In the above screenshot, you see the Organizer panel. On the left you see a few apps. At this point, we could distribute the 1.0 version of that app to the App Store by clicking the Distribute App button. Neat!
You can archive apps for distribution, like this:
In the above screenshot, you see the Devices & Simulators panel. With this specific panel, you can create new iPhone Simulator devices.
Imagine, for example, that you want to test your app specifically on the older iPhone 4S device. You can create a Simulator that simulates that specific device, including a specific iOS version. That’s super helpful for testing and debugging specific iOS versions and device models.
An important aspect of an Xcode project are its Build Settings. They include settings that determine how a project is built, such as the certificate that’s used to sign an app for distribution to the App Store.
You can reach a project’s Build Settings by clicking on the project’s name at the top of the Project Navigator in Xcode. Then, take a look at the list on the left (see screenshot). You see both a project and a target, and both of them have settings.
A project can include multiple targets. A project has build settings, and every target can override these settings. You can see this by comparing the Build Settings tab for a project, and for a target.
Let’s take a look at a few aspects of the Build Settings for a target. First, make sure you’ve opened an Xcode project, then open its Build Settings, and click your project’s name below Targets, on the left.
Notice the tabs at the top. You’ve got a few of them:
It’s worth noting here that the majority of your work, when building an app, takes place in the General, Signing and Build Settings tabs. You generally edit the Info.plist file directly, via the Project Navigator.
The Build Settings also include an important setting, namely the Deployment Target. Here’s how that works:
See those $(…) strings in the Info.plist file? They’re placeholders, and they’re replaced when your app is compiled. Where do they come from? From the Build Settings! For example, $(PRODUCT_NAME) is a string that’s called Product Name in the Build Settings, which in turn usually contains the name of your app.
A recent addition to Xcode is the Swift Package Manager (SPM). In short, Swift Package Manager lets you add 3rd-party frameworks and libraries to your Xcode project. You can then use the code from those libraries in your own project, which can greatly improve your productivity.
Right now, you’ve got 3 so-called dependency managers at your disposal:
Let’s say you want to add an open-source library you found on GitHub to your own Xcode project, like SDWebImage. Here’s how you can add it to Xcode:
Easy-peasy, right? You can now use said library’s code in your own app project. Just use import [LibraryName], and get coding.
Swift Package Manager uses a principle called semantic versioning. It’s more like a “rule” for determining which versions of a library you want to include in your project.
One of the benefits of using a dependency manager is that you can automatically upgrade to newer versions of a library when they’re released. How do you avoid upgrading to a library version that’s incompatible with your project, for example, if they’ve made breaking changes? That’s where semantic versioning comes in.
Here’s the gist of it:
That said, you can generally upgrade patch versions without thinking about it. The update is backwards compatible! The same is true for minor version changes, although you want to test your integration to be sure. You shouldn’t update major versions without planning the upgrade carefully, because major version changes include breaking changes.
Take a look at the above screenshot. You’re seeing 2 libraries that have been included with Swift Package Manager. You can find ’em via Project Settings -> Swift Packages. But what about their versions?
You can clearly see that we’re on version 5.5.2 of SDWebImage, and that we want to upgrade automatically to new versions up to the next major versions. This means that Xcode will update to versions like 5.5.3 and 5.6.0, but not 6.0.0. Neat!
The Xcode app itself can be extended with plugins, called Xcode Source Extensions, and many developers have taken the opportunity to add useful features to Xcode. There’s a whole ecosystem around building iOS apps, with plenty of 3rd-party tools.
A few of my favorites are:
Pfew! We’ve come a long way exploring Xcode in this tutorial. Here’s what we discussed: