我正在尝试使用 NSSortdescriptor 使用指向 NSDate 值的键对 NSFetchRequest 结果进行排序。我的获取结果完全随机,没有明确的原因。
我正在使用的 NSManagedObjectContext 是通过在 NSOperation 子类上创建的嵌套子上下文中保存的内容进行更新的。我知道这一切都成功完成,因为我可以从父(主)上下文获取所需的所有数据。从它获取只是不会按日期排序!
奇怪的是;用于选择两个日期之间的实体(称为“推文”)的谓词效果很好!
这是一些代码来说明我的问题:
NSSortDescriptor* timeDescriptor = [NSSortDescriptor
sortDescriptorWithKey:@"time"
ascending:NO
selector:@selector(compare:)];
NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Tweet"];
[request setSortDescriptors:[NSArray arrayWithObjects:timeDescriptor, nil]];
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"((time >= %@) AND (time <= %@))",startDate,endDate];
[request setPredicate:predicate];
NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext:[[NSApp delegate] managedObjectContext]];
[context performBlock:^{
NSError* error = nil;
NSArray* results = nil;
results = [context executeFetchRequest:request error:&error];
// Results here are not ordered correctly
// 2nd try sorting results …Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我试图列出四种最受欢迎的产品。
产品受欢迎程度由订单总量决定。
下面的查询是为了说明我想要做什么:
SELECT TOP 4 SUM(quantity) as sumQuantity, Product
FROM [Order]
GROUP BY Product
ORDER BY 1 DESC
Run Code Online (Sandbox Code Playgroud)
下面的代码是我在针对核心数据模型的获取请求中获取它的方法:
// Create an expression to sum the order quantity
NSExpressionDescription *sumExpression = [[NSExpressionDescription alloc] init];
sumExpression.name = @"sumQuantity";
sumExpression.expression = [NSExpression expressionWithFormat:@"@sum.%K", OrderAttributes.quantity];
sumExpression.expressionResultType = NSInteger32AttributeType;
// Create the fetch request
NSFetchRequest *request = [Order createFetchRequest];
request.resultType = NSDictionaryResultType;
request.propertiesToFetch = @[OrderRelationships.product, sumExpression];
request.propertiesToGroupBy = @[OrderRelationships.product];
request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:sumExpression.name ascending:NO]];
request.fetchLimit = 4;
Run Code Online (Sandbox Code Playgroud)
我的问题是 sortDescriptor,它似乎只允许 Order 的直接属性(应用程序例外)。
排序非常重要,因为它决定将返回哪四个记录。
注意:我正在使用 …
我有一个我精心设计的块谓词,只是为了发现你不能在核心数据中使用它们。
NSPredicate *rootContactPredicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
BOOL isPersonAndRoot = ([[[evaluatedObject entity] name] isEqualToString:@"Person"] && [[(Person*)evaluatedObject accounts] count] == 0);
BOOL isAccountAndRoot = ([[[evaluatedObject entity] name] isEqualToString:@"Account"] && [(Account*)evaluatedObject root] == nil);
return isPersonAndRoot || isAccountAndRoot;
}];
Run Code Online (Sandbox Code Playgroud)
所以我需要将其转换为标准字符串格式谓词,但我不清楚如何检查评估对象的实体类型。和实体是实体的子类,该Person实体是在获取请求中评估的类型。我希望它能看到子类型。AccountContact
NSPredicate我的 FRC 上有一个fetchRequest。在某个时刻,一个对象被添加到 CoreData,我创建一个新谓词,更新fetchRequest并执行获取:
self.fetchedAddressesController.fetchRequest.predicate = self.predicate;
BOOL success = [self.fetchedAddressesController performFetch:nil];
Run Code Online (Sandbox Code Playgroud)
然而,这不会调用 FRC 的委托方法,例如controllerWillChangeContent:. 而且我的表视图没有更新。
但是,当我添加以下行时:
[self.tableView reloadData];
Run Code Online (Sandbox Code Playgroud)
在上面显示的两个下方,我确实看到了预期的更新。这说明要显示的数据确实发生了变化。
我检查了新的谓词,没有问题。我还将 FRC 设置delegate为self,并且在其他情况下调用其方法。
已经有什么想法可能是错的吗?
我正在尝试获取父母的所有孩子。
在我的例子中,父对象是一个实体 AgendaEvent,它有许多 AgendaDate(子对象)。
所以这是我的功能:
func getRelatedAgendaEvent(event: AgendaEvent) ->NSFetchRequest<AgendaDate> {
// create a fetch request that will retrieve all the AgendaDate.
let fetchRquest = NSFetchRequest<AgendaDate>(entityName: "AgendaDate")
// set the predicate to only keep AgendaDate related with the AgendaEvent selected
fetchRquest.predicate = NSPredicate(format: "parent == %@", event)
return fetchRquest
}
Run Code Online (Sandbox Code Playgroud)
我在 didselectRow 中使用它作为 tableView:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var eventToPass: AgendaEvent!
var eventDateToPassArray: [AgendaDate]!
eventToPass = myTempEvents[indexPath.row]
eventDateToPassArray = try! context.fetch(getRelatedAgendaEvent(event: eventToPass))
DispatchQueue.main.async { () -> Void …Run Code Online (Sandbox Code Playgroud) 在 Swift 4 中,我有一个 CoreData“Sentence”模型,它有一个字符串属性“englishsentence”。我还有一个“单词”数组,并希望获取“englishsentence”属性包含数组中一个或多个单词的所有句子。
var words = ["today", "yesterday", "tomorrow"]
Run Code Online (Sandbox Code Playgroud)
这个数组只是一个例子。它应该在运行时改变并且可以有任何长度。
在 fetch 请求中,我试图做这样的事情:
let fetchRequest =
NSFetchRequest<NSManagedObject>(entityName: "Sentence")
let predicate = NSPredicate(format: "ANY englishsentence CONTAINS ANY word IN %@", words)
fetchRequest.predicate = predicate
Run Code Online (Sandbox Code Playgroud)
我能够为包含一个特定单词的所有句子创建一个谓词。但是,我无法让它与单词数组一起工作,除非我遍历单词数组并为每个单词发出新的获取请求。但这似乎非常低效。
我在 NSFetchedResultsController 中遇到了 fetchBatchSize 问题,所以我决定退后一步,只在普通的 NSFetchRequest 上使用它。我创建了一个非常简单的项目,其中只有一个包含 100 个项目的 tableViewController。项目只有两个属性,itemID 和 itemName。我使用以下方法填充数据数组:
func initializeItems() {
let request = NSFetchRequest<Item>(entityName: "Item")
let messageSort = NSSortDescriptor(key: "itemName", ascending: true)
request.sortDescriptors = [messageSort]
request.fetchBatchSize = 20
do {
let fetchedResults = try context.fetch(request)
if fetchedResults.count > 0 {
self.items = fetchedResults
//self.tableView.reloadData()
}
} catch {
print("Could not fetch \(error)")
}
}
Run Code Online (Sandbox Code Playgroud)
这在 tableViewController 的 viewDidLoad 中调用。上下文定义如下:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
self.context = appDelegate.persistentContainer.viewContext
Run Code Online (Sandbox Code Playgroud)
当我运行应用程序时,表格显示所有行都已完全填充(如滚动条所示)。
我不明白为什么 fetchBatchSize 被忽略了。
文档如下:
提取请求中指定的对象的批量大小。默认值为 0。批量大小为 …
我正在构建一个 SwiftUI 应用程序,它显示一个包含相关日期和持续时间的值列表。目前ContentView只是列出所有值(日期升序)。
我想要实现的是,实体按日期分组并放入其相关部分,例如:
当前的
目的
非常感谢任何帮助,非常感谢。
代码
// MARK: - ContentView
struct ContentView: View {
// MARK: - Variables
@Environment(\.managedObjectContext) var managedObjectContext
@FetchRequest(fetchRequest: EntityCore.fetch()) var entities
// MARK: - Body
var body: …Run Code Online (Sandbox Code Playgroud) 我正在尝试TrainingSessionHistory在我的 SwiftUI 视图之一中对我的(核心数据对象)进行简单的获取请求,但得到了Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
struct TrainingHistoryView: View {
var trainingSession : TrainingSession
init(trainingSession : TrainingSession) {
self.trainingSession = trainingSession
let fetchRequest = FetchRequest(fetchRequest: TrainingSessionHistory.getBy(nb: 2, myTrainingSession: self.trainingSession))
print(fetchRequest.wrappedValue) // -> crash this EXC_BAD_INSTRUCTION
}
Run Code Online (Sandbox Code Playgroud)
TrainingSessionHistoryExtension : 创建获取请求
static func getBy(nb : Int, myTrainingSession : TrainingSession) -> NSFetchRequest<TrainingSessionHistory>{
let request:NSFetchRequest<TrainingSessionHistory> = TrainingSessionHistory.fetchRequest() as! NSFetchRequest<TrainingSessionHistory>
//request.predicate = NSPredicate(format: "trainingSession == %@", myTrainingSession)
request.fetchLimit = nb
let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
request.sortDescriptors = [sortDescriptor]
return …Run Code Online (Sandbox Code Playgroud) 我有一个简单的核心数据实体Story,偶尔会使用网络调用中的最新数据进行更新。此网络调用有时会更新很多很多故事实例,因此我运行一个NSBatchInsertRequest,如下所示。(我使用批量插入的另一个原因是可能需要将许多故事添加到持久存储中。)
问题是用户可能已经将 a 标记Story为收藏夹。当他们这样做时,我设置story.isFavorite = true主线程并保存viewContext。
但是,当发生批量插入时,它会覆盖story.isFavorite,将其设置回false,即使我NSMergeByPropertyObjectTrumpMergePolicy同时在批量插入和视图上下文中使用。我也没有接触story.isFavorite批量插入处理程序,因此我不希望该属性被覆盖。
我认为使用此合并策略进行批量插入的好处是避免首先获取+然后手动更新更改的属性+最后保存。避免更改 中的属性值的正确方法是什么NSBatchInsertRequest?
@objc(Story)
public class Story: NSManagedObject {
@NSManaged public var title: String?
@NSManaged public var storyURL: URL?
@NSManaged public var updatedTime: Date?
@NSManaged public var isFavorite: Bool // <- the problem property
}
Run Code Online (Sandbox Code Playgroud)
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = false
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
context.parent = container.viewContext
context.mergePolicy = …Run Code Online (Sandbox Code Playgroud) core-data nsfetchedresultscontroller nsfetchrequest nsmanagedobject nsmanagedobjectcontext
nsfetchrequest ×10
core-data ×8
ios ×4
swift ×4
objective-c ×3
swiftui ×2
group-by ×1
nsdate ×1
nspredicate ×1
predicate ×1
sorting ×1
xcode ×1