1
votes

i have list of brands stored in Core Data, each brand is associated with multiple contents. The contents have a flag called downStatus which is used to denote whether a content is downloaded or not. The following method is used to fetch all the brands from Core data sorted with brand name

-(void)getDownloadedBrands{

AppDelegate *aAppDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

NSMutableArray *aBrands = [[NSMutableArray alloc] init];


NSEntityDescription *entity =
[NSEntityDescription entityForName:@"Brand" inManagedObjectContext:aAppDelegate.managedobjectcontext];
 NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];

NSSortDescriptor *sort=[[NSSortDescriptor alloc]initWithKey:@"brandName" ascending:YES];
//NSSortDescriptor *sort1=[[NSSortDescriptor alloc]initWithKey:@"downStatus" ascending:YES];

[request setSortDescriptors:[NSArray arrayWithObjects:sort, nil]];

aBrands =(NSMutableArray *)[aAppDelegate.managedobjectcontext executeFetchRequest:request error:nil];
[request release];
[sort release];
NSLog(@"%@",aBrands);

brands = [[NSMutableArray alloc]initWithArray:aBrands];

aAppDelegate.dbBrandArr = brands;

[self loadGridView];

}

Now i want to sort using the downStatus which is in the Content. So it will be like, downloaded brands in Alphabetical Order and then Un-Downloaded brands in Alphabetical order. The downStatus takes two values 1 for downloaded 0 for not downloaded. Please help.

2

2 Answers

1
votes

One way to do it is by making 2 fetchRequests to CoreData using the NSPredicate with value 1/0 on downStatus property and using the same alphabetical sortDescriptor.

Now create a new Array by adding the 0 array to the 1 array. In your code it would look something like this:

-(void)getDownloadedBrands{
    AppDelegate *aAppDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

    //2 arrays
    NSMutableArray *aBrands0 = [[NSMutableArray alloc] init];
    NSMutableArray *aBrands1 = [[NSMutableArray alloc] init];
    //set entity en make requests
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Brand" inManagedObjectContext:aAppDelegate.managedobjectcontext];
    NSFetchRequest *request0 = [[NSFetchRequest alloc] init];
    NSFetchRequest *request1 = [[NSFetchRequest alloc] init];
    [request0 setEntity:entity];
    [request1 setEntity:entity];
    //create sortDescriptor alphabetically
    NSSortDescriptor *sort=[[NSSortDescriptor alloc]initWithKey:@"brandName" ascending:YES];
    //create predicates on downStatus property
    NSPredicate *predicate0 = [NSPredicate predicateWithFormat:@"downStatus == %@", [NSNumber numberWithBool:0]];
    NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"downStatus == %@", [NSNumber numberWithBool:1]];
    //set predicates to the requests
    [request0 setPredicate:predicate0];
    [request1 setPredicate:predicate1];
    //set sortDescriptor to both requests
    [request0 setSortDescriptors:[NSArray arrayWithObjects:sort, nil]];
    [request1 setSortDescriptors:[NSArray arrayWithObjects:sort, nil]];
    //fetch arrays with downStatus 1/0
    aBrands0 =(NSMutableArray *)[aAppDelegate.managedobjectcontext executeFetchRequest:request0 error:nil];
    aBrands1 =(NSMutableArray *)[aAppDelegate.managedobjectcontext executeFetchRequest:request1 error:nil];
    //release requests // NOT USING ARC??
    [request0 release];
    [request1 release];
    [sort release];
    //log results
    NSLog(@"aBrands0: %@",aBrands0);
    NSLog(@"aBrands1: %@",aBrands1);
    //add object 0 array to 1 array
    NSArray *combinedArray = [aBrands1 arrayByAddingObjectsFromArray:aBrands0];
    //copy array to brands
    brands = [[NSMutableArray alloc]initWithArray:combinedArray];
    //set property on appDelegate
    aAppDelegate.dbBrandArr = brands;
    //reload tableView
    [self loadGridView];
}

-- edit, adding answer for NSDictionary with downStatus key

-(void)getDownloadedBrands{
    AppDelegate *aAppDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

    NSMutableArray *aBrands = [[NSMutableArray alloc] init];


    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Brand" inManagedObjectContext:aAppDelegate.managedobjectcontext];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];

    NSSortDescriptor *sort=[[NSSortDescriptor alloc]initWithKey:@"brandName" ascending:YES];
    //NSSortDescriptor *sort1=[[NSSortDescriptor alloc]initWithKey:@"downStatus" ascending:YES];

    [request setSortDescriptors:[NSArray arrayWithObjects:sort, nil]];

    aBrands =(NSMutableArray *)[aAppDelegate.managedobjectcontext executeFetchRequest:request error:nil];

    NSMutableArray *aBrands0 = [[NSMutableArray alloc] init];
    NSMutableArray *aBrands1 = [[NSMutableArray alloc] init];
    for (NSDictionary *dict in aBrands) {
        if ([dict valueForKeyPath:@"downStatus"] == YES)
        {
            //add to 1 array
            [aBrands1 addObject:dict];
        }
        else
        {
            //add to 0 array
            [aBrands0 addObject:dict];
        }
    }

    //sort arrays
    NSArray * array1 = [aBrands1 sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
    NSArray * array0 = [aBrands0 sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
    NSArray * allArray = [aBrands1 arrayByAddingObjectsFromArray:aBrands0];

    //combine arrays

    //copy array to brands
    brands = [[NSMutableArray alloc]initWithArray:combinedArray];
    //set property on appDelegate
    aAppDelegate.dbBrandArr = brands;
    //reload tableView
    [self loadGridView];

    [request release];
    [sort release];
    NSLog(@"%@",aBrands);
}
0
votes

If you plan to use the fetch result in a UITableViewController, you could use the sectionNameKeyPath of your fetchedResultsController for the downStatus and keep your sort descriptor for the brand name. Can look like this:

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@"customSectionTitle" cacheName:nil];

Place this in the header file of your NSManagedObject :

-(NSString*)customSectionTitle;

And this in .m :

-(NSString*)customSectionTitle{
    if ([downStatus boolValue] == YES) {
        return @"Downloaded";
    }
    else {return @"Not Downloaded";}
}

If you do not plan to use a fetchedResultsController, just sort first by downStatus and then by brand name.