WWDC 2025 deal: 30% off our Swift and SwiftUI books! Learn more ...WWDC 2025 deal:30% off our Swift and SwiftUI books >>

Nil Coalescing Newsletter - May 2025

Hi there,

It’s late May, which means WWDC is just around the corner. Like many in the Apple developer community, we are looking forward to the upcoming announcements and updates. This time of year always gets us thinking about what might be coming next. Whether it’s better tools for building SwiftUI apps or advances in lower-level frameworks like Metal, it’s always exciting to imagine what new capabilities we’ll be able to work with soon.

In this issue, I’ll share some of our WWDC wishes, along with a few tips for getting the most out of the online WWDC experience from my perspective. There is also an update on our new YouTube channel, and a quick round-up of recent blog posts.


Our WWDC wishes

One thing I’d really love to see this year is better support for text editing in SwiftUI, especially for rich text. At the moment, anything beyond plain text still requires falling back to UITextView or NSTextView, which brings in all the complexity of integrating UIKit or AppKit views into a SwiftUI layout. It would be great to have a modern, native API for building text editors, particularly on macOS and iPadOS, ideally built directly on top of TextKit.

I’m also hoping for more advanced and polished macOS-specific SwiftUI APIs. Window management still feels fairly limited, and it would be great to have more flexibility there. I’d also like to see improved support for menu bar utilities, including the ability to handle right-click menus for quick actions like quitting the app, and a simpler way to use custom icons in the menu bar and size them properly using SwiftUI.

Matt would like to see expanded support for custom component styling. At the moment, SwiftUI only exposes style protocols for a few components like buttons and toggles. It would be helpful to have public style protocols for all system components, including navigation views, lists, and tab views, so we can define complete custom styles across the entire interface.

He also has a few wishes for Metal. One of them is support for attaching mesh and fragment shader functions at runtime from within object and mesh shaders when writing out the payload. That would make it possible to build more dynamic pipelines, where a single object shader could generate multiple types of geometry like foliage, rocks, or terrain without relying on runtime branching in later stages. Another is the ability to define nested stencil buffer scopes. In pipelines that frequently update the stencil buffer, this would make the structure easier to manage and could allow the GPU to parallelize work more effectively.

Hopefully a few of these ideas make it in. We’re looking forward to finding out!


Getting the most out of WWDC online

Matt and I will be following WWDC online from New Zealand and diving into the new APIs as soon as they are available. While we hope to make it to Cupertino one day to experience WWDC in person, meet the community, and be part of the excitement on the ground, the online format still offers a lot. It really does feel like being part of a wider global developer community, and I thought I’d share a few tips that have helped me get the most out of it.

Watching the Keynote and the Platforms State of the Union live is always a highlight. If you are on social media, like X, Mastodon, Bluesky, or LinkedIn, it’s a great time to share your thoughts and see what others are posting. A lot of people who aren’t usually active show up just for WWDC, including Apple engineers. Many of them will be online sharing what they’ve worked on, now that the announcements are public, and keeping an eye on community reactions and feedback. So if you are trying things out, let others know what you are seeing and use the WWDC hashtags to follow along.

On day two, all the technical session videos drop. While it’s not possible to watch everything right away, it helps to prioritize the areas you care about most and watch a few key sessions early so you can start experimenting. That way, if you run into questions, you can book a one-on-one lab and get personalized help from Apple engineers.

This year, Apple is also offering group labs, which is new. We’ve already signed up for a few, and they look like another great way to ask questions and get answers directly from the people who built the APIs.

And if you come across any bugs while trying out new frameworks or tools, this is the best time to start filing feedback through Feedback Assistant. I know it can sometimes feel like the feedback goes nowhere, but it does get looked at, even if you don’t get a reply. It gets triaged and can count as a vote for prioritizing a fix. The early beta period is when fixes are most likely to happen, as Apple engineers are still actively working on stability before development picks up again for next year’s features. If you want to bring more attention to your feedback, you can also post about it on social media, include your Feedback Assistant number, and tag it with WWDC hashtags. Apple engineers do browse those channels, and you might be surprised by how often posts get noticed.

WWDC week always goes by quickly, but there is a lot to take in and try out. Whether you are following it live or catching up in the evenings, I hope it’s a fun and inspiring week for you too.


Nil Coalescing YouTube channel

We launched a YouTube channel this month, and I’m really excited about it. Making videos is something new for me, and it’s been a fun way to share ideas a little differently. So far, I’ve posted three videos covering topics like formatting data in SwiftUI Text views, understanding view value and identity in SwiftUI, and some lesser-known techniques for transforming Swift collections.

If you enjoy video content, I’d love for you to check them out! And don’t forget to subscribe to the channel so you don’t miss future uploads.

