All Issues

iOS Dev Weekly — Issue #32

Opening

Large, dynamic SwiftUI canvases on macOS are leaking accessibility failures into production more often than teams admit. Pixels looked right in my recent build, but VoiceOver behavior exposed missing semantics and runtime notifications — the two things SwiftUI doesn’t always wire up for you. This issue is practical: fix semantics and post the right AppKit notifications before shipping.


This Week’s Big Story

VoiceOver for Custom SwiftUI Controls on macOS

I shipped a macOS build where a custom SwiftUI canvas looked correct but VoiceOver announced many interactive pieces as “group” and focus moved unpredictably during heavy UI updates. The issue was not visual — it was missing accessibility semantics and missing runtime notifications that assistive technologies rely on. This note shows pragmatic fixes to reduce these failures reaching customers.


Trend Signals

• What Apple and Google are doing to push notifications — pay attention to platform-level notification strategies; they shape how we design long-lived background UX and user consent flows. [Source: HackerNews]

• Show HN: Open-source Workspace (mail,docs,spreadsheet,drive) web/iOS — teams continue to expect rich, cross-platform editing experiences, which raises the bar for accessibility parity across web and native. [Source: HackerNews]

• What’s new in Swift: April 2026 Edition — Swift ecosystem curation is ongoing and signals steady evolution in tooling and libraries that teams should track for compatibility and performance gains. [Source: Swift.org Blog]


Swift Snippet of the Week

import SwiftUI
import AppKit

struct CanvasItem: Identifiable {
    let id = UUID()
    let title: String
    var value: Int
}

struct AccessibleCanvas: View {
    @State private var items: [CanvasItem] = [
        .init(title: "Brush", value: 1),
        .init(title: "Eraser", value: 0)
    ]

    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            Text("Tools").font(.headline)
                .accessibilityHidden(false)
                .accessibilityLabel("Tool palette")
                .accessibilityHint("Contains drawing tools")
                .accessibilityAddTraits(.isHeader)

            ForEach($items) { $item in
                HStack {
// … (truncated for newsletter)

This pattern matters because it expresses a pragmatic tradeoff: prefer clear SwiftUI accessibility attributes for maintainability, but be ready to bridge to AppKit when you need deterministic roles, hit-testing, or to post runtime accessibility notifications.


Community Picks

More community links next issue.


Until Next Time

If you run SwiftUI canvases on macOS, add explicit accessibility labels/roles and debounce updates so VoiceOver sees stable changes — and when you need it, bridge a tiny AppKit view to guarantee behavior. Hit reply with a surprising tradeoff your team faced adding VoiceOver support, or forward this to an engineer wrestling with dynamic UI updates; I’ll collect real strategies and share them next issue.