Core Data对象数组获取及特定列表关联单词筛选求助
Hey Jeroen! Great work building an app to support kids with dyslexia—super impactful stuff. Let's fix those two Core Data issues you're running into:
问题1:将Core Data对象获取到数组中
You're actually already doing this correctly in your code, but let's clarify the two main reliable ways to get Core Data objects into an array:
Using
NSFetchedResultsController(your current approach)
ThefetchedObjectsproperty ofNSFetchedResultsControllerreturns an optional array of your fetched managed objects. You're properly unwrapping it here:if let fetchedObjects = fetchResultController.fetchedObjects { woordeninlijst = fetchedObjects }This is perfect for table views because the FRC automatically syncs your UI with Core Data changes—you're already using its delegate methods to handle inserts/deletes, which is exactly the right move.
Direct fetch with
NSManagedObjectContext
If you ever need to fetch objects without an FRC (for one-off operations), you can call thefetch(_:)method directly on the context:do { let woorden = try context.fetch(fetchRequest) woordeninlijst = woorden } catch { print("Fetch error: \(error)") }Stick with the FRC for your table view though—it takes care of all the heavy lifting for UI updates.
问题2:过滤获取特定列表的单词集合
The missing piece here is adding a predicate to your fetch request to filter WoordMO objects where their zitInLijst relationship matches the current lijst you're viewing. Here's how to implement this:
Step 1: Add the filter predicate to your fetch request
In viewDidLoad(), right after setting the sort descriptor, add this line to target only words linked to the current list:
let fetchRequest: NSFetchRequest<WoordMO> = WoordMO.fetchRequest() let sortDescriptor = NSSortDescriptor(key: "naam", ascending: true) fetchRequest.sortDescriptors = [sortDescriptor] // Add this predicate to filter words for the active list let predicate = NSPredicate(format: "zitInLijst == %@", lijst) fetchRequest.predicate = predicate
The predicate zitInLijst == %@ tells Core Data to only fetch WoordMO objects where their zitInLijst property is exactly the lijst object passed to this view controller.
Step 2: Verify your Core Data relationship setup
Double-check your model to ensure the relationships are correctly configured:
LijstMOshould have a to-many relationship toWoordMO(e.g., namedwoorden)WoordMOshould have a to-one relationship back toLijstMO(namedzitInLijst, with the inverse set towoorden)
You're already settingwoord.zitInLijst = lijstwhen saving new words, so that part is spot-on!
Step 3: Optional: Handle list switching (if needed)
If you ever need to switch the list being displayed, you can update the fetch request's predicate and re-fetch:
func updateFetchRequest(for newLijst: LijstMO) { guard let fetchRequest = fetchResultController.fetchRequest as? NSFetchRequest<WoordMO> else { return } fetchRequest.predicate = NSPredicate(format: "zitInLijst == %@", newLijst) do { try fetchResultController.performFetch() if let fetchedObjects = fetchResultController.fetchedObjects { woordeninlijst = fetchedObjects } tableView.reloadData() } catch { print("Re-fetch error: \(error)") } }
Updated viewDidLoad() snippet
Here's how your full updated viewDidLoad will look with the filter added:
override func viewDidLoad() { super.viewDidLoad() title = lijst.naam self.woordTextField.delegate = self let fetchRequest: NSFetchRequest<WoordMO> = WoordMO.fetchRequest() let sortDescriptor = NSSortDescriptor(key: "naam", ascending: true) fetchRequest.sortDescriptors = [sortDescriptor] // Filter words to only those in the current list let predicate = NSPredicate(format: "zitInLijst == %@", lijst) fetchRequest.predicate = predicate if let appDelegate = (UIApplication.shared.delegate as? AppDelegate) { let context = appDelegate.persistentContainer.viewContext fetchResultController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) fetchResultController.delegate = self do { try fetchResultController.performFetch() if let fetchedObjects = fetchResultController.fetchedObjects { woordeninlijst = fetchedObjects } } catch { print(error) } } self.navigationItem.rightBarButtonItem = self.editButtonItem }
That should resolve your issue—now only words linked to the active lijst will be fetched and displayed in your table view.
内容的提问来源于stack exchange,提问作者Jeroen De Bruin

