Chapters

Hide chapters

macOS Apprentice

Third Edition · macOS 26 · Swift 6 · Xcode 26

Section II: Building With SwiftUI

Section 2: 6 chapters
Show chapters Hide chapters

Section III: Building With AppKit

Section 3: 6 chapters
Show chapters Hide chapters

17. Using AppKit in SwiftUI
Written by Sarah Reichelt

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In Section 2 of this book, you created a complete app using the SwiftUI layout framework.

SwiftUI is Apple’s newest layout system and it has some great features, but it doesn’t do everything — at least not yet.

In this chapter, you’ll learn how to integrate AppKit components into a SwiftUI app. This allows you to use SwiftUI as the basis for your app and drop into AppKit when SwiftUI is missing a feature or isn’t suited to a particular purpose.

Showing a Warning Bar

Open your Snowman project from the end of Chapter 10, “Adding Toolbars & Menus”, or use the starter project from the downloads for this chapter.

Run the app and play a few games to remind yourself what you built:

Starting app with some games played.
Starting app with some games played.

While the disappearing snowman shows your accumulating wrong guesses, it would be cool to add a warning bar with color coding to show exactly how many guesses you have left and how close you are to losing. AppKit contains an NSLevelIndicator that is perfect for this, so now you’ll learn how to incorporate one into your SwiftUI app.

Note: In previous editions of this book, you added a web view using WKWebView. SwiftUI now contains its own WebView so this is no longer a good example of using AppKit.

Creating a Level Indicator

To show any AppKit view in a SwiftUI app, you first convert it into a SwiftUI view. The NSViewRepresentable protocol provides the means for doing this.

Fidorg jju twexevih ijfug.
Suxusm pwu zpoqaguk esrit.

Zuickt mahumf cpa rbiwegil ebbif.
Cionrk nasufk lke lvocinum ocniw.

Filling in the Methods

The first of these methods makes the AppKit view, so in makeNSView(context:), replace the placeholder with:

Setting Up the Data Flow

Your new WarningBar structure expects an Int containing the number of guesses left, but right now, there’s no property that supplies that information directly. It sounds like something Game should do, so open Game.swift and add this computed property:

Adding the View

The logical place for this bar is underneath the snowman image inside GameView. Open GameView.swift and find the Image that displays the snowman. Select the Image line and its three modifier lines, then press {. This wraps the selected lines in a pair of curly braces, indents them and places the cursor at the front so you can type the name of a new container view.

Heqliqt dek majc loyiubj mizsurhr.
Yifnuyw qiq nosz dezoeqp jofcissr.

Configuring the Level Indicator

NSLevelIndicator has several properties that you can change to make it look the way you want. To see the effect of your changes as you make them, open GameView.swift, resume the preview and then click the pin icon at the top left of the preview.

Fkehauh ehyix fisgafj tix tegii.
Wzufaih islen rudnijx fix fafua.

Guyxedx hes wocq wuyuvc.
Zadkanf guh woqc vupixf.

Hze dojehuv wulketb ric.
Msi junevat gensufn tud.

Using a Coordinator

You’re sending data from the SwiftUI view to the AppKit view, but what if you want to communicate back the other way?

Setting Up the Action and Target

The purpose of this coordinator is to detect and respond to clicks inside the level indicator. AppKit views do this with a target and action system. You tell the view what target should receive the click and what action this should trigger. In this case, the target will be the coordinator and the action will be a method in the coordinator.

Showing Hints

Right now, the app doesn’t build. This is because you added a new binding property to WarningBar and that property doesn’t exist or get passed to the view yet.

Odsocq laj e razn.
Ebtuxw por o vufy.

Lisa veitc wenzem.
Rubu diijv heggel.

Observing Events

You’ve seen how to convert an AppKit view into a SwiftUI view for presentation in your SwiftUI app, but AppKit has more than views. One thing it’s extremely good at is event handling.

Trapping Key Strokes

Start by stripping out the views and code related to the text entry field.

Vugibzazc sed chenpiv.
Qitujkicy maw swuhjan.

Processing Key Strokes

The first step is to work out if the player pressed a valid key.

Fhekuml jovx lok cmexm hokoyguiv.
Kvuwurb fuvd vey lnaqc bitorzuep.

Watching for the Command Key

Run the app and press Command-N to try to start a second game. Try quitting the app using Command-Q. The game intercepted these key presses, so it looks like you’ve guessed N and Q for the first game. You didn’t get a new game, and the app didn’t quit.

When Should You Start With SwiftUI?

You’ve made a SwiftUI app and you’ve made an AppKit app. Now, you’ve learned how to include AppKit in a SwiftUI app, but when is this the right approach to take?

Challenges

  1. Add a tooltip to WarningBar that shows how it can be used to display a hint.
  2. Add a menu item to toggle the hint on and off, give it a keyboard shortcut, and make sure the menu item is disabled when the game isn’t in progress. Bonus points if you get its title to change between “Show Hint” and “Hide Hint” depending on the current state of the hint.

Key Points

  • NSViewRepresentable lets you create a SwiftUI version of an AppKit view.
  • A coordinator handles passing data back from the AppKit view to SwiftUI.
  • You can include non-view AppKit features, like NSEvent, in a SwiftUI app.
  • The hybrid approach — adding AppKit to a SwiftUI app to supply missing features — is extremely powerful, and it is frequently the best way to structure your apps.

Where to Go From Here?

In this chapter, you integrated AppKit into a SwiftUI app and looked at when this is the right approach. In the next chapter, you’ll do the reverse and bring SwiftUI into your AppKit app.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now