import CoreData import SwiftFoundationExtensions import SwiftUI import os /** Provides access to the results of an `NSFetchRequest` for the `Target` type. Similar to `@FetchRequest` but processes the fetch via `ManagedObjectContextProvider` available in the view's environment. This allows for supporting multiple contexts for an application and routing read operations to specific context instances. Example: ``` @StorageRecords( fetchRequest: ... ) private var records: [MyManagedObjectType] ``` */ @propertyWrapper public struct StorageRecords : DynamicProperty { private let logger: Logger = .loggerFor(StorageRecords.self) /** The fetch request used to retrieve the requested records. */ private let fetchRequest: NSFetchRequest /** Provides a way to retrieve an `NSManagedObjectContext` for the type being fetched. */ @Environment(\.managedObjectContextProvider) private var contextProvider /** Controls the flow of retrieving records and responding to store updates. */ @StateObject private var controller = StorageRecordsController() /** Initializes the wrapper with a `NSFetchRequest`. */ public init(_ fetchRequest: NSFetchRequest) { self.fetchRequest = fetchRequest } public var wrappedValue: [Target] { get { controller.results } nonmutating set { logger.warning("Cannot set value of StorageRecords wrapper: \(String(describing: newValue))") } } /** Called before a view's body is rendered to update our `wrappedValue`. Initializes the underlying controller, executing the requested fetch and starts to monitor the store for changes. */ nonmutating public func update() { do { let context = try contextProvider.viewContext(for: Target.self) try controller.initialize(for: fetchRequest, using: context) } catch { fatalError("Failed to update StorageRecords wrapper during update: \(error.description)") } } }