Created
November 3, 2022 16:48
-
-
Save andresilveirah/68d8c7fb03b08ab0f26032c4fd859eab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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