我在核心数据中与帖子和标签有很多联系。每个标签有很多帖子,每个帖子有很多标签。我有一个视图控制器,要在其中显示特定标签的所有与其相关的帖子。
我这样做:
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,但感觉必须有一种Core Data方法可以按时间戳对相关对象进行排序
编辑:根据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)'
看起来像将整个对象插入查询字符串。这似乎是错误的,但也许我需要以不同的方式设置对象的格式?
答案 0 :(得分:0)
关键是要使用request.predicate = NSPredicate(format: "%@ IN self.tags", tag)
与request.predicate = NSPredicate(format: "%@ IN Post.tags", tag)
谓词的上下文是Post,所以我认为它不再需要访问。 Self.tags,tag和SELF.tags都可以工作。