Created
January 3, 2020 14:57
-
-
Save thijsnado/a84673e84409064efaec0069cba1cc7f to your computer and use it in GitHub Desktop.
An example of how to easily use previews with SwiftUI views that query core data.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if DEBUG | |
import CoreData | |
import SwiftUI | |
/// A protocol for allowing easy use of CoreData | |
/// with preview provider. | |
/// | |
/// NOTE: you must still | |
/// make preview comply with PreviewProvider: | |
/// ``` | |
/// struct OurPreview: CoreDataPreviewProvider, PreviewProvider { | |
/// static var body: some View { | |
/// // your view code | |
/// } | |
/// | |
/// static func setupDb(_ context: NSManagedObjectContext) { | |
/// // setup db | |
/// } | |
/// } | |
/// ``` | |
/// | |
/// This helper is also unnecessary if you are passing in core data objects manually | |
/// instead of trying to query them using a fetched results controller. | |
protocol CoreDataPreviewProvider { | |
associatedtype Body: View | |
/// CoreDataPreviewProvider calls body to generate | |
/// previews method and automatically attach core data context to | |
/// environment | |
static var body: Body { get } | |
/// A clean contextObject will be sent to setupDB and can be | |
/// used to seed records for sake of previewing | |
/// | |
/// Example usage: | |
/// ``` | |
/// func setupDb(_ context: NSManagedObjectContext) { | |
/// let user = User(context: Context) | |
/// user.name = "Joe" | |
/// | |
/// try! context.save() | |
/// } | |
/// | |
static func setupDb(_ context: NSManagedObjectContext) | |
} | |
extension CoreDataPreviewProvider { | |
/// Don't override this method. Instead set body static method and | |
/// it will be called and setup with core data. | |
static var previews: some View { | |
let context = buildContextWithSetupData() | |
return body.environment(\.managedObjectContext, context) | |
} | |
private static func buildContextWithSetupData() -> NSManagedObjectContext { | |
let context = cleanPreviewContext() | |
setupDb(context) | |
return context | |
} | |
/// Iterates over all entities and destroys records, as well as resetting context and returning it | |
private static func cleanPreviewContext() -> NSManagedObjectContext { | |
let container = (UIApplication.shared.delegate as! AppDelegate).persistentContainer | |
let context = container.viewContext | |
context.reset() | |
try! container.managedObjectModel.entities.forEach { entity in | |
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entity.name!) | |
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest) | |
context.reset() | |
try context.execute(deleteRequest) | |
} | |
return context | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment