我在核心数据中与帖子和标签存在多对多关系。每个标签有很多帖子,每个帖子也有很多标签。我有一个 View Controller ,我想在其中显示特定标签的所有与其关联的帖子。
我这样做:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
//2
let fetchRequest: NSFetchRequest<Tag> = Tag.fetchRequest()
//3
fetchRequest.predicate = NSPredicate(format: "Tag.name == %@", tag.name!)
// let sort = NSSortDescriptor(key: "timeStamp", ascending: true)
// fetchRequest.sortDescriptors = [sort]
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil) as? NSFetchedResultsController<Tag>
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
tag = fetchedResultsController.object(at: IndexPath(item: 0, section: 0))
tag = Tag(context: managedContext)
let posts = tag.posts
我底部的帖子对象是一组对象 - 无序。我想要一组按时间戳排序的帖子,它们都属于这个特定的标签,但我不知道如何创建它。
我知道通常要按时间戳对项目进行排序,您会像我在步骤 3 中所做的那样引入 NSSortDescriptor (但已被注释掉)。但我相信这会按标签的时间戳对我的获取请求(标签)进行排序。每个标签没有时间戳,我真正想要排序的是与该标签关联的帖子。所以我不相信这是这样做的方法。
我该如何解决这个问题?我想我可以只使用 swift 但感觉必须有一种核心数据方法来按时间戳对相关对象进行排序
编辑:根据 Paulw11 的建议更新了方法:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
guard let appDelegate =
UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext =
appDelegate.persistentContainer.viewContext
//2
let tagFetchRequest: NSFetchRequest<Tag> = Tag.fetchRequest()
let postFetchRequest: NSFetchRequest<Post> = Post.fetchRequest()
//3
tagFetchRequest.predicate = NSPredicate(format: "%K == %@", #keyPath(Tag.name), tag.name!)
do {
let results = try managedContext.fetch(tagFetchRequest)
tag = results.first
} catch let error as NSError {
print("Tag Fetch error: \(error) description: \(error.userInfo)")
}
guard let tag = tag else { return }
postFetchRequest.predicate = NSPredicate(format: "%@ IN Post.tags", tag)
let sort = NSSortDescriptor(key: "timeStamp", ascending: true)
postFetchRequest.sortDescriptors = [sort]
fetchedResultsController = NSFetchedResultsController(fetchRequest: postFetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
posts = fetchedResultsController.fetchedObjects as! [Post]
firstPostDate = posts.first?.timeStamp as Date?
lastPostDate = posts.last?.timeStamp as Date?
for (i,post) in posts.enumerated() {
let date = post.timeStamp as Date?
let day = date?.days(from: Calendar.current.startOfDay(for: firstPostDate!))
indexMap[day!] = IndexPath(row: i, section: 0)
}
这给出了这个错误消息:
2018-11-29 15:36:56.261887-0800 SweatNetOffline[31250:17419187] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'unimplemented SQL generation for predicate : (<Tag: 0x60000216b2a0> (entity: Tag; id: 0xc36a752f5b05e34c <x-coredata://F02C5E33-89B9-4814-9D1B-8C74CAEC7DA1/Tag/p79> ; data: {
mostRecentThumbnail = nil;
mostRecentUpdate = "2018-12-07 21:47:44 +0000";
name = test;
posts = (
"0xc36a752f5af9e34e <x-coredata://F02C5E33-89B9-4814-9D1B-8C74CAEC7DA1/Post/p48>"
);
uuid = nil;
}) IN Post.tags)'
看起来像是将整个对象插入到查询字符串中。这似乎是错误的,但也许我需要以不同的方式格式化对象?
最佳答案
关键是使用request.predicate = NSPredicate(format: "%@ IN self.tags", tag)
与request.predicate = NSPredicate(format: "%@ IN Post.tags", tag)相反
谓词的上下文是 Post,所以我想它不再需要被访问,这是假设的。 Self.tags、tags 和 SELF.tags 都可以。
关于ios - 如何对CoreData中的相关对象进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53547393/