TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

SOLVED: How to get rid of AppDelegate in modern Swift Apps

Forums > Swift

I have a utility app that I rewrite every few years. It started all the way back in 2010. It seems that AppDelegates are causing more and more problems. I use the app delegate to instaniate a few classes that are then used across all views.

My latest issue is that the instaniated classes use the AppDelegate so that the can read properties between the three classes. Starting in Beta 3, I am now getting that the primary class cannot find my AppDelegate, specifically the macro code indicates

Canot find type '_delegate' in scope
in Expansion of macro 'ObservationTracked' here

In the first beta I could add in the line @ObservationIgnored private var _delegate = UIApplication.shared.delegate as? AppDelegate

And the code would compile, and the app worked fine.. however now it no longer compiles.

Given all of this, I would like to learn the correct pattern for creating three dependent classes, and sharing their state across all aspects of the application.

3      

Create them as @StateObject in the root View of your app. Then add them using .environmentObject(_:) so they are available to every View below the root View.

3      

I thought it was that easy, but I am still getting Generic struct 'StateObject' requires that 'ClassName' conform to 'ObservableObject'.

And the class compliles with no errors and is defined as @Observable class ClassName {}

Any suggestion on how to figure out why it thinks it is not an ObservableObject?

3      

Ah, sorry, you're using the new @Observable macro, which I haven't yet had a chance to play around with. But from Apple's Migrating from the Observable Object protocol to the Observable macro page, it seems you would make changes like the following...

@main
struct BookReaderApp: App {
    @StateObject private var library = Library()

    var body: some Scene {
        WindowGroup {
            LibraryView()
                .environmentObject(library)
        }
    }
}

// AFTER
@main
struct BookReaderApp: App {
    @State private var library = Library()

    var body: some Scene {
        WindowGroup {
            LibraryView()
                .environment(library)
        }
    }
}

And then you would use the @Environment property wrapper to acces your Observable item in your Views instead of @EnvironmentObject:

// BEFORE
struct LibraryView: View {
    @EnvironmentObject var library: Library

    var body: some View {
        List(library.books) { book in
            BookView(book: book)
        }
    }
}

// AFTER
struct LibraryView: View {
    @Environment(Library.self) private var library

    var body: some View {
        List(library.books) { book in
            BookView(book: book)
        }
    }
}

See if that helps.

4      

Thanks @roosterboy - Made those changes, but still no dice.. I think there is something that is wrong in my class library, but the macro expansion is not providing any guidance. And the compiler doesn't show any meaningful message either. There has to be some other way to expand on the error message.

3      

btw, I missed changing .environmentObject() to .environment()

3      

Hacking with Swift is sponsored by Blaze.

SPONSORED Still waiting on your CI build? Speed it up ~3x with Blaze - change one line, pay less, keep your existing GitHub workflows. First 25 HWS readers to use code HACKING at checkout get 50% off the first year. Try it now for free!

Reserve your spot now

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.