NEW: Learn to build the incredible iOS 15 Weather app today! >>

What's the SwiftUI way to do this AppDelegate thing?

Forums > SwiftUI

I'm working my way through "Hacking with macOS -- SwiftUI Edition 2020-01-31". For Project 2, "Odd One Out", there are some instructions relating to AppDelegate.swift, but there's no such file in my Project 2, I think AppDelegate isn't really a SwiftUI thing? I don't know. Anyway, I don't know how to do

window.titlebarAppearsTransparent = true
window.isMovableByWindowBackground = true

I looked around online for a way to translate this stuff into SwiftUI, but the only stuff I found was just way beyond what I could understand. Did I get the wrong version of the book? Is there a newer version that replaces AppDelegate stuff with...I don't know, ContentView stuff or whatever?

   

In January 2020, you still had to build SwiftUI apps using the old (UI|App)Kit lifecycle. So, using AppDelegate, etc.

At WWDC that year, the SwiftUI lifecycle was introduced and we no longer had to use that stuff.

However, you can still use an AppDelegate if you need to, like this:

//create a class to use as your app's delegate
class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        // Insert code here to initialize your application
    }

    func applicationWillTerminate(_ aNotification: Notification) {
        // Insert code here to tear down your application
    }

    //...add any other NSApplicationDelegate methods you need to use
}

//use AppDelegate in your App struct
@main
struct SampleApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

That should work, but I haven't tried rebuilding those old projects in the newer SwiftUI way of doing things.

   

Cool, thanks much. But you mention the newer SwiftUI way? What's the newer SwiftUI way to get isMovableByWindowBackground? I found WindowGroup..windowStyle(HiddenTitleBarWindowStyle()) to get the effect of titlebarAppearsTransparent but I can't find anything about the isMovable thing. Any ideas?

If not, then could you give me an idea of where to get window in AppDelegate.applicationDidFinishLaunching()? Thanks for any help you can give me.

   

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS, you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Side note: It's always interesting to learn where code came from, but it might be better to learn SwiftUI instead, since that's what Apple will be using for the foreseeable future. Have you checked out Apple's free courses for SwiftUI? [https://developer.apple.com/tutorials/swiftui]. Historically, Apple has also released ebooks that teach you Swift by building an app, but it looks like they haven't made one for Xcode 13. I'm somewhat new to SwiftUI myself, so if you ever need anything, feel free to contact me.

   

Heh, yes, I've seen Apple's free tutorials. That's why I've spent hundreds of $$$ for Paul's tutorials. But I think you've misunderstood. Learning SwiftUI with a tutorial that takes me through developing an app is precisely what I'm doing, reading Paul's book "Hacking with macOS". The only reason I'm asking the original question is that Paul's tutorial has this old stuff in it, and I figure maybe it's just an editing oversight, and someone can surely tell me what Paul will change that to in his next edition.

I'd love your help: tell me how to get the effect of those two flags using proper, modern SwiftUI, and I'll be in your debt.

   

Or, if you're feeling bored and/or extremely charitable, clone my implementation of his tutorial and tell me why "Play Again" isn't showing up on the blue button. I hacked the app a bit so it will just advance you every time you click an animal; it doesn't matter which one you click. After you get a screen full of animals, when you click on one, you get the end screen, animated opacity, looks great. Except that the blue button is supposed to say "Play Again".

Any ideas why not? Cheers

   

Your button isn't in the correct spot. You'd need to move it to inside the if isGameOver declaration.

   

   

I am more indebted to you than I expected. I would NEVER have thought to move that if{} block into a VStack. I'm still in the dark about where procedural code can be run. I would never have guessed it could run inside a VStack.

As for the movable window thing, that looks right, but where do I get the window? I've tried NSApp.mainWindow and NSApp.windows.first, but those aren't available even when ContentView.onAppear runs. Am I looking in the wrong place for the main window?

Much gratitude to you already

1      

But you mention the newer SwiftUI way?

By "newer SwiftUI way", I mean the SwiftUI lifecycle using an App struct annotated with @main rather than having an NSApplicationDelegate annotated with @NSApplicationMain.

I got this to work just fine:

import SwiftUI

class AppDelegate: NSObject, NSApplicationDelegate {
    func applicationDidFinishLaunching(_ notification: Notification) {
        guard let app = notification.object as? NSApplication else {
            fatalError("no application object")
        }

        guard app.windows.count > 0 else {
            fatalError("no windows")
        }

        app.windows.first?.isMovableByWindowBackground = true
    }
}

@main
struct Project2App: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .windowStyle(HiddenTitleBarWindowStyle())
    }
}

1      

Thank you so much! Please tell me there is a magical room in Hogwarts where you learned stuff like this. How in the world did you know to circumvent SwiftUI to set that flag? I mean, how did you know not to do it with a view modifier like titlebarAppearsTransparent? What's different between those two flags that makes one work as a view modifier and the other one require help from Rube Goldberg?

Again, thank you. My therapist is getting rich from this😆

   

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS, you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Learn More

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.