Jeff Ericson
Jeff Ericson

Reputation: 71

Swift & Core Data unwrapping fetchedresults

I'm pretty new to iOS and trying to understand how to work with Core Data. The basic challenge I struggle with is accessing the data from a fetchResult outside of a view, as if it were in an array or a database query result (which I thought this was)
Example:

Core Data Entity Foo has a 1:1 relationship with Core Data Entity Bar. I create a new Foo that needs to attach to an existing Bar.

I do a fetch<Bar> with a predicate that returns a fetchedResult object. I need to get access to the Bar object inside the fetchedResult object so that I can assign it:

newFoo.bar = fetched<Bar> doesn't work, and I can't figure out how to get to the Bar - I've spent probably 10 hours going through tutorials and Apple docs and can't find any way to unwrap it or access it - convert it or access it as if it were just a simple array of objects.

At this point I'm about to give up - I'm creating duplicate classes for the entities and when the app inits I load ALL of the Core Data from every entity and map it to Arrays that can be easily accessed, then just update Core Data with changes. That can't be how this is supposed to work.

What am I missing? This should be easy.

EDIT=========================== Added a simplified code section:

import Foundation
import CoreData

struct Create: View {
    @Environment(\.managedObjectContext) var viewContext
    @EnvironmentObject var show: ViewLogic

    func newOnDemand() {
        let newT = T(context: viewContext)
        let newS = S(context: viewContext)

        let existingPlace = Place.idRequest(id: placeId) <-- returns fetchedResults<Place>, I need Place or [Place]

        newT.place = existingPlace      <--- Place object required here. HOW?
        newT.S = newS                   <--- New Objects. Simple.
        do {
//              print("Saving session...")
              try viewContext.save()
          } catch let error as NSError {
              print("Failed to save session data! \(error): \(error.userInfo)")
          }

=========================== fetch
class Place: 
static func idRequest(id: UUID) -> NSFetchRequest<Place> {
        let request: NSFetchRequest<Place> = Place.fetchRequest()
            request.predicate = NSPredicate(format: "id == %@", id)
            request.sortDescriptors = [NSSortDescriptor(key: "sortOrder", ascending: true)]
          request.fetchLimit = 1    // use to specify specific queries. Position.
        return request

=========================== entity class
import Foundation
import CoreData


extension T {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<T> {
        return NSFetchRequest<T>(entityName: "T")
    }
    @NSManaged public var id: UUID

    @NSManaged public var place: Place?
}

Upvotes: 0

Views: 131

Answers (1)

vadian
vadian

Reputation: 285064

According to the code the method idRequest returns a fetch request, not any fetchresults. You have to call fetch on the managed object context passing the request to fetch the data

let request = Place.idRequest(id: placeId)
do {
   if let existingPlace = try viewContext.fetch(request).first {
      newT.place = existingPlace
      // do other things
   }
} catch {
   print(error)
}

Upvotes: 1

Related Questions