Skip to content

Instantly share code, notes, and snippets.

@kean
Last active February 15, 2020 21:38
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 kean/d7c8bdbd1c350c5c3e58f8e95710bf6c to your computer and use it in GitHub Desktop.
Save kean/d7c8bdbd1c350c5c3e58f8e95710bf6c to your computer and use it in GitHub Desktop.
// The MIT License (MIT)
//
// Copyright (c) 2020 Alexander Grebenyuk (github.com/kean).
import CoreData
final class FetchedEntities<Element: NSManagedObject>: NSObject, NSFetchedResultsControllerDelegate, RandomAccessCollection, ObservableObject {
private let controller: NSFetchedResultsController<Element>
init(context: NSManagedObjectContext, request: NSFetchRequest<Element>) {
self.controller = NSFetchedResultsController<Element>(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
super.init()
self.controller.delegate = self
try? self.controller.performFetch()
}
convenience init<Value>(context: NSManagedObjectContext, sortedBy keyPath: KeyPath<Element, Value>, ascending: Bool = true) {
let request = NSFetchRequest<Element>(entityName: Element.entity().name!)
request.sortDescriptors = [NSSortDescriptor(keyPath: keyPath, ascending: ascending)]
self.init(context: context, request: request)
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
objectWillChange.send()
}
// MARK: - Collection
typealias Index = Int
var startIndex: Index { return controller.fetchedObjects?.startIndex ?? 0 }
var endIndex: Index { return controller.fetchedObjects?.endIndex ?? 0 }
func index(after i: Index) -> Index { i + 1 }
subscript(index: Index) -> Element {
get { return controller.object(at: IndexPath(row: index, section: 0)) }
}
}
// The MIT License (MIT)
//
// Copyright (c) 2020 Alexander Grebenyuk (github.com/kean).
import SwiftUI
import CoreData
struct ConsoleView: View {
@ObservedObject var messages: FetchedEntities<MessageEntity>
var body: some View {
List(messages, id: \.self) { message in
Text(message.text)
}
}
}
struct ConsoleView_Previews: PreviewProvider {
static var previews: some View {
let store = mockMessagesStore
let messages = FetchedEntities<MessageEntity>(context: store.viewContext, sortedBy: \.created)
return ConsoleView(messages: messages)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment