views:

499

answers:

3

Hi All,

I'm trying to retrieve data from Core Data and put it into a Mutable Array

I have an Entity called 'Stock' and in Properties, attributes called : code, price & description...

How do I get the data stored in these attributes into a simple Mutable Array?


I've added this code...

NSMutableArray *array = [[NSMutableArray alloc]init];
[array addObject:[stock valueForKey:@"code"]];

and I get this error...

'-[NSCFArray insertObject:atIndex:]: attempt to insert nil' 

I have a 'Managed Object Class' called 'Stock' and declared called stock. Am I missing something?


If I do this in the -cellForRowAtIndexPath...

Stock   *stock1  = [fetchedResultsController objectAtIndexPath:indexPath];

array = [[NSMutableArray alloc] init];
[array addObject:stock1.code];

NSLog(@"Filtered List is? %@", array);

In the console I can see these 2 items

'The Filtered array is 810005'
'The Filtered array is 810007

'

What must I do to get these items(810005 & 810007) into an array set up in the -viewDidLoad method? Like it does in the -cellForRowAtIndexPath?

Update

Hi Marcus,

Finally got it working (well, 80%)

I put this in the -cellForRowAtIndexPath

Stock *product = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
{   

    filteredListContent = [NSMutableArray arrayWithObjects:stock1.code, nil];

    product = [self.filteredListContent objectAtIndex:indexPath.row];

    [self configureFilteredCell:cell atIndexPath:indexPath];

    [filteredListContent objectAtIndex:indexPath.row];
    NSLog(@"Filtered List Array List is? %@", stock1.code);
}
else 
{
    listContent = [NSMutableArray arrayWithObjects:stock1.code, nil];
    [self configureCell:cell atIndexPath:indexPath];

    NSLog(@"List Array List is?          %@", stock1.code);
}

Then I used this code in the scope

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    self.savedSearchTerm = searchText;

    if (searchText !=nil)
    {
        NSPredicate *predicate =[NSPredicate predicateWithFormat:@"code beginsWith[cd] %@", searchText];
        [fetchedResultsController.fetchRequest setPredicate:predicate];

    }
    else
    {
        NSPredicate *predicate =[NSPredicate predicateWithFormat:@"code contains[cd] %@", searchText];
        [fetchedResultsController.fetchRequest setPredicate:predicate];
        [self.tableView reloadData];
    }

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error])
    {
        // Handle error
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }           

    [self.tableView reloadData];

Everything is filtering fine but when I hit cancel on the search, it's not reloading the original data...

I won't be defeated...!!

Thanx

+1  A: 

Have you read the documentation? You fetch your Stock instances (all of them or filter them with a predicate), then do with them whatever you please.

You can then add their properties to an array individually:

[array addObject:[stockInstance valueForKey:@"price"];

... or use a combination of < NSKeyValueCoding > protocol methods such as -dictionaryWithValuesForKeys: NSDictionary methods such as -objectsForKeys:notFoundMarker: to get an array for given keys.

This may or may not actually be what you need to do, though. It depends on what you intend to use the resulting array for. If you want a quick sum of all matching Stock instances' "price" values, for example, you can use Set and Array Operators. It really depends on what you're trying to achieve.

Joshua Nozzi
Hi Joshua,I've added this code... NSMutableArray *array = [[NSMutableArray alloc]init]; [array addObject:[stock valueForKey:@"code"]];and I get an error...'-[NSCFArray insertObject:atIndex:]: attempt to insert nil'I have a 'Managed Object Class' called 'Stock' and declared called stockAm I missing something?
Stef
You cannot insert nil into an array. Only real objects (including) [NSNull null]. You should guard against attempting insertion if "code" (or whatever) is nil
Joshua Nozzi
Hi Josh, The only thing is "code" has two item stored... :-(I'll show, hold on...
Stef
Hi Marcus, I have your book in front of me 'Core Data, Data on Mac OS X' On Chapter 4 'Accessing Attributes' That's basically what I'm trying to do. It looks so easy...
Stef
+2  A: 

Since you are having this issue in your -viewDidLoad, I am guessing (and without the code from -viewDidLoad, it is only a guess) that you are trying to fetch objects from the NSFetchedResultsController before the -executeFetch: has been called on the controller and therefore you are in the land of nils.

I would suggest setting a break point in your -viewDidLoad and watching the values and you walk through your code. This will tell you what is nil and where.

Of course a better question is, why are you trying to put NSManagedObject instances into a NSMutableArray? Since they are already in your NSFetchedResultsController is there really a need to build up another array? What is the end goal?

Update

Now I understand what you are trying to do.

Solution 1

Only populate the array when a search has been conducted. Take a look at the http://developer.apple.com/iphone/library/samplecode/TableSearch/index.html example code and you should see how to apply it to your situation.

If you want to enter the table view with a pre-defined search then you need to perform it after you have executed a -performFetch: in the NSFetchedResultsController.

Solution 2

Modify the NSPredicate on the NSFetchedResultsController to include your search terms and then execute -performFetch: on the NSFetchedResultsController, you may have to do a -reloadData on the table as well, I am not sure.

When the user clears the search field you reset the predicate and re-fetch everything. Since it is all cached there should be no performance penalty.

Solution 2 just occurred to me and I have not tested it personally but there is no reason it shouldn't work just fine. Should even give you live updates within the search.

Marcus S. Zarra
Hi Marcus,Really I'm trying to use an 'Search Display controller'. I did it in Sqlite by pulling the data into an array. I was trying to find a way to use it in core data and predicate. I know there must be an easy way to do this in Core Data but I can't seem to find a way...Do you have any suggestions?
Stef
I'm reading through your book trying to understand core data inside out...I'm surprised to see you here...You've pointed me in the right direction...Thanx for your help so far...
Stef
First time back at SO since last evening ... this makes a LOT more sense now. This is why it's a good idea to state your goal in your original question. It saves unnecessary guessing at what you're trying to do (and useless explanations about things you're not trying to do). :-)
Joshua Nozzi
(ran out of room) I'd say solution 2 is actually the #1 solution. If you drag entities from your model into IB, you can examine how it automatically sets up a search field purely with Cocoa Bindings (using the information from your model).
Joshua Nozzi
A: 

When I got your error,

'-[NSCFArray insertObject:atIndex:]: attempt to insert nil'

I had given the fetchedRequest a sort descriptor that had a nil key. The error appeared when I used these lines:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:nil ascending:NO];   
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

The error disappeared when I set the key to @"name":

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
Rose Perrone