В настоящее время у меня есть два управляемых объекта для основных данных, которые имеют отношение «один ко многим».
Цель
extension Goal {
@nonobjc public class func createFetchRequest() -> NSFetchRequest<Goal> {
return NSFetchRequest<Goal>(entityName: "Goal")
}
@NSManaged public var title: String
@NSManaged public var date: Date
@NSManaged public var progress: NSSet?
}
Прогресс
extension Progress {
@nonobjc public class func createFetchRequest() -> NSFetchRequest<Progress> {
return NSFetchRequest<Progress>(entityName: "Progress")
}
@NSManaged public var date: Date
@NSManaged public var comment: String?
@NSManaged public var goal: Goal
}
Для каждой цели вы можете иметь несколько Progress
объектов. Проблема в том, что когда я запрашиваю выборку для Progress
с конкретным Goal
в качестве предиката, ничего не возвращается. У меня есть подозрение, что я неправильно использую предикат.
Вот как я их запрашиваю.
- Сначала я беру
Goal
для контроллера табличного представления:
var fetchedResultsController: NSFetchedResultsController<Goal>!
if fetchedResultsController == nil {
let request = Goal.createFetchRequest()
let sort = NSSortDescriptor(key: "date", ascending: false)
request.sortDescriptors = [sort]
request.fetchBatchSize = 20
fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: self.context, sectionNameKeyPath: "title", cacheName: nil)
fetchedResultsController.delegate = self
}
fetchedResultsController.fetchRequest.predicate = goalPredicate
do {
try fetchedResultsController.performFetch()
} catch {
print("Fetch failed")
}
И передать результат на следующий экран,
Detail
контроллер просмотра:
if let vc = storyboard?.instantiateViewController(withIdentifier: "Detail") as? DetailViewController {
vc.goal = fetchedResultsController.object(at: indexPath)
navigationController?.pushViewController(vc, animated: true)
}
Наконец, я получаю
Progress
, используя
Goal
в качестве предиката из
Detail
контроллера представления:
var goal: Goal!
let progressRequest = Progress.createFetchRequest()
progressRequest.predicate = NSPredicate(format: "goal == %@", goal)
if let progress = try? self.context.fetch(progressRequest) {
print("progress: \(progress)")
if progress.count > 0 {
fetchedResult = progress[0]
print("fetchedResult: \(fetchedResult)")
}
}
Goal
возвращается правильно, но я ничего не получаю. для Progress
. Я пробовал:
progressRequest.predicate = NSPredicate(format: "goal.title == %@", goal.title)
или
progressRequest.predicate = NSPredicate(format: "ANY goal == %@", goal)
, но результат тот же.
Ниже показано, как я установил связь:
// input for Progress from the user
let progress = Progress(context: self.context)
progress.date = Date()
progress.comment = commentTextView.text
// fetch the related Goal
var goalForProgress: Goal!
let goalRequest = Goal.createFetchRequest()
goalRequest.predicate = NSPredicate(format: "title == %@", titleLabel.text!)
if let goal = try? self.context.fetch(goalRequest) {
if goal.count > 0 {
goalForProgress = goal[0]
}
}
// establish the relationship between Goal and Progress
goalForProgress.progress.insert(progress)
// save
if self.context.hasChanges {
do {
try self.context.save()
} catch {
print("An error occurred while saving: \(error.localizedDescription)")
}
}