Skip to content

Commit c5742cf

Browse files
author
Joe Page
committed
- fix column sorting including:
> nil objects are sorted above non-nil objects > NSDate column sorting will compare NSDate objects directly > NSNumber column sorting compares NSNumber objects directly > NSSet/NSArray/NSData objects are sorted according to their size (count or length) > no need to create NSString objects anymore for non-string column types
1 parent 79e884d commit c5742cf

2 files changed

Lines changed: 61 additions & 87 deletions

File tree

CoreDataUtil/CoreData/MFLCoreDataIntrospection.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
- (void) executeFetch: (NSFetchRequest *)fetch;
6464

6565
- (void)sortEntityData:(NSString *)fieldName;
66-
+ (id)getDisplayValueForObject:(id)obj dateStyle:(NSDateFormatterStyle) dateStyle;
66+
+ (id)getDisplayValueForObject:(id)obj;
6767
- (NSInteger)getCurrentHistoryIndex;
6868
- (void)setCurrentHistoryIndex:(NSInteger)currentIndex;
6969
- (void)updateCoreDataHistory:(NSString *)name predicate:(NSPredicate *)predicate objectType:(MFLObjectType)type;

CoreDataUtil/CoreData/MFLCoreDataIntrospection.m

Lines changed: 60 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,16 @@ - (void)loadObjectModel
7070
// Success
7171
[self.delegate onLoadObjectModelSuccess];
7272
} else if (self.momFileUrl == nil) {
73+
NSLog(@"Could not load Object File because it was nil!");
7374
NSError* error = [self errnoErrorWithReason:@"Could not load Object File because it was nil!"];
7475
[self.delegate onLoadObjectModelFailedWithError:error];
76+
return;
7577
} else {
7678
// Unknow Failure. Maybe the file was not a valid object model file
79+
NSLog(@"Could not load Object File: %@", self.momFileUrl);
7780
NSError* error = [self errnoErrorWithReason:[NSString stringWithFormat:@"Failed to load: %@. Make sure it is a valid Object Model file.", self.momFileUrl]];
7881
[self.delegate onLoadObjectModelFailedWithError:error];
79-
82+
return;
8083
}
8184
}
8285

@@ -229,106 +232,77 @@ - (void) executeFetch: (NSFetchRequest *)fetch {
229232
self.entityData = [self.context executeFetchRequest:fetch error:NULL];
230233
}
231234

