Open window / scene in SwiftUI 2.0 on macOS

Published by malhal on

Update June 2022: windowing APIs have now been added so the code below might not be the best way to implement it.

Here is how to open a new window or re-activate an existing one in SwiftUI on macOS.

In your ContentView create a button and open a URL for your app and another View e.g. Viewer to be shown in the window we will open:

struct ContentView: View {
    @Environment(\.openURL) var openURL
    var body: some View {
        VStack {
            Button("Open Viewer") {
                if let url = URL(string: "myappname://viewer") {
                     openURL(url)
                }
            }
            Text("Hello, world!")
        }
        .padding()
    }
}

struct Viewer: View {
    var body: some View {
        Text("Viewer")
    }
}

In your App add another WindowGroup for your viewer and set it to enable handling of external launch events (an internal event in our case).

@main
struct GroupDefaultsTestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }

        WindowGroup("Viewer") { // other scene
            Viewer().handlesExternalEvents(preferring: Set(arrayLiteral: "viewer"), allowing: Set(arrayLiteral: "*")) // activate existing window if exists
        }
        .handlesExternalEvents(matching: Set(arrayLiteral: "viewer")) // create new window if one doesn't exist
    }
}

Now in Project->Info->URL Types type in myappname in the URL Schemes field (and the identifier field too) to register our app with the system.

Now run your app and click the button and it should open a new window! In first window click the button again and it’ll re-activate the existing second window bringing it to front.

Categories: SwiftUI

2 Comments

Why Does URL Scheme/onOpenURL In SwiftUI Always Open A New Window? - Programming Questions And Solutions Blog · 20th February 2023 at 2:09 am

[…] article, "Open window / scene in SwiftUI 2.0 on macOS" shows how to open windows. I took the pieces of it and made it to where it would simply open my […]

SwiftUI 2: the way to open view in new window · 26th April 2024 at 2:46 pm

[…] Remember that this approach works well for macOS apps. If you need cross-platform behavior, consider using platform-specific code or AppKit for more complex scenarios 1234. […]

Comments are closed.