-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reworking/refactoring to share functionality with Daily Calorie Track…
…er (#12)
- Loading branch information
Showing
73 changed files
with
2,717 additions
and
1,760 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,7 @@ | ||
--wraparguments after-first | ||
|
||
# was changing | ||
# let routine: Routine = Routine.get(viewContext, forURIRepresentation: routineURI) | ||
# to | ||
# let routine = Routine.get(viewContext, forURIRepresentation: routineURI) | ||
--disable redundantType |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// CoreDataStack-clear.swift | ||
// | ||
// Copyright 2023 OpenAlloc LLC | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
// | ||
|
||
import CoreData | ||
|
||
import TrackerLib | ||
|
||
extension CoreDataStack { | ||
/// Clear Categories and Servings from the main store. (Should not be present in Archive store.) | ||
/// NOTE: does NOT save context | ||
func clearPrimaryEntities(_ context: NSManagedObjectContext) throws { | ||
try context.deleter(AppSetting.self) | ||
try context.deleter(Exercise.self) | ||
try context.deleter(Routine.self) | ||
} | ||
|
||
/// Clear the log entities from the specified store. | ||
/// If no store specified, it will clear from all stores. | ||
/// NOTE: does NOT save context | ||
public func clearZEntities(_ context: NSManagedObjectContext, inStore: NSPersistentStore? = nil) throws { | ||
try context.deleter(ZExerciseRun.self, inStore: inStore) | ||
try context.deleter(ZExercise.self, inStore: inStore) | ||
try context.deleter(ZRoutineRun.self, inStore: inStore) | ||
try context.deleter(ZRoutine.self, inStore: inStore) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// | ||
// CoreDataStack-preview.swift | ||
// | ||
// Copyright 2023 OpenAlloc LLC | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
// | ||
|
||
import CoreData | ||
|
||
import TrackerLib | ||
|
||
public extension CoreDataStack { | ||
// obtain a manager that has been cleared of all data | ||
static func getPreviewStack() -> CoreDataStack { | ||
do { | ||
let stack = CoreDataStack(isCloud: false, fileNamePrefix: "Test") | ||
|
||
let ctx = stack.container.viewContext | ||
try stack.clearPrimaryEntities(ctx) | ||
try stack.clearZEntities(ctx) | ||
try ctx.save() | ||
|
||
return stack | ||
} catch { | ||
fatalError("Could not obtain preview core data stack.") | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// | ||
// CoreDataStack-stores.swift | ||
// | ||
// Copyright 2023 OpenAlloc LLC | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
// | ||
|
||
import CoreData | ||
|
||
import TrackerLib | ||
|
||
public extension CoreDataStack { | ||
enum StoreType: String { | ||
case main = "" | ||
case archive | ||
} | ||
|
||
func getMainStore(_ context: NSManagedObjectContext) -> NSPersistentStore? { | ||
getStore(context, .main) | ||
} | ||
|
||
func getArchiveStore(_ context: NSManagedObjectContext) -> NSPersistentStore? { | ||
getStore(context, .archive) | ||
} | ||
|
||
private func getStore(_ context: NSManagedObjectContext, _ storeType: StoreType) -> NSPersistentStore? { | ||
getStore(context, storeKey: storeType.rawValue) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// | ||
// CoreDataStack.swift | ||
// | ||
// Copyright 2023 OpenAlloc LLC | ||
// | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this | ||
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
// | ||
|
||
import CoreData | ||
|
||
import TrackerLib | ||
|
||
// NOTE: needed to pass as .environmentObject | ||
extension CoreDataStack: ObservableObject {} | ||
|
||
// NOTE that we're using two stores with a single configuration, | ||
// where the Z* records on 'main' store eventually will be transferred | ||
// to the 'archive' store on iOS, to reduce watch storage needs. | ||
public final class CoreDataStack: BaseCoreDataStack { | ||
static let modelName = "Grout" | ||
static let baseFileName = "Grout" | ||
static let cloudPrefix = "iCloud.org.openalloc.grout" | ||
// static let archiveSuffix = "archive" | ||
|
||
#if os(watchOS) | ||
// NOTE the watch won't get the archive store | ||
let storeKeys = [StoreType.main.rawValue] | ||
#else | ||
let storeKeys = [StoreType.main.rawValue, StoreType.archive.rawValue] | ||
#endif | ||
|
||
public init(isCloud: Bool, fileNamePrefix: String = "") { | ||
let cloudPrefix = isCloud ? CoreDataStack.cloudPrefix : nil | ||
|
||
super.init(modelName: CoreDataStack.modelName, | ||
baseFileName: CoreDataStack.baseFileName, | ||
cloudPrefix: cloudPrefix, | ||
fileNamePrefix: fileNamePrefix, | ||
storeKeys: storeKeys) | ||
} | ||
|
||
override public func loadModel(modelName: String) -> NSManagedObjectModel { | ||
let bundle = Bundle.module | ||
let modelURL = bundle.url(forResource: modelName, withExtension: ".momd")! | ||
return NSManagedObjectModel(contentsOf: modelURL)! | ||
} | ||
|
||
// for de-duping | ||
// NOTE that this is happening on background thread | ||
// NOTE handler is responsible for saving context | ||
override public func handleInsert(backgroundContext: NSManagedObjectContext, | ||
entityName: String, | ||
objectID: NSManagedObjectID, | ||
storeID: String) | ||
{ | ||
logger.debug("handleInsert: name=\(entityName) uri=\(objectID.uriRepresentation().absoluteString.suffix(5)), storeID=\(storeID.suffix(5))") | ||
|
||
guard let mainStore = getMainStore(backgroundContext) else { | ||
logger.error("handleInsert: unable to get main store") | ||
return | ||
} | ||
|
||
#if !os(watchOS) | ||
guard let archiveStore = getArchiveStore(backgroundContext) else { | ||
logger.error("handleInsert: unable to get archive store") | ||
return | ||
} | ||
#endif | ||
|
||
let object = backgroundContext.object(with: objectID) | ||
|
||
do { | ||
switch entityName { | ||
case AppSetting.entity().name: | ||
try AppSetting.dedupe(backgroundContext) | ||
case Exercise.entity().name: | ||
try Exercise.dedupe(backgroundContext, object) | ||
case Routine.entity().name: | ||
try Routine.dedupe(backgroundContext, object) | ||
case ZExercise.entity().name: | ||
try ZExercise.dedupe(backgroundContext, object, inStore: mainStore) | ||
#if !os(watchOS) | ||
try ZExercise.dedupe(backgroundContext, object, inStore: archiveStore) | ||
#endif | ||
case ZExerciseRun.entity().name: | ||
try ZExerciseRun.dedupe(backgroundContext, object, inStore: mainStore) | ||
#if !os(watchOS) | ||
try ZExerciseRun.dedupe(backgroundContext, object, inStore: archiveStore) | ||
#endif | ||
case ZRoutine.entity().name: | ||
try ZRoutine.dedupe(backgroundContext, object, inStore: mainStore) | ||
#if !os(watchOS) | ||
try ZRoutine.dedupe(backgroundContext, object, inStore: archiveStore) | ||
#endif | ||
case ZRoutineRun.entity().name: | ||
try ZRoutineRun.dedupe(backgroundContext, object, inStore: mainStore) | ||
#if !os(watchOS) | ||
try ZRoutineRun.dedupe(backgroundContext, object, inStore: archiveStore) | ||
#endif | ||
default: | ||
_ = 0 | ||
} | ||
|
||
try backgroundContext.save() // should automatically merge changes into foreground context | ||
} catch let error as TrackerError { | ||
logger.error("handleInsert: \(error)") | ||
} catch { | ||
logger.error("handleInsert: \(error.localizedDescription)") | ||
} | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.