232-
- (void)sortEntityData:(NSString *)fieldName
233-
{
234-
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
235-
[formatter setDateStyle:self.dateStyle];
236-
[formatter setTimeStyle:self.dateStyle];
237-
238-
SEL comparisonSelector = nil;
239-
235+
- (void)sortEntityData:(NSString *)fieldName {
236+
BOOL isStringColumn = NO;
237+
240238
// Put values for selected column into a dictionary with their current row number as the key
241-
NSMutableDictionary *columnObjs = [[NSMutableDictionary alloc] init];
239+
NSMutableDictionary *columnObjs = [[NSMutableDictionary alloc] initWithCapacity:[self.entityData count]];
242240
NSInteger rowNum = 0;
243-
for (NSArray *row in self.entityData)
244-
{
245-
id valueObj = [MFLCoreDataIntrospection getDisplayValueForObject:[row valueForKey:fieldName] dateStyle:self.dateStyle];
246-
if ([valueObj isKindOfClass:[NSString class]] && [formatter dateFromString:valueObj])
247-
{
248-
valueObj = [formatter dateFromString:valueObj];
241+
for (NSArray *row in self.entityData) {
242+
id obj = [row valueForKey:fieldName];
243+
// check if this is column is NSString
244+
if (!isStringColumn && [obj isKindOfClass:[NSString class]]) {
245+
isStringColumn = YES;
249246
}
250-
251-
if (comparisonSelector == nil && [valueObj isKindOfClass:[NSString class]]) {
252-
comparisonSelector = @selector(caseInsensitiveCompare:);
247+
248+
id valueObj = obj;
249+
250+
// change values of non-native/sortable objects for easier sorting
251+
if (obj == nil) {
252+
valueObj = [NSNull null];
253253
}
254-
255-
columnObjs[[NSString stringWithFormat:@"%ld", rowNum]] = valueObj;
254+
if ([obj isKindOfClass:[NSSet class]]) {
255+
NSSet* mySet = obj;
256+
valueObj = @([mySet count]);
257+
}
258+
else if ([obj isKindOfClass:[NSArray class]]) {
259+
NSArray* myArray = obj;
260+
valueObj = @([myArray count]);
261+
}
262+
else if ([obj isKindOfClass:[NSManagedObject class]]) {
263+
valueObj = [[obj entity] name];
264+
}
265+
else if ([obj isKindOfClass:[NSData class]]) {
266+
NSData* data = (NSData*) obj;
267+
valueObj = @([data length]);
268+
}
269+
270+
// add valueObj to array for sorting
271+
columnObjs[@(rowNum)] = valueObj;
256272
rowNum++;
257273
}
258274

259-
if (comparisonSelector == nil) {
260-
comparisonSelector = @selector(compare:);
261-
}
262-
263275
// sort!
264-
NSArray *sortedColumns = [columnObjs keysSortedByValueUsingSelector:comparisonSelector];
265-
276+
NSArray *sortedColumns = [columnObjs keysSortedByValueUsingComparator:^NSComparisonResult(id obj1, id obj2) {
277+
// handle nil objects by putting them above any non-nil object
278+
if (obj1 == NSNull.null && obj2 == NSNull.null) {
279+
return NSOrderedSame;
280+
}
281+
else if (obj1 == NSNull.null) {
282+
return NSOrderedAscending;
283+
}
284+
else if (obj2 == NSNull.null) {
285+
return NSOrderedDescending;
286+
}
287+
// both objects are NOT nil
288+
else if (isStringColumn) {
289+
return [obj1 caseInsensitiveCompare:obj2];
290+
}
291+
else {
292+
return [obj1 compare:obj2];
293+
}
294+
}];
295+
296+
266297
// Move the sorted values back into an array
267298
NSMutableArray *temp = [[NSMutableArray alloc] init];
268-
for (NSString *oldRowNum in sortedColumns)
299+
for (NSNumber *oldRowNum in sortedColumns)
269300
{
270-
[temp addObject:(self.entityData)[[oldRowNum integerValue]]];
301+
[temp addObject:(self.entityData)[(NSUInteger)[oldRowNum integerValue]]];
271302
}
272303
self.entityData = temp;
273304
}
274305

275-
+ (id)getDisplayValueForObject:(id)obj dateStyle:(NSDateFormatterStyle) dateStyle
276-
{
277-
if (obj == nil)
278-
{
279-
return @"";
280-
}
281-
else if ([obj isKindOfClass:[NSSet class]])
282-
{
283-
NSSet* mySet = obj;
284-
NSString *cellText = @"0";
285-
if (mySet && [mySet count] > 0)
286-
{
287-
cellText = [NSString stringWithFormat:@"%lu", [mySet count]];
288-
}
289-
290-
return cellText;
291-
}
292-
else if ([obj isKindOfClass:[NSArray class]])
293-
{
294-
NSArray* myArray = obj;
295-
NSString *cellText = @"0";
296-
if (myArray && [myArray count] > 0)
297-
{
298-
cellText = [NSString stringWithFormat:@"%lu", [myArray count]];
299-
}
300-
301-
return cellText;
302-
}
303-
else if ([obj isKindOfClass:[NSManagedObject class]])
304-
{
305-
return [[obj entity] name];
306-
}
307-
else if ([obj isKindOfClass:[NSDate class]])
308-
{
309-
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
310-
[dateFormatter setDateStyle:dateStyle];
311-
[dateFormatter setTimeStyle:dateStyle];
312-
313-
NSString *dateString = [dateFormatter stringFromDate:obj];
314-
return dateString;
315-
}
316-
else if ([obj isKindOfClass:[NSData class]])
317-
{
318-
NSData* data = (NSData*) obj;
319-
320-
return [NSString stringWithFormat:@"%ld bytes", [data length]];
321-
}
322-
else if ([obj isKindOfClass:[NSNumber class]]) {
323-
NSNumber *number = obj;
324-
return [NSString stringWithFormat:@"%f", number.floatValue];
325-
}
326-
else
327-
{
328-
return obj;
329-
}
330-
}
331-
332306
- (NSArray*) keyPathsForEntity:(NSEntityDescription*) entityDescription {
333307

334308
NSMutableArray* keyPaths = [NSMutableArray arrayWithCapacity:0];

0 commit comments

Comments
 (0)