ios – Changing SwiftUI App to SwiftData: Single @Mannequin Class vs. Separate Fashions for Every Entity

Spread the love


Shall we say you have got a SwiftUI app, just like the landmarks app, that at present has single Observable class occasion accountable for offering knowledge for the entire app:

@Observable
class ModelData {
    var landmarks: [Landmark] = load("landmarkData.json")
    var hikes: [Hike] = load("hikeData.json")
    var profile = Profile.default

    var options: [Landmark] {
        landmarks.filter { $0.isFeatured }
    }

    var classes: [String: [Landmark]] {
        Dictionary(
            grouping: landmarks,
            by: { $0.class.rawValue }
        )
    }
}

It’s offered to the app like this:

@principal
struct LandmarksApp: App {
    @State personal var modelData = ModelData()

    var physique: some Scene {
        WindowGroup {
            ContentView()
                .atmosphere(modelData)
        }
    }
}

And accessed inside particular person elements of the app like this:

@Setting(ModelData.self) var modelData

If we had been to transform this app to SwiftData, we might:

A) Mannequin the Landmark and Hike objects individually by placing “@Mannequin” on every one… and eliminating the computed queries and utilizing @Question as an alternative. (Unsure what we’d do with Profile since it’s singular)… and share these two separate “mannequin arrays” (?) with the remainder of the app utilizing the approach on this query. On this case, the ModelData class would not exist.

B) OR…. (that is the query)… can we simply put an SwiftData “@Mannequin” on the present ModelData class as a complete, and share it with your entire app? I’ve began attempting to do that, and I’ve obtained so far as

@Mannequin
class ModelData {
    var landmarks: [Landmark]
    var hikes: [Hike]
    var profile: Profile
    
    var options: [Landmark] {
        landmarks.filter { $0.isFeatured }
    }
    var classes: [String: [Landmark]] {
        Dictionary(
            grouping: landmarks,
            by: { $0.class.rawValue }
        )
    }
    
    init(landmarks: [Landmark] = load("landmarks.json"), hikes: [Hike] = load("hikes.json"), profile:Profile = Profile.default) {
        self.landmarks = landmarks
        self.hikes = hikes
        self.profile = profile
    }
}

… and it compiles since I made all the pieces codable… however after I begin occupied with how I’d edit or replace landmarks my head hurts… and it looks as if possibly it is by no means a good suggestion to make use of this “choice B.”

Nonetheless, after I proceed with choice A, I attain a degree the place I understand I’ve misplaced the utility features they usually should be scattered within the codebase.

Are these equally legitimate approaches?

Leave a Reply

Your email address will not be published. Required fields are marked *