Skip to content

Instantly share code, notes, and snippets.

@randomor
Last active February 19, 2021 20:59
Show Gist options
  • Save randomor/be39af31c346220cfaca4f5a9b00252f to your computer and use it in GitHub Desktop.
Save randomor/be39af31c346220cfaca4f5a9b00252f to your computer and use it in GitHub Desktop.
SwiftUI 2020 + CloudKit + Core Data ZenJournal prototype: https://thezenjournal.com
import SwiftUI
import CoreData
let appTransactionAuthorName = "app"
@main
struct ZenJournalApp: App {
var body: some Scene {
WindowGroup {
NavigationWrapper()
.environment(\.managedObjectContext, persistentContainer.viewContext)
}
}
var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "ZenModel")
// Enable history tracking and remote notifications
guard let description = container.persistentStoreDescriptions.first else {
fatalError("###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
let id = "iCloud.com.idealistspace.zenjournal"
let options = NSPersistentCloudKitContainerOptions(containerIdentifier: id)
description.cloudKitContainerOptions = options
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
// do {
// // Uncomment to do a dry run and print the CK records it'll make
//// try container.initializeCloudKitSchema(options: [.dryRun, .printSchema])
// // Uncomment to initialize your schema
// try container.initializeCloudKitSchema()
// } catch {
// print("Unable to initialize CloudKit schema: \(error.localizedDescription)")
// }
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)")
}
return container
}()
}
import SwiftUI
struct NavigationWrapper: View {
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: ZenLog.allLogsFetchRequest()) var allLogs: FetchedResults<ZenLog>
var body: some View {
VStack{
TimelineView(logs: self.allLogs)
}
}
}
import Foundation
import CoreData
class ZenLog: NSManagedObject, Identifiable {
@NSManaged var text: String?
@NSManaged var createdAt: Date?
}
extension ZenLog {
// ❇️ The @FetchRequest property wrapper in the ContentView will call this function
static func allLogsFetchRequest() -> NSFetchRequest<ZenLog> {
let request: NSFetchRequest<ZenLog> = ZenLog.fetchRequest() as! NSFetchRequest<ZenLog>
// ❇️ The @FetchRequest property wrapper in the ContentView requires a sort descriptor
request.sortDescriptors = [NSSortDescriptor(key: "createdAt", ascending: true)]
return request
}
}
@randomor
Copy link
Author

randomor commented Jul 13, 2020

Not exactly sure if this is the right way to do it but it worked for me. Remember to add your .xcdatamodelId file to pair with your core data config. Also add the right entitlement for your app including iCloud CloudKit and remote notifications.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment