Must-Watch Sessions From WWDC ’23
Ensure you’re up-to-date on the most important announcements from WWDC ’23 with this round-up of important sessions for developers to watch! By Audrey Tam.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Must-Watch Sessions From WWDC ’23
15 mins
Another WWDC has come and gone, and there are so many important and compelling session videos yet to watch! Or at least scan.
There are sessions on our most important tools: Swift, Xcode and SwiftUI. The new Observable
and SwiftData
frameworks will revolutionize how your apps handle data. Accessibility and localization got some notable improvements. And, of course, everyone’s excited about Vision Pro and using visionOS in everything.
Kodeco Team members nominated a few other topics as favorites: Widgets, Swift OpenAPI Generator, Push notifications console and Swift-DocC.
Here’s a roundup of the most important videos from WWDC ’23. Watch them to ensure that you’re up-to-date with Apple’s most important changes this year!
Swift, Xcode & SwiftUI
It’s always worth scanning the What’s new sessions. Even if you don’t start using all the new things right away, you’ll be aware of what’s there, and you’ll know what everyone else is talking about on social media.
Swift
First up, What’s new in Swift.
The Chapters links make it easy to jump straight to whatever sounds interesting:
You can get a quick overview of the updates by scrolling through the code snippets:
Tap directly into the video, and the transcript scrolls to match:
And you can search the transcript for specific terms, then jump right into the video or check out the code.
Macros are the big news in Swift, and they underpin the big news in SwiftUI and SwiftData. Here are two sessions to get you started:
Also take a look at the macro repositories from Doug Gregor and Krzysztof Zabłocki.
Xcode
Next, What’s new in Xcode 15 — your favorite IDE gets easier to use every year, with loads of productivity enhancements like intelligent code completion, previews, test navigator and test reports, improved navigation, source control and debugging.
For example, read this SwiftLee article about the new Xcode bookmarks:
I can feel my workflow shrinking already!
And, whether you love or hate unit and UI tests, be sure to look at Fix failures faster with Xcode test reports to learn about failure patterns, UI automation explorer and UI test video recordings.
SwiftUI
SwiftUI keeps getting better and easier to use.
There are improvements to SwiftUI previews and new SwiftUI support for watchOS, MapKit
, Charts
and StoreKit
, but the big news here is the new Observation
framework described in the Simplified data flow chapter and in more detail in Discover Observation in SwiftUI.
We’re back to just three property wrappers: @State
, @Environment
and the new @Bindable
— a lightweight wrapper if you just need to create a binding to an @Observable
value — say, to display it in a text field so the user can edit it.
Observable TIL
I’ll quickly walk you through converting the Combine-based ObservableObject
protocol to @Observable
in a very simple app.
Click Download materials at the top or bottom of this article to download the starter project. Open it in Xcode 15 beta. It would work in Xcode 14, but I’ve already set its iOS deployment target and minimum deployment to 17.0.
TIL is simpler than Apple’s FoodTruck app — it just lets the user add acronyms, which it displays in a list. Refresh the ContentView
preview and add a couple of acronyms to see how it works.
In ThingStore, change:
final class ThingStore: ObservableObject {
@Published var things: [Thing] = []
}
to this:
@Observable class ThingStore {
var things: [Thing] = []
}
ObservableObject
becomes @Observable
, and any public properties will be published. You can mark an accessible property @ObservationIgnored
if you don’t want it to be observed.
final
keyword is optional when making a class observable.
TIL doesn’t let the user edit an acronym after it’s created, so Thing
doesn’t need to be @Observable
, and it can remain a struct
.
In AddThingView, change:
@ObservedObject var someThings: ThingStore
to this:
let someThings: ThingStore
In ContentView, change:
@StateObject private var myThings = ThingStore()
to this:
let myThings = ThingStore()
You no longer need @ObservedObject
or @StateObject
. When AddThingView
updates someThings.things
, ContentView
will automatically update because myThings
is observable, and ContentView
reads its things
array.
Refresh the preview, then add a few acronyms to see the app works the same as before, but now with a little bit less code.
Now, build and run the app in a simulator. Add a couple of acronyms, then stop the running app in Xcode. Reopen the app in the simulator: No Thing
s, no surprise. The app has no persistence code.
SwiftData
No need to mess around with writing and reading plists or files — or worse, grapple with un-Swifty Core Data: Meet SwiftData! Start with this session, then dive deeper with these:
-
Model your schema with SwiftData: Use
@Attribute
to customize properties, set up@Relationship
s with other@Model
s, exclude properties from your data model with@Transient
and, when the time comes, migrate from one version of your schema to the next. - Build an app with SwiftData: Work with a multi-platform SwiftUI app to convert existing model classes and update the UI with model layer changes. Also, learn how to use SwiftData in document-based apps.
-
Dive deeper into SwiftData: Learn about
ModelContext
,ModelContainer
,FetchDescriptor
,SortDescriptor
and enumerate.
And, if your apps already use Core Data, take a look at Migrate to SwiftData to learn how to switch to SwiftData or add it alongside your Core Data code.
TIL With SwiftData
And now, to convert TIL to use SwiftData. Continue with the Observable
version of TIL.
In TilApp, import SwiftData
import SwiftData
Then add this modifier to WindowGroup
:
.modelContainer(for: Thing.self)
You create a model container for the Thing
model type. You can also pass an array of model types as the for
parameter, to store more than one type. Creating a container also sets a model context in the environment for this container.
In ThingStore, import SwiftData
then replace Thing
with this:
@Model
class Thing {
// let id = UUID() // be sure to delete this!
let short: String
let long: String
let alt: String
init(short: String, long: String, alt: String) {
self.short = short
self.long = long
self.alt = alt
}
}
Like @Observable
, @Model
is a macro. It converts a class into a stored model managed by SwiftData.
You definitely don’t want the id
property anymore. It confuses the model and produces wildly incorrect results. And, now that Thing
is a class, you need an initializer, even if you assign default values to all the properties. The @Model
macro requires an init
method.
Comment out ThingStore
: The container and context take care of everything.
In ContentView, import SwiftData
then replace this property:
let myThings = ThingStore()
with these two lines:
@Environment(\.modelContext) private var modelContext
@Query private var myThings: [Thing]
You bring in the model context and set up a simple query to fetch the array of Thing
s.
Fix the error messages about myThings.things
by deleting .things
from myThings.things
:
if myThings.isEmpty {
And
ForEach(myThings) { thing in
In the sheet(isPresented:)
closure, delete the someThings
argument:
AddThingView()
You don’t have a ThingStore
anymore, and you don’t have to pass anything to AddThingView
.
In AddThingView, replace this line:
let somethings: ThingStore
With this:
@Environment(\.modelContext) private var modelContext
You bring in the model context here, too.
And, in the Done button’s closure, replace:
someThings.things.append(Thing(short: short, long: long, alt: alt))
With model context code:
let newThing = Thing(short: short, long: long, alt: alt)
modelContext.insert(newThing)
In #Preview
, delete the someThings
argument.
Now, back in ContentView, add this modifier in #Preview
:
ContentView()
.modelContainer(for: Thing.self, inMemory: true)
Refresh the preview and add a few acronyms to see the app works the same as before. Now, for the magic: Build and run in a simulator, add a few Thing
s, then stop the running app in Xcode. Reopen the app in the simulator to see your Thing
s are still there!