UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: SwiftData context seperate from views

Forums > SwiftUI

Hi everyone, I am trying to build an app that would have SwiftData and networking component. I would like to have seperate class that would handle processing of user SwiftData entities. My problem is, modelContainer as well as context are passed via environment property wrapper to child views and all my logic is seperate from all my view classes. What is the correct SwiftUI proper way how to get container or context in custom classes?

1      

hi Stepan,

when you initialize your app, you can take more control of creation of the modelContainer.

that is: instead of using the usual .modelContainer(for: ...) modifier, you can define a modelContainer in the app's initializer (and then inject it into the SwiftUI environment using .modelContainer(modelContainer)). if you do this, your app might then create other class objects and pass the container to each.

you can find a simple example of this in my ShoppingList17 project. look for ShoppingListApp.init() in the ShoppingListApp.swift file.

thanks to Stewart Lynch for presenting this idea in a recent video, and i highly recommend that folks follow his work.

hope that helps,

DMG

2      

✅✅✅✅

I second the vote for watching Stewart Lynch's videos on SwiftData.

2      

thank tou guys thousand times!

1      

I may have misunderstood the question... or the answer?

I thought the issue was that the Views get access to the context through environment variables, but methods in the classes do not. I tried to get around this by passing the context to the method as a parameter, but I still think that it is causing an issue with computed vars in the classes. I find that I can insert an class member to the context, but a variable in the class that counts the members does not update when accessed?

Is this a different question/issue I should post?

   

hi Gerry,

i took Stepan's question to mean that there might be (class) objects out there in an app that need to know about the modelContext. if that's the case, the suggestion i gave above certainly makes it possible.

there is another alternative situation, such as what you see in an MVVM-style app, where when a SwiftUI view is instantiated, it creates a view model and passes it the modelContext.

in both cases, that non-View (class) object is then able to make ad-hoc data fetches against SwiftData using the modelContext.

but perhaps you're looking at something a little different: the idea of a (class) object having its own version of a @Query, so that it can monitor changes in the modelContext.

if we were using Core Data, such a (class) object would use an NSFetchedResultsController (rather than a @FetchRequest that can only be used in a View) to monitor changes in the modelContext in real time.

that is, @FetchRequest is designed to easily work with Core Data, but only in a View. an NSFetchedResultsController provides pretty much the same function, although you can use it anywhere you like.

so i think you're asking "if @Query is designed to easily work with SwiftData, but only in a View, what provides the same functionality everywhere else?

alas, the answer right now for SwiftData is: nothing. (in fact, if you look at the sample project i suggested above, you'll see that the one object i created outside of SwiftUI with access to the modelContext has to be told to make a new data fetch whenever i change the number of items on the shopping list -- it is not capable of discovering the change on its own.)

look to WWDC2024 and "SwiftData 2" to fill this gap. (is it really only three months away?) i would think this is one of the most obvious additions for SwiftData.

hope that helps,

DMG

   

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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.