我的亲戚如下图所示。
我想先按正在进行促销的活动排序,然后按开始日期排序。如果当前日期介于开始日期和结束日期之间,则升级处于活动状态。不幸的是,由于CoreData的原因,我无法使用瞬态属性进行排序。在我的控制器中,我没有使用fetch控制器。
有什么办法可以做到这一点吗?
更新:
我有以下排序描述符:
// First is incorrect
[NSSortDescriptor(key: "promotion.start", ascending: false),
NSSortDescriptor(key: "start", ascending: true)]
谓词(不过,它们没问题):
let promotionsPredicate =
NSPredicate(format: "(%@ >= promotion.start && %@ <= promotion.end) && " +
"(ANY promotion.cities.id == %@)", NSDate(), NSDate(), objectID)
let eventsPredicate =
NSPredicate(format: "start >= %@ && venue.city.id == %@",
NSDate(), objectID)
let subpredicates = [eventsPredicate, promotionsPredicate]
let compoundPredicate NSCompoundPredicate(orPredicateWithSubpredicates: subpredicates)
这就是请求(我使用的是CoreStore,但想法应该很清楚):
class func pagedEventsForPredicateSortedByInPromoAndStartDate(predicate: NSPredicate,
descriptors: [NSSortDescriptor],
fetchOffset: Int,
fetchLimit: Int) -> [Event] {
return CoreStore.fetchAll(From(Event),
Where(predicate),
OrderBy(descriptors),
Tweak { (fetchRequest) -> Void in
fetchRequest.fetchOffset = fetchOffset
fetchRequest.fetchLimit = fetchLimit
fetchRequest.returnsObjectsAsFaults = false
}) ?? []
}
最佳答案
据我所知,你必须得到所有的Event
对象,但只是在适当的顺序。要以如此复杂的顺序完成这项工作,包括关系,据我所知,您必须获取所有事件,然后使用NSArray's
方法对它们进行排序
- (NSArray<ObjectType> *)sortedArrayUsingComparator:(NSComparator)cmptr
下面是代码片段
一。从核心数据获取
// get the right context here
NSManagedObjectContext *yourContext;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Event"];
// extra line, predicate is nil by default, any other required predicate could be written here
request.predicate = nil;
__block NSArray *results = nil;
[yourContext performBlockAndWait:^{
NSError *error = nil;
results = [yourContext executeFetchRequest:request error:&error];
if (error) {
// handle error here
}
}];
Fetch是用核心方法手动生成的,您可以使用
Magical Record
或任何其他与核心数据一起工作的框架将其排成一行。2。对结果排序
__weak typeof(self) weakSelf = self;
NSDate *now = [NSDate date];
NSArray *sortedResults = [results sortedArrayUsingComparator:^NSComparisonResult(Event *_Nonnull obj1, Event *_Nonnull obj2) {
BOOL isObj1InActivePromotion = [weakSelf date:now isBetweenDate:obj1.promotion.start andDate:obj1.promotion.end];
BOOL isObj2InActivePromotion = [weakSelf date:now isBetweenDate:obj2.promotion.start andDate:obj2.promotion.end];
// if they eather are in active promotion or no, just compare them by start date of the Event
if (isObj1InActivePromotion == isObj2InActivePromotion) {
return [obj1.start compare:obj2.start];
} else {
return isObj1InActivePromotion ? NSOrderedAscending : NSOrderedDescending;
}
}];
三。使用NSDate的附加方法
此方法用于排序方法
+ (BOOL)date:(NSDate *)date isBetweenDate:(NSDate *)beginDate andDate:(NSDate *)endDate
{
if ([date compare:beginDate] == NSOrderedAscending) {
return NO;
}
if ([date compare:endDate] == NSOrderedDescending) {
return NO;
}
return YES;
}
由于明显的原因,我无法检查代码,因此很抱歉有任何错误。
关于ios - CoreData按关系排序,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37499548/