Skip to content

Instantly share code, notes, and snippets.

@amfathi
Last active February 28, 2020 09:52
Show Gist options
  • Select an option

  • Save amfathi/d7780133d5b114b83a943aab5c9bbf49 to your computer and use it in GitHub Desktop.

Select an option

Save amfathi/d7780133d5b114b83a943aab5c9bbf49 to your computer and use it in GitHub Desktop.
CoreDataSupport (iOS10 and above)
import Foundation
import CoreData
// MARK: - CoreData Protocols
protocol CoreDataRetrivable {
init(managedObject: NSManagedObject)
}
protocol CoreDataStorable {
@discardableResult
func mapToManagedObject(entity: NSEntityDescription, insertInto: NSManagedObjectContext) -> NSManagedObject
}
typealias CoreDataModel = CoreDataStorable & CoreDataRetrivable
// MARK: - Database
protocol Database {
func fetch<T: CoreDataRetrivable>(table: CoreDataTables, predicate: NSPredicate?) -> [T]
func store<T: CoreDataStorable>(object: T, in table: CoreDataTables)
func delete(table: CoreDataTables, predicate: NSPredicate?)
func update(table: CoreDataTables, values: [String: Any], predicate: NSPredicate?)
}
class CoreDataDatabase: Database {
private let context: NSManagedObjectContext = AppDelegate.shared.managedObjectContext
func fetch<T: CoreDataRetrivable>(table: CoreDataTables, predicate: NSPredicate? = nil) -> [T] {
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: table.rawValue)
do {
if let predicate = predicate { fetchRequest.predicate = predicate }
let items = try context.fetch(fetchRequest)
var list: [T] = []
for item in items {
list.append(T(managedObject: item))
}
return list
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
return [T]()
}
func store<T: CoreDataStorable>(object: T, in table: CoreDataTables) {
guard let entity = NSEntityDescription.entity(forEntityName: table.rawValue, in: context) else { return }
object.mapToManagedObject(entity: entity, insertInto: context)
do {
try context.save()
} catch let error as NSError {
print("Could not store. \(error), \(error.userInfo)")
}
}
func delete(table: CoreDataTables, predicate: NSPredicate? = nil) {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: table.rawValue)
fetchRequest.predicate = predicate
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try context.execute(deleteRequest)
} catch let error as NSError {
print("Could not delete. \(error), \(error.userInfo)")
}
}
func update(table: CoreDataTables, values: [String: Any], predicate: NSPredicate?) {
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: table.rawValue)
do {
if let predicate = predicate { fetchRequest.predicate = predicate }
let items = try context.fetch(fetchRequest)
for item in items {
for value in values {
item.setValue(value.value, forKey: value.key)
}
}
try context.save()
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
}
class AppDelegate: UIResponder, UIApplicationDelegate {
static var shared: AppDelegate {
// swiftlint:disable:next force_cast
return UIApplication.shared.delegate as! AppDelegate
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "CoreData") //.xcdatamodeld
container.loadPersistentStores(completionHandler: { _, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
var managedObjectContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
import Foundation
enum CoreDataTables: String {
case weatherList = "WeatherList"
}
struct WeatherModel {
let temperature: Double?
let date: Date?
}
extension WeatherModel: CoreDataModel {
init(managedObject: NSManagedObject) {
self.temperature = managedObject.value(forKey: "temperature") as? Double
self.date = managedObject.value(forKey: "date") as? Date
}
func mapToManagedObject(entity: NSEntityDescription, insertInto: NSManagedObjectContext) -> NSManagedObject {
let managedObject = NSManagedObject(entity: entity, insertInto: insertInto)
managedObject.setValue(temperature, forKey: "temperature")
managedObject.setValue(date, forKey: "date")
return managedObject
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment