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

SOLVED: @Environment(\.managedObjectContext) var moc VS. class DataController: ObservableObject

Forums > SwiftUI

After working with Core Data a little bit it and reading about it, it seems to me that passing a class around to different views is more streamlined that using @Environment(.managedObjectContext) var moc.

With the class, I can add methods to it to do the various saving, deleting, and other tasks. For instance, with the following class Paul gave us and some additions:

import CoreData
import Foundation

class DataController: ObservableObject {
    let container = NSPersistentContainer(name: "Friendface")

    init() {
        container.loadPersistentStores { descrption, error in
            if let error = error {
                print("Core Data failed to load: \(error.localizedDescription)")
                return
            }
            self.container.viewContext.mergePolicy = NSMergePolicy.mergeByPropertyObjectTrump
        }
    }
    func saveData() {
        if container.viewContext.hasChanges {
            do {
                try container.viewContext.save()
            } catch {
                print("Save Failed! Error: \(error.localizedDescription)")
            }
        }
    }
}

instead of writing:

if moc.hasChanges {
   do {
       try moc.save()
   } catch {
       print("Save failed! Error: \(error.localizedDescription)")
   }
}

I can write:

dataController.saveData()

which seems preferred when I'm having to do it multiple times in a particular view. I do of course have to create the ObservedObject passed from wherever I initially created it, but it seems more compact and less prone to typos or missing stuff to me.

Are there disadvantages to passing the class instead of using the Environment?

2      

Building a centralized data controller (or whatever name you like) gives you the ability to minimize code replication, and tailor certain funcs for specific needs, while still keeping your View code light and lean.

Example, I have a class for API access; nicely wraps up http GETs, POSTs, and so forth. I drop it into pretty much every project where I"m doing API callouts. Then I build an extension where I put this-app-specific functions and just call something like

self.apiPost( url: URL(string: "...")!, body: parmsDict ){ jsonPacket, error in ... ... ... }

Makes for some pretty clean code, a centralized executor of API calls (which could and is just as easily be CoreData calls), and lean Views (and / or ViewModels) that are just containers for and consumers of the API class.

2      

Hacking with Swift is sponsored by Superwall

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Learn More

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.