Skip to content

Instantly share code, notes, and snippets.

@gh-rusinov
Created September 18, 2020 13:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gh-rusinov/cd3f04cd4fa10f8133b203b91f39d726 to your computer and use it in GitHub Desktop.
Save gh-rusinov/cd3f04cd4fa10f8133b203b91f39d726 to your computer and use it in GitHub Desktop.
import WidgetKit
import SwiftUI
import CoreData
struct Provider: TimelineProvider {
var managedObjectContext : NSManagedObjectContext
init(context : NSManagedObjectContext) {
self.managedObjectContext = context
}
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date())
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date())
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate)
entries.append(entry)
}
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
}
struct SimpleEntry: TimelineEntry {
let date: Date
}
struct BooksWidgetEntryView : View {
var entry: Provider.Entry
@Environment(\.managedObjectContext) var moc
@FetchRequest(entity: Book.entity(), sortDescriptors: [NSSortDescriptor(keyPath: \Book.date, ascending: true)]) var books: FetchedResults<Book>
var body: some View {
Text("Test")
}
}
public extension URL {
/// Returns a URL for the given app group and database pointing to the sqlite database.
static func storeURL(for appGroup: String, databaseName: String) -> URL {
guard let fileContainer = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup) else {
fatalError("Shared file container could not be created.")
}
return fileContainer.appendingPathComponent("\(databaseName).sqlite")
}
}
public enum AppGroup: String {
case facts = "group.app-group-books"
public var containerURL: URL {
switch self {
case .facts:
return FileManager.default.containerURL(
forSecurityApplicationGroupIdentifier: self.rawValue)!
}
}
}
// MARK: - Core Data stack
var persistentContainer: NSPersistentCloudKitContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let storeURL = AppGroup.facts.containerURL.appendingPathComponent("Books")
let description = NSPersistentStoreDescription(url: storeURL)
let container = NSPersistentCloudKitContainer(name: "Books")
container.persistentStoreDescriptions = [description]
description.setOption(true as NSObject, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
}()
@main
struct BooksWidget: Widget {
let kind: String = "BooksWidget"
@Environment(\.managedObjectContext) var moc
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider(context: persistentContainer.viewContext)) { entry in
BooksWidgetEntryView(entry: entry)
.environment(\.managedObjectContext, self.moc)
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
struct BooksWidget_Previews: PreviewProvider {
static var previews: some View {
BooksWidgetEntryView(entry: SimpleEntry(date: Date()))
.previewContext(WidgetPreviewContext(family: .systemSmall))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment