FREE TRIAL: Accelerate your app development career with Hacking with Swift+! >>

What’s new in Xcode 13?

Vim keybindings, integrated collaboration, faster version comparison, and more.

Paul Hudson       @twostraws

Xcode 13 arrived at WWDC21 and includes a huge range of new features, improvements, and performance enhancements. In this article I’m going to walk you through all the key changes, so you can get up to speed quickly, but before I start I need to make two things clear:

First, no, I don’t have beta access to Xcode Cloud or the new Swift Playgrounds. Trust me, I wish I did! Both of these things look likely to be significant upgrades for the Swift community, and I’m really keen to try them out at the earliest opportunity.

And second, you might immediately note that Xcode hides your file extensions by default in the project navigator. This seems to mimic your Finder configuration, so if you’re suddenly confused where your file extensions have gone then you can bring them back With This One Weird Tip: go to Xcode’s preferences, select General, then change File Extensions to Show All. I’m going to try sticking with hidden extensions to see how I get on with it.

Anyway, in this article I’ll be talking about the new workflow tools for teams, the new source control features, the new improvements to how we write code, and more – it’s a packed release, so let’s get straight to it.

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Get started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Source editor improvements

First let’s talk about the source editor, which is where we spend most of our time – this is just the way we type code into Xcode, as opposed to all the main IDE features around it.

When I posted about some of these on Twitter, a bunch of folks replied back saying how Xcode sucks because their personal favorite IDE had these features years ago, and honestly just please pass me by with those kinds of comments – if I wanted to use your IDE I would already be doing so.

So, let’s talk about some major changes to the way we write code in Xcode.

First, if you use a type that isn’t currently available, Xcode can automatically import it for you. So, if you write code like this:

struct ExampleView: View

…then Xcode will detect that View belongs to the SwiftUI framework, and when you use code completion it will also bring in import SwiftUI.

Tip: This will only work with protocols that are already imported somewhere else in your project – it won’t read all types in unrelated protocols.

Second, Xcode now detects when you’re trying to unwrap an optional, and completes it for you. Try it with code like this:

struct UserGreeting {
    func greet(name: String?) {
        if let na
    }
}

As you’re writing if let na Xcode will offer the correct completion: if let name = name.

Third, Xcode is now able to offer deeper autocomplete options by including properties inside properties. Try it with code like this:

class ExampleVC: UIViewController {
    override func viewDidLoad() {
        let someText = UILabel()
        view.corn
        view.addSubview(someText)
    }
}

As you’re typing view.corn Xcode will offer view.layer.cornerRadius as a completion – it has looked inside the layer property and hoisted its completion options up one level.

Fourth, Xcode now autocompletes all enum cases when you’re using switch. Try it out with code like this:

struct PaintMixer {
    enum Color {
        case red, green, blue, tartan
    }

    func handle(color: Color) {
        switch col
    }
}

As you’re typing switch col Xcode will offer to complete the rest of color, but also fill in all the possible cases it can use.

Fifth, when you loop over an array, Xcode will automatically complete using a singular version of the array name. Try it out with code like this:

struct NamePrinter {
    let names = ["Becca", "Holly", "Ted"]

    func printNames() {
        for nam
    }
}

As you’re typing for nam, Xcode will offer to complete the rest of the loop, producing for name in names – it figures out that names is plural, creates the singular version of it, and uses that.

If I had to guess, I’d say this feature was powered by machine learning of some sort because it’s able to understand all sorts of plurals – including irregular ones. Try these out, for example:

let indices = [1, 2, 3]
let people = ["Eric", "Maeve", "Otis"]
let millennia = [1000, 2000, 3000]
let geese = ["Golden", "Mother", "Untitled"]

Sixth is the ability to have Xcode tone back its source editor issue reports. These are obviously very important and I rely on them dozens of times every day, but sometimes you know exactly what the problem is and the just kind of get in the way – sometimes they actually interfere with what you’re trying to do.

Well, in Xcode 13 there’s a new way to show issues in your source editor called minimized mode. This still shows your code issues right next to your source code, but now collapses them down to a single icon on the right edge. Clicking that will bring up the same information and options you had before. If you’d like to try this new feature, go to Xcode’s preferences, choose the General tab, then change the Issues option from Show Inline to Show Minimized.

And seventh is the ability to place column breakpoints, which are – as you might imagine – breakpoints that happen at a precise part of a line of code, rather than breaking for the whole line.

As an example, we might have several functions being called together to produce a single value, like this:

func first() -> String { "A" }
func second() -> String { "B" }
func third() -> String { "C" }

func buildString() -> String {
    first() + second() + third()
}

If we place a breakpoint on that single line inside buildString(), we need to step into each one of the functions individually to figure out what’s going wrong. But if we already know roughly where the problem is, we can place a column breakpoint – we could ask Xcode to pause at exactly the point where second() is called, for example.

To try this out in the code above, select second() then press Shift+Cmd+A to bring up the code actions – or right-click then select Show Code Actions. In that menu you’ll see Set Column Breakpoint, which will insert a small, vertical breakpoint exactly there.

These column breakpoints work exactly like regular line breakpoints, so you can click and drag them away to remove, or right-click and select Edit Breakpoint to add customization.

And then there’s Vim mode

The last major change to Xcode’s source editor deserves some special focus because it’s going to make a lot of people happy – and also make a lot of other people unable to quit!

That feature is Vim key bindings, and you can enable it under Xcode’s preferences – go to the Text Editing tab and check the Enable Vim Key Bindings box.

If you haven’t use Vim before, it’s a command-line text editor that started out back in 1976 as Vi, and become “Vi Improved” (just Vim for short) in 1991. Vim has a very particular way of working that requires careful knowledge of the keyboard, and at last you can now use much of that knowledge in Xcode too.

I say “much” because only a subset of Vim’s keybindings are supported: navigation, insertion, yanking, searching, and so on are all there, but relative line numbers, repeating operations, saving a file with :w doesn’t work, and more. However, it’s a great start, and I’m sure more will come.

Fun fact: The first person to file feedback asking for Vim support in Xcode did so back in 2004, back in the Xcode 1 days!

Let’s talk about version control

Xcode has had integrated version control for a very long time, but this year it’s getting its biggest upgrade ever – it’s now much easier to compare changes between any two versions, you can open pull requests in Xcode and invite reviewers, and even handle code review right inside the IDE.

Tip: You need to have Xcode’s source control features turned on this to work. If you previously disabled them, go to Preferences > Source Control and check the Enable Source Control box before continuing.

To demonstrate the new features, start by opening up any project that has some interesting version control history. For example, I might use Unwrap, my free app for learning Swift.

With this open, you’ll notice Xcode immediately shows you current branch right in its title bar, next to the Play button – I see “Unwrap” and “main”, for example. If you want to change to a new branch, click that and select something else, or press the detail dots next to your current branch and make a new branch from there.

Now just go ahead and make changes like you normally would, and if you Xcode’s “Show Source Control Changes” option selected you’ll see your new lines get marked with a blue edge. When you’re ready, go to View > Show Code Review to see exactly what changed, but this is where things get more interesting:

  • In the source control navigator there’s a new Changes tab where you can flick through all your local changes quickly.
  • The new bottom bar updates to show how many changes there and, and provides arrows so you can navigate between them.
  • Also in the bottom bar are controls to select what you’re comparing – Uncommitted Changes and Last Commit are the default, but you can change either of those however you want.

These version buttons have a color scheme that you’ll get used to: if it’s black it means it’s your last commit, if it’s purple it means it’s a newer commit, and if it’s orange it’s an older commit. These same colors are also used in the source editor to highlight the changes.

Tip: If you’re busy exploring older changes this way, press Reset to get back to the default view.

Once you’ve checked your work, commit the change as you normally would by going to Source Control > Commit and adding a meaningful commit message, optionally also pushing it to the remote repository.

And now you can make a pull request: click your branch name in the title bar and select Create Pull Request. Give it a title and a description, and even add any reviewers you want by clicking the person icon next to Publish.

Comments are shown in Xcode, and you can view changes there too. Right-click on a review you're doing and insert a comment.

Checking performance and crashes

Xcode’s organizer is a great way to identify problems in your code – it’s not new, but you can go there to see your crashes, slow disk writes, extensive memory usage, and more. This year they added support for spotting termination – when your code goes bang – and for regressions, in case you ship an update with significantly worse metrics than before.

But the most impressive feature is that Apple has said now crash reports from TestFlight users will appear the Organizer window within just a few minutes of happening, along with whatever feedback your user submitted. This is going to be huge for when someone tells you directly about a problem on Twitter or Slack, because you can immediately see the crash, see what code caused the crash, and ask them what they were up to.

Custom documentation with DocC

Xcode 13 now has the ability to create documentation sets straight from our code. It reads all the Markdown comments you add, and builds them right into Xcode’s default help system using exactly the same layout and formatting as Apple’s own frameworks.

This is such a big feature that I think it deserves it’s own dedicated article – watch this space.

And there’s more…

There are still more new features introduced in Xcode 13, including support for Swift package collections, cloud signing, and new accessibility controls and overrides, and this is still only beta 1 – it’s going to be a few more months until the final version is ready, and I’m excited to see how it continues to be refined.

What’s your favorite feature of Xcode 13? Let me know on Twitter @twostraws!

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Get started

Sponsor Hacking with Swift and reach the world's largest Swift community!

BUY OUR BOOKS
Buy Pro Swift Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift (Vapor Edition) Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Server-Side Swift (Kitura Edition) Buy Beyond Code

About the author

Paul Hudson is the creator of Hacking with Swift, the most comprehensive series of Swift books in the world. He's also the editor of Swift Developer News, the maintainer of the Swift Knowledge Base, and a speaker at Swift events around the world. If you're curious you can learn more here.

Was this page useful? Let us know!

Average rating: 5.0/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.