Streaming is available in most browsers,
and in the Developer app.
-
What’s new in Xcode 15
Discover the latest productivity and performance improvements in Xcode 15. Explore enhancements to code completion and Xcode Previews, learn about the test navigator and test report, and find out more about the streamlined distribution process. We'll also highlight improved navigation, source control management, and debugging.
Chapters
- 0:00 - Introduction
- 0:39 - Downloading Xcode
- 1:29 - Code completion updates
- 3:45 - What's new in asset catalogs
- 4:30 - Meet string catalogs
- 5:25 - What's new in Swift-DocC
- 7:01 - Meet Swift macros
- 8:40 - What's new in Previews
- 10:00 - The bookmark navigator
- 12:18 - What's new in source control
- 14:50 - What's new in testing
- 17:23 - Updates in the debug console
- 18:37 - Updates in Xcode Cloud distribution
- 19:37 - Signature verification and privacy manifests
- 21:03 - What's new in Xcode distribution
Resources
Related Videos
WWDC23
- Build programmatic UI with Xcode Previews
- Create rich documentation with Swift-DocC
- Debug with structured logging
- Discover String Catalogs
- Expand on Swift macros
- Fix failures faster with Xcode test reports
- Get started with privacy manifests
- Simplify distribution in Xcode and Xcode Cloud
- Verify app dependencies with digital signatures
- Write Swift macros
-
Download
♪ Mellow instrumental hip-hop ♪ ♪ Shilpa Chirackel: Hello, my name is Shilpa. Ryan Golbeck: And I'm Ryan. Shilpa: Today, we're very excited to show you everything we've been working on in Xcode 15. Ryan: Xcode is the center of your development experience. In Xcode, we pull together all aspects of your development workflow into one place, making it easy and fun to build apps while keeping you focused in a single tool. Today we will touch on many of the improvements this year with Xcode 15, starting with editing, navigating, and sharing, through to testing, debugging, and distributing your app. Shilpa: Before showing you what's new in Xcode, we need to download it. And the best way to get the released versions of Xcode is from the Mac App Store. This guarantees you will always use the newest version of the tools and can take advantage of the latest features. Last year, we made it easier to get started by making the watch and TV simulator optional downloads. This year, we're going even further by making all simulators downloadable, including iOS and Apple's new spatial computing platform, allowing you to configure Xcode to match your needs. Now, when you get Xcode, it will be smaller, making it easier to write code even before you get all the simulators. Alternatively, if you need to download Xcode from the Developer website, such as the latest beta, you can choose up front which simulators to include. Now that we've got Xcode, let's jump right in and see what's new in the source editor. Code completion helps you get to the code you want faster and with fewer mistakes. In Xcode 15, it gets a whole lot smarter. Let's take a look. Completions take advantage of new sources of information. Here I have Backyard Birds. I'll start by creating a new file and name it PlantSummaryRow. I'll add the required import statements. Now when I create a new struct, completion suggests PlantSummaryRow for the type name, and that's because that's the name of the file I created. Let me finish implementing this file.
I'm done with the implementation. The way some completions are presented has improved too. When you're calling a function that has default arguments, it can be challenging to get exactly the parameters you want. You can see all possible permutations of default arguments to help you pick the one you want. I'll add a frame modifier to this VStack and press the right arrow on the keyboard. I'll select the one I need, in this case width. And completions now have more context awareness, giving you even better suggestions for the code you're writing. Coming back to the VStack, when I type a dot to add a modifier, padding is the top suggestion because Xcode knows it's one of the most frequently used modifiers for this view. But when I add a modifier to a Text, I get font as the top suggestion. These editor suggestions also consider the surrounding code. I already changed the font on this text. When I want to add another modifier, the top suggestion is bold, as I wouldn't want to use the same modifier twice when working on text. Here's another example. In this file, I'm using CLLocation to find where my birds are. As I already typed in latitude, now it will suggest longitude, as these two properies are commonly paired together. All this means you'll have better top suggestions, leading you to type safer code faster. Hey Ryan, I heard that we're bringing the power completions to asset catalogs too. Can you tell me some more? Ryan: Sure, Shilpa. Color and image assets are now backed by Swift symbols. This means that they can now be code completed. In my asset catalog, I have some custom colors and images. Xcode 15 automatically generates symbols for each of them, and I can reference these in my code instead of using string names. If I change the name of this image to MultipleClouds and build my project, I get an issue in another file where we use this asset. And I can correct it using CodeComplete. These symbols give me type safety, so I don't have to worry about mysteriously missing colors or images at runtime. And Xcode 15 brings the power and flexibility of catalogs to your localization experience too. String catalogs pull together your localizations into a single place, giving you a centralized way to review and update them. To get started, you can convert a project to use string catalogs by selecting Edit > Convert to string catalog. This brings up a sheet showing all of the storyboards, .strings, and .stringsdict files that can be migrated. And once migrated, all of your translations are organized into a single editor. In the sidebar on the left, you can review the translation progress for each of the languages that you support. And keeping up to date is easy. All of the strings are pulled directly from source each time you build. When new strings are added or removed, the editor annotates the affected languages and badges the relevant strings. Get started migrating today by heading over to the session "Discover String Catalogs." Shilpa, what's new in Xcode for documentation this year? Shilpa: A lot. Clear, concise code is made even better with documentation. Whether you're explaining something to your future self or one of the consumers of your API, writing great documentation is key. And great documentation deserves great presentation. Xcode 15 has beautiful new styling and spacing, making documentation easier to read. But the biggest improvement is a new assistant that shows a real-time preview of your documentation. While crafting documentation, I can display the assistant by choosing Editor > Assistant > and then Documentation Preview in the jump bar. As I type in the source editor, the preview is updated in real time. This will show me exactly how my docs will look in a fully built documentation archive. I'll add a code example to show how it could be used in practice. I'll begin by writing "Use this initializer to display an image of a given bird." Then I'll paste in my code example. Since this example involves UI, I'll add a screenshot of what the resulting view would look like. I can reference the image named BirdIcon because I included it in my documentation catalog. The new documentation preview is a huge help to make sure your docs are presented exactly how you want. If you're passionate about writing documentation, like I am, watch the session "Create rich documentation with Swift-DocC" to learn more. Just as important as documentation is that your code should be concise and understandable. New in Swift this year is a powerful new language feature, Swift macros. Macros makes for more expressive APIs and helps eliminate repeated code. And Xcode's integration gives you complete visibility into macros, allowing you to treat macro-generated code like all other code in your app. Macros are part of the Swift packages in the SDK. Now we're utilizing the power of macros in a number of Apple's own frameworks, like Swift standard library, foundation, and the new Swift data framework. I can also create my own macro package to share with others. To create a package, I'm going to use quick actions, a new feature that lets me access all of Xcode's menu options just by pressing Command-Shift-A. The new macro package will come with great examples to get me started. I've already created a macro package, EnumHelper. Inside EnumHelper, I implemented CaseDetection as a macro. The beauty of macros is that they generate normal Swift code. It wraps up and neatly tucks away the code they provide. But when you want to see what a macro is doing or when you want to debug in macro-generated code, you can expand the macro right in line with the help from quick actions. You can even set a breakpoint on the code inside a macro if you need to debug it. Watch the session "Expand on Swift macros" to gain a deeper technical understanding of Swift macros. Equipped with this new knowledge, you can code along to write a few macros from scratch in the session "Write Swift macros." Let's explore another area of Xcode that's taking advantage of macros, previews. With the help of macros, the new Previews API is simple and easy to remember. I'll add a preview by typing #Preview. I want to preview the account screen. App detail column has various states, which I can show by creating another preview. I'm able to see both of these scenarios. But now I have two previews in UI. To tell them apart, I'll add a title, "Placeholder View".
But wait, there are more improvements. We're bringing previews to UIKit and AppKit. So even in my older Food Truck app, I can add a preview for my UIViewController and iterate as quickly as I have in SwiftUI. Now let's look at developing widgets with previews. The API also introduces new workflows for building time-based widgets.
The canvas has a new area that shows all of the entries. And as I navigate through them, I can see how the widget's transitions animate. Check out the session "Build programmatic UI with Xcode Previews" to learn how to adopt the new and exciting preview features in your project. I'll hand it back to Ryan to talk about the improvements in navigation. Ryan: Thanks, Shilpa. As your project grows, it becomes more complex, making it difficult to keep track of landmarks that you want to reference during a task. To help, Xcode 15 introduces the bookmarks navigator. I'll open it by clicking right next to the source control navigator. I've been adding bookmarks to places in my code that I need to add documentation. I want to add another one in this file, and it's easy to do. I'll just right-click on this location and select Bookmark.
The bookmark shows up in the navigator with a preview of its location, but I can change this display if I want by clicking it and entering a different description. Xcode annotates a line of code with my description, making it easy to see and remember what I want it to do. My list of bookmarks is starting to grow, but I can manage them by sorting and grouping them however I like. I want to group all of my documentation-related bookmarks together. I'll select the ones I'm interested in, and with a secondary click, open the context menu to select New Group From Selection. This creates a new group that I'll call Places to Add Documentation. Bookmarks are great reminders in my code, but they can also be used as to-do lists. I can mark one as complete by clicking to its left. Or I can delete it altogether by selecting Delete Bookmark in the context menu. This removes the bookmark annotation in the editor. Lines of code aren't the only thing I can bookmark, though. Bookmarks are also a great way to keep track of Find queries. Before Xcode 15, I've added to-dos in my code, but they are hard to find, so I've already bookmarked a query to find all of them.
But I can bookmark any Find query. I want to keep a handy list of all the view modifiers in my code. I'll use the new Conforming Types query to find all conformances to the viewModifier protocol.
Then, I can bookmark this query by right-clicking in the results and selecting Bookmark Find "viewModifier". My query is available in the bookmark navigator. If the results of my query ever change, I can refresh the list with just one click on the refresh button next to the bookmark. Xcode 15's new bookmark navigator keeps track of your work so you don't have to, keeping your focus on the task at hand. Another important part of development is sharing your work. Bringing your changes together, especially when crafting a commit to share with your colleagues, can be as important as the changes themselves. Xcode 15 introduces a new changes navigator and commit editor, which together are a great way to review all of your changes. I've been working on adding documentation to my project. I can review these changes in the source control navigator. The first thing you'll notice is an improved reporting and presentation of each file's status. My stage modifications show up as an icon next to the file name. I want to start reviewing these changes, so I'll click on the uncommitted changes item to bring up the commit editor. I can now review all of my modifications in a single scrolling view. Each section shows just enough context to understand the surrounding code. And If I want to see more, I can use the drag handle to expose more of the file. Each change is also presented in a source editor, giving me access to the annotations and controls that I'm used to. During my review, I notice that there's an issue in the BirdsNavigationStack file. It looks like I made a typo in my documentation, but I can fix this without leaving the view. Xcode processes my change and removes the issue. My edit is also immediately indicated as unstaged in the changes bar. The status indicator highlights that the BirdsNavigationStack now has both staged and unstaged changes. I want to include my fix in the next commit, so I'll stage it by clicking the changes bar next to the fix and selecting Stage Change. I also notice I've accidentally staged a log statement that I was using for debugging. I'll use the changes bar again to unstage this change. These staging controls are easy to use and they're integrated throughout Xcode. I'm ready to check in my changes. I'll start by adding a description in the commit message box, and then clicking the Commit button. Xcode creates my commit and opens it immediately in the commit viewer, summarizing what was included. And lastly, I can share my commit with my teammates. I'll click on the status indicator next to my commit, select Push, and follow the prompts. These source control features are a great improvement to keep you focused in Xcode 15. But hey, Shilpa, I think we have some new features that help with testing too. Can you tell us about those? Shilpa: Sure, Ryan, testing is an important part of shipping a high-quality app. It allows you to catch regressions quickly and maintain your app's quality as it grows in complexity. Testing gets some big improvements this year, starting with an updated test navigator, rewritten from the ground up in Swift to be more efficient. When running or reporting your test results in real time, Xcode is now 45 percent faster. The test navigator is organized around your test plan, making it easier to find the test you care about. You can also use filters to find tests based on any result type, such as expected failure. Once you run your test in Xcode or Xcode Cloud, the test reports help you explore the results, showing you where to focus next. It starts with a high-level summary of the entire test run. This includes Insights, a pattern-based analysis of the results. Within the Test section, you can understand how the test performed. It's easy to figure out how many tests passed and failed across different devices and configurations. Insights analyze test results to identify potentially related failures that might have been difficult to see before. It also alerts us to test runs that may cause the entire suite to take longer to return results.
The second insight sticks out to me. The test failed while attempting to tap the Account button. I want to investigate this further. From the overview, I can navigate to the test list, which shows all of the test runs, with filters for result type, run destination, and test plan configuration. I see the test failed to tap the Account button across multiple languages with the same error message. To learn more, I can look at the individual class or navigate to a new dedicated Test Details view for individual test methods. The Test Details view contains tabs for different ways of exploring the results data, including a breakdown of all runs and a dedicated performance metrics tab. Debugging UI test failures is more fun than ever with the new automation explorer. The explorer is interactive, so you can watch your test playback or can scrub through the timeline. Touch or mouse events are overlaid on the video. At the point of failure, like when my test failed to tap the Account button, I can inspect the UI hierarchy of my app. This will make fixing UI test failures a whole lot easier. For an in-depth study, watch the session "Fix failures faster with Xcode test reports" to learn more. Now back to Ryan so we can talk about debugging. Ryan: Testing and debugging go hand in hand. They are both about crafting a high-quality app. And debugging also gets some great improvements this year, starting with OSLog integration into Xcode. OSLog is a great tool for capturing runtime information. It provides a structured and customizable logging mechanism that keeps your log output organized. And Xcode 15's console introduces full support for OSLog, including the ability to perform complex filtering on log data, like subsystem category and severity. The presentation of the logs is cleaner than ever. The focus is on your log content, with extra data neatly hidden away. The background color of each log entry indicates its severity, making it easy to scan long streams of log output for critical messages. And while the metadata fields are hidden by default, they're just a couple of clicks away. You can choose just the fields you want to see. And when you're looking for something specific, the filter field lets you narrow your search. You can filter on the metadata or on the full text of the log. And a feature that I really like, you can jump from a log entry directly back to the line of code that created it. We do a deep dive into these logging features in the session "Debug with structured logging". Lastly, let's talk about distribution. Distribution is about getting your app out into the world, to your teammates, to your beta testers, and to your users. And Xcode 15 has some improvements to make this process easier and safer. Let's start with Xcode Cloud. Xcode Cloud is a great way to distribute your app. It manages things like build versioning, app signing, and the distribution profile for you automatically. This year, Xcode Cloud handles two more details for you. First, TestFlight test details. Xcode Cloud adds support for including test notes right alongside your source code. These will be automatically attached to the TestFlight build for distribution, and so the notes will appear to your testers right alongside your app. And secondly, Xcode Cloud now supports notarization for your Mac apps. All you need to do is add the notarization post action in your workflow, and Xcode Cloud will do the rest. When your build is complete, your app will be automatically notarized and stapled, and be ready to download. Notarizing your app is vital for your users. It lets them know that your app hasn't been tampered with. But it's just as important that you can trust the integrity of the SDKs and frameworks that you depend on. To provide this assurance, Xcode introduces signature verification for XCFrameworks. Authors can digitally sign the contents of their frameworks, and you can verify these signatures right in Xcode. The framework inspector has a new signature slice. It tells you exactly who produced and signed the framework. And Xcode will remember this identity. So if it ever changes when updating the framework, you get a clear warning about the problem, but there's more to it than that. Authors can now include a privacy manifest in their framework. This manifest details exactly how the framework uses and protects sensitive data. Since the privacy manifest is bundled with the framework, it is also part of the signed package, and you can trust that its contents came directly from the author. I can use Xcode to summarize all of the manifests into a complete privacy report for my app. Here's a report that I've generated. This report is designed to make it easy to fill in the privacy nutrition label in App Store Connect, making sure I provide accurate information to my users. And Apple is working with privacy-impacting SDKs to ensure that all of your critical dependencies provide this valuable information. We cover these topics in a lot more depth in the sessions "Verify app dependencies with digital signatures" and "Get started with privacy manifests". Privacy manifests are a great tool when distributing your app to your users. When you're working on a bug fix or a new feature branch, you want to distribute your app to your teammates and only your teammates. So Xcode 15 now supports the TestFlight internal testing distribution option. TestFlight internal builds are available to your team only, so you can never accidentally release them to customers. They're easy to create. Just select the "TestFlight internal testing" option when distributing your app through App Store Connect.
But it's actually even easier than this. Xcode now bundles a set of the most common distribution methods and recommended settings. Step one, select any of these new options, including TestFlight internal only. Step two, click Distribute and you're done. There is no step three. And if you're distributing through App Store Connect, you will also now get desktop notifications about your build status. So when your app is ready to test, you'll be notified right away. These updates make it easy to iterate and distribute your app quickly, which makes working closely with your teammates, testers, and users smooth and fast. Start exploring these features by having a look at the session "Simplify distribution with Xcode and Xcode Cloud". Well, that was a quick overview of what's new in Xcode 15. It is easier to get, faster to use, and has a ton of improvements to make your development more focused, smooth, and fun. Shilpa: Go download Xcode 15 so you can start trying out these cool new features. Thanks for watching. ♪
-
-
1:52 - Code Completion - PlantSummaryRow
import Foundation import SwiftUI import BackyardBirdsData import LayeredArtworkLibrary struct PlantSummaryRow: View { var plant: Plant var body: some View { VStack { ComposedPlant(plant: plant) .padding(4) .padding(.bottom, -20) .clipShape(.circle) .background(.fill.tertiary, in: .circle) .padding(.horizontal, 10) VStack { Text(plant.speciesName) } } } }
-
3:28 - Code Completion - Latitude & Longitude
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let mostRecent = locations.last?.coordinate { logger.debug("Handled coordinate update: \(mostRecent.latitude)") } }
-
6:18 - BirdIcon Documentation
/// Create the bird icon view. /// /// The bird icon view is a tailored version of the ``ComposedBird`` view. /// /// Use this initializer to display an image of a given bird. /// /// ```swift /// var bird: Bird /// /// var body: some View { /// HStack { /// BirdIcon(bird: bird) /// .frame(width: 60, height: 60) /// Text(bird.speciesName) /// } /// } /// ``` /// /// ![A screenshot of a view containing a bird icon with the bird's species name below it.](birdIcon)
-
7:37 - CaseDetection Macro
extension TokenSyntax { fileprivate var initialUppercased: String { let name = self.text guard let initial = name.first else { return name } return "\(initial.uppercased())\(name.dropFirst())" } } public struct CaseDetectionMacro: MemberMacro { public static func expansion< Declaration: DeclGroupSyntax, Context: MacroExpansionContext >( of node: AttributeSyntax, providingMembersOf declaration: Declaration, in context: Context ) throws -> [DeclSyntax] { declaration.memberBlock.members .compactMap { $0.decl.as(EnumCaseDeclSyntax.self) } .map { $0.elements.first!.identifier } .map { ($0, $0.initialUppercased) } .map { original, uppercased in """ var is\(raw: uppercased): Bool { if case .\(raw: original) = self { return true } return false } """ } } } @main struct EnumHelperPlugin: CompilerPlugin { let providingMacros: [Macro.Type] = [ CaseDetectionMacro.self, ] }
-
8:07 - Using CaseDetection Macro
@CaseDetection enum Element { case one case two } var element: Element = .one if element.isOne { // Handle interesting case }
-
8:50 - New Preview API
#Preview { AppDetailColumn(screen: .account) .backyardBirdsDataContainer() } #Preview("Placeholder View") { AppDetailColumn() .backyardBirdsDataContainer() }
-
9:22 - UIViewController Preview
#Preview { let controller = DetailedMapViewController() controller.mapView.camera = MKMapCamera( lookingAtCenter: CLLocation(latitude: 37.335_690, longitude: -122.013_330).coordinate, fromDistance: 0, pitch: 0, heading: 0 ) return controller }
-
17:34 - OSLog
import OSLog let logger = Logger(subsystem: "BackyardBirdsData", category: "Account") func login(password: String) -> Error? { var error: Error? = nil logger.info("Logging in user '\(username)'...") // ... if let error { logger.error("User '\(username)' failed to log in. Error: \(error)") } else { loggedIn = true logger.notice("User '\(username)' logged in successfully.") } return error }
-
-
Looking for something specific? Enter a topic above and jump straight to the good stuff.
An error occurred when submitting your query. Please check your Internet connection and try again.