👉 Nil Coalescing on YouTube

Lesser-Known Techniques for Swift Collection Transformations

In this video, I share three concise techniques for transforming collections in Swift. You’ll see how to use comparison operators as function arguments, map with key paths, and accumulate values efficiently using reduce(into:). These approaches replace verbose closures with clearer, more expressive alternatives that are built into the language.

SwiftUI View Value vs View Identity Explained

Understanding the difference between view value and view identity in SwiftUI is essential for building apps with reliable state management and predictable behavior. In this video, we break down these two key concepts using simple, focused examples. We’ll look at how views update when state changes, what causes state to reset, and how SwiftUI tracks identity in the view hierarchy. You'll see how small changes in structure can affect view behavior, and how to design your views to avoid common pitfalls.

Formatting Data inside SwiftUI Text Views

In this video, I walk through how to format lists, measurements, and dates directly inside SwiftUI Text views using string interpolation. We’ll look at how to use the format and style parameters to present data clearly, concisely, and with full localization, without writing extra logic or manual conversions.


Tech Learnings

Trigger repeated updates with AsyncTimerSequence

For my demo project in the View Value vs View Identity video, I needed a simple way to update a SwiftUI view every second. I ended up using AsyncTimerSequence from the Swift Async Algorithms package, and it worked really well.

AsyncTimerSequence creates an asynchronous sequence that yields values at a fixed interval using a specified clock. We can loop over this sequence using for await inside a task(priority:_:) modifier, which makes it a great fit for SwiftUI. The task is automatically cancelled when the view is removed from the hierarchy, so there is no need to manage cleanup manually.

A good option to keep in mind when you want a lightweight timer in a SwiftUI view.

import SwiftUI
import AsyncAlgorithms

struct TickingCounter: View {
    @State private var count = 0
    
    var body: some View {
        Text("\(count)")
            .font(.system(size: 130))
            .monospacedDigit()
            .task {
                for await _ in AsyncTimerSequence(
                    interval: .seconds(1),
                    clock: .continuous
                ) {
                    count += 1
                }
            }
    }
}

Update view state after a delay using Task.sleep()

In my Formatting data inside SwiftUI Text views video, I covered how we can display dynamic dates using styles like relative, offset, or timer. These styles allow SwiftUI Text views to update automatically as time passes.

In that demo, I used a relative style to show how long was left until an event. Later, I needed a similar countdown for another project, and I also wanted the countdown view to disappear once the event had started. The challenge was triggering a view update while it was still on screen, based on the current time.

The solution I ended up using was to call Task.sleep() in the parent view, using the time interval between now and the event time. Once the sleep finishes, I update a piece of state to hide the countdown.

struct ShowtimeView: View {
    private let showtime = Date().advanced(by: 20)
    @State private var showCountdown = true
    
    var body: some View {
        ZStack {
            if showCountdown {
                ShowtimeCountdown(showtime: showtime)
            } else {
                Text("The show has started!")
            }
        }
        .task {
            if showtime.timeIntervalSinceNow > 0 {
                try? await Task.sleep(
                    for: .seconds(
                        showtime.timeIntervalSinceNow.rounded(.down)
                    ),
                    clock: .continuous
                )
                showCountdown = false
            } else {
                showCountdown = false
            }
        }
    }
}

struct ShowtimeCountdown: View {
    let showtime: Date
    
    var body: some View {
        Text("\(showtime, style: .relative) left until showtime")
            .monospacedDigit()
    }
}

Blog

Enable scrolling based on content size in SwiftUI

Support large accessibility text by wrapping content in a scroll view, and prevent unnecessary bounce by enabling scrolling only when the content doesn’t exceed the screen size.

Mesh gradients in SwiftUI

Explore ways to create and customize mesh gradients in SwiftUI, including color adjustments, finer control with Bezier points, and color position animations to add variety and emphasis to your design.

Formatting data inside SwiftUI Text views

Format interpolated values like arrays of strings, measurements, and dates directly inside SwiftUI Text views using FormatStyle, and display dynamic dates using Text.DateStyle.

Format long parameter lists into separate lines in Xcode

Quickly split long function calls or initializers into separate lines using a built-in Xcode shortcut.

Embedding a custom font into a macOS app bundle

Add a custom font to your Mac app by embedding it in the app bundle and making sure it loads correctly for use in your UI.


Discounts

Every month, I share exclusive, limited-time offers on my books with email newsletter subscribers. Sign up so you don’t miss future newsletter issues and can take advantage of upcoming discounts!


Subscribe so you don’t miss future issues!

Invalid email address

Unexpected server error

Subscribed!

We take your privacy seriously and will never share your details with third parties.

You can unsubscribe anytime using the link in our emails.

Newsletter RSS feed