Enables cloudkit

release
Laurent 3 years ago
parent 8b9016ddba
commit 152e88138b
  1. 10
      LeCountdown/LeCountdown.entitlements
  2. 17
      LeCountdown/Model/Persistence.swift
  3. 51
      LeCountdown/Views/ContentView.swift
  4. 3
      LeCountdown/Views/PresetsView.swift

@ -2,6 +2,16 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.icloud-container-identifiers</key>
<array>
<string>iCloud.LeCountdown</string>
</array>
<key>com.apple.developer.icloud-services</key>
<array>
<string>CloudKit</string>
</array>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.staxriver.countdown</string>

@ -48,14 +48,30 @@ struct PersistenceController {
let storeURL = URL.storeURL(for: "group.com.staxriver.countdown", databaseName: "group.com.staxriver.countdown")
let storeDescription = NSPersistentStoreDescription(url: storeURL)
// storeDescription.shouldMigrateStoreAutomatically = true
// storeDescription.shouldInferMappingModelAutomatically = true
let id = "iCloud.LeCountdown"
let options = NSPersistentCloudKitContainerOptions(containerIdentifier: id)
storeDescription.cloudKitContainerOptions = options
let remoteChangeKey = "NSPersistentStoreRemoteChangeNotificationOptionKey"
storeDescription.setOption(true as NSNumber, forKey: remoteChangeKey)
container = NSPersistentCloudKitContainer(name: "LeCountdown")
container.persistentStoreDescriptions = [storeDescription]
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
// do {
// try container.initializeCloudKitSchema()
// } catch {
// fatalError("Unresolved error \(error)")
// }
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
@ -72,6 +88,7 @@ struct PersistenceController {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
}

@ -7,6 +7,8 @@
import SwiftUI
import CoreData
import Combine
import CloudKit
class BoringContext : ObservableObject {
@ -64,6 +66,11 @@ struct ContentView<T : AbstractTimer>: View {
}
}
var coreDataPublisher: NotificationCenter.Publisher { NotificationCenter.default
.publisher(for: .NSManagedObjectContextDidSave, object: viewContext) }
var cloudkitPublisher: NotificationCenter.Publisher { NotificationCenter.default
.publisher(for: Notification.Name(rawValue: "NSPersistentStoreRemoteChangeNotificationOptionKey"), object: viewContext) }
@State private var isEditing: Bool = false {
didSet {
if self.isEditing == false {
@ -80,10 +87,6 @@ struct ContentView<T : AbstractTimer>: View {
GridItem(spacing: 10.0),
]
var timersArray: [T] {
return Array(timers)
}
var body: some View {
GeometryReader { reader in
@ -158,11 +161,6 @@ struct ContentView<T : AbstractTimer>: View {
.sheet(isPresented: $boringContext.isShowingNewData, content: {
self._newView(isPresented: $boringContext.isShowingNewData)
.environment(\.managedObjectContext, viewContext)
.onDisappear {
withAnimation {
self._buildItemsList()
}
}
})
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
@ -184,6 +182,17 @@ struct ContentView<T : AbstractTimer>: View {
}
}
}
// .onReceive(cloudkitPublisher, perform: { _ in
// print(">>>cloudkitPublisher")
// withAnimation {
// self._buildItemsList()
// }
// })
.onReceive(coreDataPublisher, perform: { _ in
withAnimation {
self._buildItemsList()
}
})
.onAppear {
self._buildItemsList()
self._askPermissions()
@ -246,18 +255,18 @@ struct ContentView<T : AbstractTimer>: View {
self.model.spots = spots
}
fileprivate func _reorder(from: IndexSet, to: Int) {
var timers: [AbstractTimer] = self.timersArray
timers.move(fromOffsets: from, toOffset: to)
for (i, countdown) in timers.enumerated() {
countdown.order = Int16(i)
}
do {
try viewContext.save()
} catch {
self.boringContext.error = error
}
}
// fileprivate func _reorder(from: IndexSet, to: Int) {
// var timers: [AbstractTimer] = Array(self.timers)
// timers.move(fromOffsets: from, toOffset: to)
// for (i, countdown) in timers.enumerated() {
// countdown.order = Int16(i)
// }
// do {
// try viewContext.save()
// } catch {
// self.boringContext.error = error
// }
// }
fileprivate func _askPermissions() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .criticalAlert]) { success, error in

@ -13,11 +13,13 @@ enum PresetSection: Int, Identifiable, CaseIterable {
case workout
case chill
case cooking
case tea
case other
var presets: [Preset] {
switch self {
case .cooking: return [.softBoiled, .mediumBoiledEggs, .hardBoiledEggs]
case .tea: return [.greenTea, .blackTea]
case .workout: return [.runningSplits]
case .chill: return [.nap, .meditation]
case .other: return [.toothbrushing]
@ -30,6 +32,7 @@ enum PresetSection: Int, Identifiable, CaseIterable {
case .workout: return NSLocalizedString("Workout", comment: "")
case .chill: return NSLocalizedString("Chill", comment: "")
case .other: return NSLocalizedString("Other", comment: "")
case .tea: return NSLocalizedString("Tea", comment: "")
}
}
}

Loading…
Cancel
Save