Skip to content

Instantly share code, notes, and snippets.

@andresilveirah
Created November 3, 2022 16:48
Show Gist options
  • Save andresilveirah/68d8c7fb03b08ab0f26032c4fd859eab to your computer and use it in GitHub Desktop.
Save andresilveirah/68d8c7fb03b08ab0f26032c4fd859eab to your computer and use it in GitHub Desktop.
import Foundation
import CoreData
class PersistentContainer: NSPersistentContainer {
static let modelName = "MyDataModel"
static var main: PersistentContainer? = {
guard
let modelURL = Bundle.framework.url(forResource: modelName, withExtension: "momd"),
let model = NSManagedObjectModel(contentsOf: modelURL)
else {
return nil
}
let container = PersistentContainer(name: modelName, managedObjectModel: model)
container.loadPersistentStores { (_, error) in
print(error as Any)
}
return container
}()
}
struct CoreDataStorage {
var container: Entity? // this is Swift's auto-generated class for the entity you modeled in your DataCoreModel
let context = PersistentContainer.main!.viewContext
let decoder = JSONDecoder()
let encoder = JSONEncoder()
init?() {
let request = Entity.fetchRequest()
let results = try? context.fetch(request)
if results?.count == 0 {
container = Entity(context: context)
} else {
container = results?.first ?? Entity(context: context)
}
}
func integer(forKey defaultName: String) -> Int {
(container?.value(forKey: defaultName) as? Int) ?? 0
}
func string(forKey defaultName: String) -> String? {
container?.value(forKey: defaultName) as? String
}
func object<T>(ofType type: T.Type, forKey defaultName: String) -> T? where T : Decodable {
guard let data = container?.value(forKey: defaultName) as? Data else {
return nil
}
return try? decoder.decode(T.self, from: data)
}
func set(_ value: Any?, forKey defaultName: String) {
container?.setValue(value, forKey: defaultName)
try? context.save()
}
func setObject<T>(_ value: T, forKey defaultName: String) where T : Encodable {
container?.setValue(try? encoder.encode(value), forKey: defaultName)
try? context.save()
}
func setValuesForKeys(_ keyedValues: [String : Any]) {
keyedValues.forEach {
self.set($0.value, forKey: $0.key)
}
try? context.save()
}
func removeObject(forKey defaultName: String) {
container?.setValue(nil, forKey: defaultName)
}
func removeObjects(forKeys keys: [String]) {
keys.forEach {
removeObject(forKey: $0)
}
}
func dictionaryRepresentation() -> [String : Any] {
guard let container = container else { return [:] }
return container.dictionaryWithValues(
forKeys: Mirror(reflecting: container).children.compactMap { $0.label }
)
}
}
struct CoreDataStore {
var storage: Storage
var name: String
var otherAttribute: DecodableClass
var name: String? {
get {
storage.string(forKey: "name")
}
set {
storage.setObject(newValue, forKey: "name")
}
}
var otherAttribute: String? {
get {
storage.string(forKey: "otherAttribute")
}
set {
storage.set(newValue, forKey: "otherAttribute")
}
}
func clear() {
storage.removeObjects(forKeys: ["name", "otherAttribute"])
}
init(storage: CoreDataStorage) {
self.storage = storage
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment