diff --git a/CocktailBucket (iOS).entitlements b/CocktailBucket (iOS).entitlements
new file mode 100644
index 0000000..a3f099f
--- /dev/null
+++ b/CocktailBucket (iOS).entitlements
@@ -0,0 +1,23 @@
+
+
+
+
+ aps-environment
+ development
+ com.apple.developer.icloud-container-identifiers
+
+ iCloud.com.example.apple-samplecode.CoreDataCloudKitDemo5VTM8F229V
+
+ com.apple.developer.icloud-services
+
+ CloudDocuments
+ CloudKit
+
+ com.apple.developer.ubiquity-container-identifiers
+
+ iCloud.com.example.apple-samplecode.CoreDataCloudKitDemo5VTM8F229V
+
+ com.apple.developer.ubiquity-kvstore-identifier
+ $(TeamIdentifierPrefix)$(CFBundleIdentifier)
+
+
diff --git a/CocktailBucket (macOS).entitlements b/CocktailBucket (macOS).entitlements
new file mode 100644
index 0000000..628366c
--- /dev/null
+++ b/CocktailBucket (macOS).entitlements
@@ -0,0 +1,23 @@
+
+
+
+
+ com.apple.developer.aps-environment
+ development
+ com.apple.developer.icloud-container-identifiers
+
+ iCloud.com.example.apple-samplecode.CoreDataCloudKitDemo5VTM8F229V
+
+ com.apple.developer.icloud-services
+
+ CloudDocuments
+ CloudKit
+
+ com.apple.developer.ubiquity-container-identifiers
+
+ iCloud.com.example.apple-samplecode.CoreDataCloudKitDemo5VTM8F229V
+
+ com.apple.developer.ubiquity-kvstore-identifier
+ $(TeamIdentifierPrefix)$(CFBundleIdentifier)
+
+
diff --git a/CocktailBucket--iOS--Info.plist b/CocktailBucket--iOS--Info.plist
new file mode 100644
index 0000000..634f4e4
--- /dev/null
+++ b/CocktailBucket--iOS--Info.plist
@@ -0,0 +1,12 @@
+
+
+
+
+ UIBackgroundModes
+
+ fetch
+ processing
+ remote-notification
+
+
+
diff --git a/CocktailBucket.xcodeproj/project.pbxproj b/CocktailBucket.xcodeproj/project.pbxproj
index 05b589b..e46ce66 100644
--- a/CocktailBucket.xcodeproj/project.pbxproj
+++ b/CocktailBucket.xcodeproj/project.pbxproj
@@ -23,6 +23,8 @@
F9CD5D402679E5FA008AED32 /* BucketListDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9CD5D3E2679E5FA008AED32 /* BucketListDetail.swift */; };
F9CD5D422679E61C008AED32 /* EditCocktail.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9CD5D412679E61C008AED32 /* EditCocktail.swift */; };
F9CD5D432679E61C008AED32 /* EditCocktail.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9CD5D412679E61C008AED32 /* EditCocktail.swift */; };
+ F9DCF6932850A4000068AE34 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9DCF6922850A4000068AE34 /* CloudKit.framework */; };
+ F9DCF6962850A40F0068AE34 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9DCF6952850A40F0068AE34 /* CloudKit.framework */; };
F9F9D4122844B26800DC4B06 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9F9D4112844B26800DC4B06 /* Persistence.swift */; };
F9F9D4132844B26800DC4B06 /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9F9D4112844B26800DC4B06 /* Persistence.swift */; };
F9F9D41528466ACC00DC4B06 /* BucketList+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9F9D41428466ACC00DC4B06 /* BucketList+Extensions.swift */; };
@@ -51,6 +53,11 @@
F9CD5D3B2679E5CE008AED32 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = ""; };
F9CD5D3E2679E5FA008AED32 /* BucketListDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BucketListDetail.swift; sourceTree = ""; };
F9CD5D412679E61C008AED32 /* EditCocktail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCocktail.swift; sourceTree = ""; };
+ F9DCF68F2850A3EE0068AE34 /* CocktailBucket--iOS--Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "CocktailBucket--iOS--Info.plist"; sourceTree = ""; };
+ F9DCF6902850A3FC0068AE34 /* CocktailBucket (iOS).entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "CocktailBucket (iOS).entitlements"; sourceTree = ""; };
+ F9DCF6922850A4000068AE34 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.5.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; };
+ F9DCF6942850A40B0068AE34 /* CocktailBucket (macOS).entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "CocktailBucket (macOS).entitlements"; sourceTree = ""; };
+ F9DCF6952850A40F0068AE34 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };
F9F9D4112844B26800DC4B06 /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; };
F9F9D41428466ACC00DC4B06 /* BucketList+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BucketList+Extensions.swift"; sourceTree = ""; };
F9F9D41728466DB900DC4B06 /* Cocktail+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Cocktail+Extensions.swift"; sourceTree = ""; };
@@ -66,6 +73,7 @@
buildActionMask = 2147483647;
files = (
F9F9D428284E06A300DC4B06 /* CropViewController in Frameworks */,
+ F9DCF6932850A4000068AE34 /* CloudKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -73,6 +81,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ F9DCF6962850A40F0068AE34 /* CloudKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -82,8 +91,12 @@
F9CD5D012679CBEF008AED32 = {
isa = PBXGroup;
children = (
+ F9DCF6942850A40B0068AE34 /* CocktailBucket (macOS).entitlements */,
+ F9DCF6902850A3FC0068AE34 /* CocktailBucket (iOS).entitlements */,
+ F9DCF68F2850A3EE0068AE34 /* CocktailBucket--iOS--Info.plist */,
F9CD5D062679CBEF008AED32 /* Shared */,
F9CD5D122679CBF0008AED32 /* Products */,
+ F9DCF6912850A4000068AE34 /* Frameworks */,
);
sourceTree = "";
};
@@ -134,6 +147,15 @@
path = Views;
sourceTree = "";
};
+ F9DCF6912850A4000068AE34 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ F9DCF6952850A40F0068AE34 /* CloudKit.framework */,
+ F9DCF6922850A4000068AE34 /* CloudKit.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@@ -399,11 +421,13 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = "CocktailBucket (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 5VTM8F229V;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "CocktailBucket--iOS--Info.plist";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -429,11 +453,13 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = "CocktailBucket (iOS).entitlements";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 5VTM8F229V;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_FILE = "CocktailBucket--iOS--Info.plist";
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
@@ -460,6 +486,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = "CocktailBucket (macOS).entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
@@ -489,6 +516,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_ENTITLEMENTS = "CocktailBucket (macOS).entitlements";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
diff --git a/Shared/Persistence.swift b/Shared/Persistence.swift
index edb91b2..5bb9ea4 100644
--- a/Shared/Persistence.swift
+++ b/Shared/Persistence.swift
@@ -8,6 +8,10 @@
import Foundation
import CoreData
+// MARK: - Creating Contexts
+
+let appTransactionAuthorName = "app"
+
class PersistenceController: ObservableObject {
static let shared = PersistenceController()
@@ -26,16 +30,32 @@ class PersistenceController: ObservableObject {
return url
}()
- let container: NSPersistentContainer
+ let container: NSPersistentCloudKitContainer
init() {
- container = NSPersistentContainer(name: "CocktailBucket")
+ container = NSPersistentCloudKitContainer(name: "CocktailBucket")
+
+ let privateStoreDescription = container.persistentStoreDescriptions.first!
+ let storesURL = privateStoreDescription.url!.deletingLastPathComponent()
+ privateStoreDescription.url = storesURL.appendingPathComponent("private.sqlite")
+ privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
+ privateStoreDescription.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
+
+ container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
+ container.viewContext.transactionAuthor = appTransactionAuthorName
+
+ // Pin the viewContext to the current generation token and set it to keep itself up to date with local changes.
container.viewContext.automaticallyMergesChangesFromParent = true
+ do {
+ try container.viewContext.setQueryGenerationFrom(.current)
+ } catch {
+ fatalError("###\(#function): Failed to pin viewContext to the current generation:\(error)")
+ }
}
}
diff --git a/Shared/Views/EditCocktail.swift b/Shared/Views/EditCocktail.swift
index d90bde1..5bc432c 100644
--- a/Shared/Views/EditCocktail.swift
+++ b/Shared/Views/EditCocktail.swift
@@ -243,7 +243,6 @@ struct EditCocktail: View {
createOrUpdateCocktailPicture()
try? viewContext.save()
- viewContext.reset()
}
private func createOrUpdateCocktailPicture() {