【发布时间】:2017-03-16 09:51:10
【问题描述】:
摘要
我希望能够创建一个基于来自核心数据实体的 fetchRequest 中的表达式的新值。
拥有具有此属性的实体(短版)
Name Attributes
[Course] -> {licenseStart, name, id}
我想在该实体上创建一个 fetchResquest 并检索一个字典,其中包含所有属性以及一个基于此表达式的更多属性:
licenseStart.doubleValue / 1000 < NSDate().timeIntervalSince1970 ? "Actually" : "Cooming Soon"
所以结果会是:
[ "licenseStart":1,"id":3, "name":"A", "status":0, ...
"licenseStart":2,"id":4, "name":"B", "status":0, ...
"licenseStart":3,"id":6, "name":"B", "status":0, ...
"licenseStart":4,"id":2, "name":"C", "status":0, ...
"licenseStart":5,"id":1, "name":"D", "status":1, ...
"licenseStart":6,"id":7, "name":"E", "status":1, ...
]
发布
我想针对几天以来一直面临的问题提出一个问题。我尝试过的每种方法最终都会得到更复杂的解决方案。
让我给你解释一下情况:
我有一个具有不同属性的实体的 CoreData 模型,其中一个是 license start 这是一个 unix 时间戳编号,用于确定课程何时开始。
所以,当我想填充数据以创建带有课程的 UITableView 时,我从数据库中毫无问题地获取所有这些信息,我使用此 licenseStart 属性来计算基于的部分在公式上,这是 UITableView 的代码
UITableViewController
let entity = NSEntityDescription.entityForName("Course", inManagedObjectContext: managedObjectContext!)
let req = NSFetchRequest()
let predicate = sectionProtocol?.FRCPredicate
let sort = [NSSortDescriptor(key: "licenseStart", ascending: true), NSSortDescriptor(key: "name", ascending: true), NSSortDescriptor(key: "courseId", ascending: true)]
req.entity = entity
req.sortDescriptors = sort
req.predicate = predicate
/* NSFetchedResultsController initialization
a 'nil' 'sectionNameKeyPath' generates a single section */
var aFetchedResultsController = NSFetchedResultsController(fetchRequest: req, managedObjectContext: managedObjectContext!, sectionNameKeyPath:"dateStatus", cacheName: nil)
在这之后我的结果(小例子)是这样的
[ "licenseStart":1,"id":3, "name":"A",...
"licenseStart":2,"id":4, "name":"B",...
"licenseStart":3,"id":6, "name":"B",...
"licenseStart":4,"id":2, "name":"C",...
"licenseStart":5,"id":1, "name":"D",...
"licenseStart":6,"id":7, "name":"E",
]
我将在 UITableView 中拥有的是:
[Actually]
[A]
[B]
[B]
[C]
[Cooming Soon]
[D]
[E]
所以,我现在要做的是使用 licenseStart 创建两个部分,如何?很简单,只需使用我的模型的一个名为 dateStatus 的属性并创建两个可能使用许可开始的结果如下:
模型类
var dateStatus : Int {
get {
return licenseStart.doubleValue / 1000 < NSDate().timeIntervalSince1970 ? "Actually" : "Cooming Soon"
}
}
所以在我的 UITableView 中,我再次使用 dataSource 委托方法来填充行和部分。
问题
到目前为止,一切都很完美。但是现在我想添加一个排序选项,让用户对结果进行升序或降序排序,问题是当我排序时,即使用不同的排序选项升序:
let entity = NSEntityDescription.entityForName("Course", inManagedObjectContext: managedObjectContext!)
let req = NSFetchRequest()
let predicate = sectionProtocol?.FRCPredicate
let sort = [NSSortDescriptor(key: "licenseStart", ascending: true), NSSortDescriptor(key: "name", ascending: false), NSSortDescriptor(key: "courseId", ascending: false)]
req.entity = entity
req.sortDescriptors = sort
req.predicate = predicate
/* NSFetchedResultsController initialization
a 'nil' 'sectionNameKeyPath' generates a single section */
var aFetchedResultsController = NSFetchedResultsController(fetchRequest: req, managedObjectContext: managedObjectContext!, sectionNameKeyPath:"dateStatus", cacheName: nil)
由于我基于 licenseStart 创建部分的方式,此提取的结果将与以前完全相同:
[ "licenseStart":1,"id":3, "name":"A",...
"licenseStart":2,"id":4, "name":"B",...
"licenseStart":3,"id":6, "name":"B",...
"licenseStart":4,"id":2, "name":"C",...
"licenseStart":5,"id":1, "name":"D",...
"licenseStart":6,"id":7, "name":"E",
]
我将在 UITableView 中拥有的是:
[Actually]
[A]
[B]
[B]
[C]
[Coming Soon]
[D]
[E]
为什么?因为 licenseStart 都是不同的,它使用 NSSortDescriptors 中的第一个元素来检索数据。这不是我想要的行为,我想要的是让这些部分的顺序与以前完全相同,但里面的元素排列不同
即:
[Actually]
[C]
[B]
[B]
[A]
[Coming Soon]
[E]
[D]
可能的解决方案
我的想法是在 fetchrequest 期间创建一个新列,如果我能够在检索数据时评估此表达式 licenseStart.doubleValue / 1000 < NSDate().timeIntervalSince1970 ? 0 : 1,我将在结果中拥有这个带有 0 和 1 的新列:
[ "licenseStart":1,"id":3, "name":"A", "status":0, ...
"licenseStart":2,"id":4, "name":"B", "status":0, ...
"licenseStart":3,"id":6, "name":"B", "status":0, ...
"licenseStart":4,"id":2, "name":"C", "status":0, ...
"licenseStart":5,"id":1, "name":"D", "status":1, ...
"licenseStart":6,"id":7, "name":"E", "status":1, ...
]
现在我可以使用这个 status 在 NSSortDescriptors 中创建部分,[NSSortDescriptor(key: "status", ascending: true),NSSortDescriptor(key: "licenseStart", ascending: true), NSSortDescriptor(key: "name", ascending: true), NSSortDescriptor(key: "courseId", ascending: true)] 用于升序,[NSSortDescriptor(key: "status", ascending: true),NSSortDescriptor(key: "licenseStart", ascending: false), NSSortDescriptor(key: "name", ascending: false), NSSortDescriptor(key: "courseId", ascending: false)] 用于降序。
这会给我我想要的行为.. 但我还没有找到一种好的和干净的方法来做到这一点。我尝试使用 NSExpressions 来执行此操作,但我不能将 小于 与 CoreData fetch 一起使用..
另外,一个可能的解决方案是在我的数据模型中创建这个新列并在保存数据时生成这个值,但这不是一种有效的方法,因为每次用户填充时,这个 licenseStart 值都必须与当前时间戳进行比较这张表。
我在问是否有人对此问题有一个简短的想法或聪明的解决方案。
在 MySQL 或 SQLite 中,基于某个值或表达式创建新列很容易,但在 coredata 中,我是新手,所以我没有看到明确的方法。
非常感谢。
【问题讨论】:
-
这是一个很长的问题。您能否在某处(可能在顶部)放置一个摘要,显示您想要实现的最终结果以及您实际得到的结果。这似乎有点像意识流 - 有助于让你的想法下降,但很难看出实际问题是什么。
-
添加了总结,感谢@AshleyMills 的反馈:)
标签: ios swift uitableview core-data nsfetchedresultscontroller