2021-11-29 19:58:06 -08:00
//
// P e r s i s t e n c e . s w i f t
2023-03-26 09:08:08 -07:00
// M e s h t a s t i c
2021-11-29 19:58:06 -08:00
//
2023-03-26 09:08:08 -07:00
// C o p y r i g h t ( c ) G a r t h V a n d e r H o u w e n 1 1 / 2 8 / 2 1 .
2021-11-29 19:58:06 -08:00
//
import CoreData
2021-12-12 17:17:46 -08:00
class PersistenceController {
2021-12-25 23:48:12 -08:00
2021-12-12 17:17:46 -08:00
static let shared = PersistenceController ( )
2021-11-29 19:58:06 -08:00
2021-12-12 17:17:46 -08:00
static var preview : PersistenceController = {
let result = PersistenceController ( inMemory : false )
let viewContext = result . container . viewContext
for _ in 0. . < 10 {
let newItem = NodeInfoEntity ( context : viewContext )
2021-12-16 22:45:18 -08:00
newItem . lastHeard = Date ( )
2021-12-12 17:17:46 -08:00
}
do {
try viewContext . save ( )
} catch {
// R e p l a c e t h i s i m p l e m e n t a t i o n w i t h c o d e t o h a n d l e t h e e r r o r a p p r o p r i a t e l y .
// f a t a l E r r o r ( ) c a u s e s t h e a p p l i c a t i o n t o g e n e r a t e a c r a s h l o g a n d t e r m i n a t e . Y o u s h o u l d n o t u s e t h i s f u n c t i o n i n a s h i p p i n g a p p l i c a t i o n , a l t h o u g h i t m a y b e u s e f u l d u r i n g d e v e l o p m e n t .
let nsError = error as NSError
fatalError ( " Unresolved error \( nsError ) , \( nsError . userInfo ) " )
}
return result
} ( )
2021-11-29 19:58:06 -08:00
2021-12-12 17:17:46 -08:00
let container : NSPersistentContainer
2021-11-29 19:58:06 -08:00
2021-12-12 17:17:46 -08:00
init ( inMemory : Bool = false ) {
2023-03-06 10:33:18 -08:00
2021-12-12 17:17:46 -08:00
container = NSPersistentContainer ( name : " Meshtastic " )
2023-03-06 10:33:18 -08:00
2021-12-12 17:17:46 -08:00
if inMemory {
container . persistentStoreDescriptions . first ! . url = URL ( fileURLWithPath : " /dev/null " )
}
2023-03-06 10:33:18 -08:00
2021-12-25 23:48:12 -08:00
container . loadPersistentStores ( completionHandler : { ( _ , error ) in
2023-03-06 10:33:18 -08:00
2021-12-12 17:17:46 -08:00
// M e r g e p o l i c y t h a t f a v o r s i n m e m o r y d a t a o v e r d a t a i n t h e d b
self . container . viewContext . mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
2022-01-01 08:03:46 -08:00
self . container . viewContext . automaticallyMergesChangesFromParent = true
2023-03-06 10:33:18 -08:00
2021-12-12 17:17:46 -08:00
if let error = error as NSError ? {
2021-11-29 19:58:06 -08:00
2021-12-31 20:52:22 -08:00
print ( " 💥 CoreData Error: \( error . localizedDescription ) . Now attempting to truncate CoreData database. All app data will be lost. " )
2021-12-29 16:13:17 -08:00
self . clearDatabase ( )
2021-12-12 17:17:46 -08:00
}
} )
}
2023-03-06 10:33:18 -08:00
2021-12-29 16:13:17 -08:00
public func clearDatabase ( ) {
guard let url = self . container . persistentStoreDescriptions . first ? . url else { return }
let persistentStoreCoordinator = self . container . persistentStoreCoordinator
do {
2023-03-06 10:33:18 -08:00
try persistentStoreCoordinator . destroyPersistentStore ( at : url , ofType : NSSQLiteStoreType , options : nil )
2021-12-29 16:13:17 -08:00
try persistentStoreCoordinator . addPersistentStore ( ofType : NSSQLiteStoreType , configurationName : nil , at : url , options : nil )
2022-10-03 16:52:00 -07:00
print ( " 💥 CoreData database truncated. All app data has been erased. " )
2023-03-06 10:33:18 -08:00
2021-12-29 16:13:17 -08:00
} catch let error {
2022-10-03 16:52:00 -07:00
print ( " 💣 Failed to destroy CoreData database, delete the app and re-install to clear data. Attempted to clear persistent store: " + error . localizedDescription )
2021-12-29 16:13:17 -08:00
}
}
2021-11-29 19:58:06 -08:00
}
2022-10-06 08:56:15 -07:00
extension NSManagedObjectContext {
2023-03-06 10:33:18 -08:00
2022-10-06 08:56:15 -07:00
// / E x e c u t e s t h e g i v e n ` N S B a t c h D e l e t e R e q u e s t ` a n d d i r e c t l y m e r g e s t h e c h a n g e s t o b r i n g t h e g i v e n m a n a g e d o b j e c t c o n t e x t u p t o d a t e .
// /
// / - P a r a m e t e r b a t c h D e l e t e R e q u e s t : T h e ` N S B a t c h D e l e t e R e q u e s t ` t o e x e c u t e .
// / - T h r o w s : A n e r r o r i f a n y t h i n g w e n t w r o n g e x e c u t i n g t h e b a t c h d e l e t i o n .
public func executeAndMergeChanges ( using batchDeleteRequest : NSBatchDeleteRequest ) throws {
batchDeleteRequest . resultType = . resultTypeObjectIDs
2023-03-06 10:33:18 -08:00
2022-10-06 08:56:15 -07:00
let result = try execute ( batchDeleteRequest ) as ? NSBatchDeleteResult
let changes : [ AnyHashable : Any ] = [ NSDeletedObjectsKey : result ? . result as ? [ NSManagedObjectID ] ? ? [ ] ]
2023-03-06 10:33:18 -08:00
2022-10-06 08:56:15 -07:00
NSManagedObjectContext . mergeChanges ( fromRemoteContextSave : changes , into : [ self ] )
}
}