NSDictionary won't fill up - objective-c

I have the following piece of code.
-(NSDictionary *)getPlayers
{
NSManagedObjectContext *context = self.genkDatabase.managedObjectContext;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Team"
inManagedObjectContext:context];
fetchRequest.predicate = [NSPredicate predicateWithFormat:#"position ==[c] %#", #"Doelman"];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error.
}else
for (Team *info in fetchedObjects) {
[_photos setObject:info.image forKey:#"player_imgUrl"];
[_photos setObject:info.name forKey:#"player_name"];
}
NSLog(#"%#",_photos);
return _photos;
But for some reason or another my NSLog always gives (null) back. But when I do this
[_photos setObject:info.image forKey:#"player_imgUrl"];
[_photos setObject:info.name forKey:#"player_name"];
NSLog(#"name: %#",info.name );
NSLog(#"url: %#",info.image );
It gives the right data back.
Can somebody help?
Kind regards.

Make sure you have instantiated your _photos dictionary somewhere with the following line of code:
_photos = [[NSMutableDictionary alloc] init];
Just defining it as an instance variable or a property is not enough.

You have a mistake which may not be directly connected to the issue. In for loop you always reset name and image for the same key. so at the end of the loop your dictionary must have one name and one image, not all the ones from the array. You should change it
UPDATE:probably something like this:
int count = fetchedObjects.count;
for (int i = 0; i < count; i++)
{
NSString *image_key = [NSString stringWithFormat:#"player_imgUrl%d",i];
NSString *name_key = [NSString stringWithFormat:#"player_name%d",i];
[_photos setObject:[[fetchedObjects objectAtIndex:i] image] forKey:image_key];
[_photos setObject:[[fetchedObjects objectAtIndex:i] name] forKey:name_key];
}

Related

Core Data update does not save and does not give any error, why?

I am using a very simple piece of code to update an NSManagedObject, but the save does not make it to the persistent store (SQLite). There are no error messages and the logs look ok so I am a little lost.
I have scaled down the code as much as possible to try and isolate the problem as shown below.
The logs tell me that the orderNumber and status are set correctly and also the debug output of the arrays are all correct, but my simple update still fails without any error at all.
+ (int) synchOrderWithStatusUpdate:(NSString *)orderNumber : (int)status {
if ([NWTillHelper isDebug] == 1) {
NSNumber *statusCheck = [NSNumber numberWithInt:status];
NSLog(#"WebServices:synchOrderWithStatusUpdate:ordernumber = %#, status = %d, status2 = %#", orderNumber, status, statusCheck);
}
synchOrderErrorCode = 0;
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate];
NSManagedObjectContext *context = appDelegate.persistentContainer.viewContext;
// *** The query for all tables uses orderNumber as selection so we set that up first for re use
NSPredicate *predicateOrderNumber =[NSPredicate predicateWithFormat:#"orderNumber like[cd] %#", [NWTillHelper getCurrentOrderNumber]];
NSFetchRequest *fetchRequestOh = [[NSFetchRequest alloc] initWithEntityName:#"OrderHead"];
NSFetchRequest *fetchRequestOrp = [[NSFetchRequest alloc] initWithEntityName:#"OrderRow"];
NSFetchRequest *fetchRequestTender = [[NSFetchRequest alloc] initWithEntityName:#"Tender"];
fetchRequestOh.predicate = predicateOrderNumber;
fetchRequestOrp.predicate = predicateOrderNumber;
fetchRequestTender.predicate = predicateOrderNumber;
fetchRequestOh.resultType = NSDictionaryResultType;
fetchRequestOrp.resultType = NSDictionaryResultType;
fetchRequestTender.resultType = NSDictionaryResultType;
NSError *errorOh = nil;
NSMutableArray *orderHeads = [[context executeFetchRequest:fetchRequestOh error:&errorOh] mutableCopy];
NSError *errorOrp = nil;
NSArray *orderRows = [[context executeFetchRequest:fetchRequestOrp error:&errorOrp] mutableCopy];
NSError *errorTender = nil;
NSArray *tenderRows = [[context executeFetchRequest:fetchRequestTender error:&errorTender] mutableCopy];
if ([NWTillHelper isDebug] == 1) {
NSLog(#"WebServices:synchOrderWithStatusUpdate:orderHeadsArray: %#", [orderHeads objectAtIndex:0]);
NSLog(#"WebServices:synchOrderWithStatusUpdate:orderRowsArray: %#", orderRows);
NSLog(#"WebServices:synchOrderWithStatusUpdate:tenderRowsArray: %#", tenderRows);
}
// *** Set the status before upload since this dictates what will happen in backend
// *** regardless if synch is successful or not
NSManagedObject *orderHeadObject = nil;
orderHeadObject = [orderHeads objectAtIndex:0];
[orderHeadObject setValue:[NSNumber numberWithInt:status] forKey:#"status"];
// Save the objects to persistent store
NSError *error = Nil;
[context save:&error];
NSLog(#"Jongel Error = %#", error);
if(error !=nil) {
if([NWTillHelper isDebug] == 1) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
synchOrderErrorCode = 99;
}
return 10101;
The orderHeads are fetched as dictionaries. The NSManagedObjectContext will not be aware of any changes made to a dictionary. Only NSManagedObjects will be managed by the NSManagedObjectContext, hence the name ;-)
Try to fetch the orderHeadObject as an NSManagedObject as this will allow you to save the changes back into the store. If you need the dictionary for JSON serialisation: Just fetch it again as a dictionary after you have made the changes. That second fetch will be very fast since all values of the object are already cached, so CoreData won't have to reload from the database.

Core Data Issue - Unable to store NSNumber

I am trying to use Core Data in my application. I want to store an attribute "totalKM".
to store my attribute I use these lines:
Model *event = (Model *)[NSEntityDescription insertNewObjectForEntityForName:#"Model" inManagedObjectContext:managedObjectContext];
int number = 4;
[event setTotalKM:[NSNumber numberWithDouble:number]];
to read my attribute I use these:
Model *event = (Model *)[NSEntityDescription insertNewObjectForEntityForName:#"Model" inManagedObjectContext:managedObjectContext];
NSNumber *number = [event totalKM];
My attribute "totalKM" is always default value, O. And I have no exception. Am i missing something?
Thanks.
insertNewObjectForEntityForNamethis method use to put model to context.
this is a new object.
the right way is:
Set new one
Model *event = (Model *)[NSEntityDescription insertNewObjectForEntityForName:#"Model" inManagedObjectContext:managedObjectContext];
int number = 4;
[event setTotalKM:[NSNumber numberWithDouble:number]];
//save change if need
NSError *error = nil;
if (![self.manageObjectContext save:&error]) {
NIDERROR(#"save managedContext error :%#",error);
}
fetch object progress
When you need to get a model form coredate.u need 2 fetch use fetch
like this dome
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
[fetchRequest setEntity:[NSEntityDescription entityForName:#"Board"
inManagedObjectContext:self.manageObjectContext]];
//set fetch conditions
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"board_id == %#", aBoardID];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *results = [self.manageObjectContext executeFetchRequest:fetchRequest error:&error];
if (error) {
NIDERROR(#"fetch board error.\n board id: %# \n error:%#", aBoardID, error);
return nil;
}
Model *model = results[0];
NSLog(#"%#",model.totalKM)

NRGridView won't show data from my core data database

I am building a app for a local football club. I want to show all players names and pictures in a grid. Therefore I am using the NRGridview. But it won't load up with my data. I have an NSArray with all players information. Here you see the method which generates this array.
- (NSArray *)getTeam
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Team"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *mutableFetchResults = [self.genkDatabase.managedObjectContext executeFetchRequest:request error:&error];
NSLog(#"first error log %#", [error localizedDescription]);
if (mutableFetchResults == nil) {
NSLog(#"second error log %#", [error localizedDescription]);
}else if ([mutableFetchResults count] == 0){
NSLog(#"geen resultaten voor team");
}else{
NSLog(#"team names: %#",[mutableFetchResults valueForKey:#"name"]);
return mutableFetchResults;
}
return mutableFetchResults;
}
And this is what I do in the tableview.
- (NRGridViewCell*)gridView:(NRGridView *)gridView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyCellIdentifier = #"MyCellIdentifier";
NRGridViewCell* cell = [gridView dequeueReusableCellWithIdentifier:MyCellIdentifier];
if(cell == nil){
cell = [[NRGridViewCell alloc] initWithReuseIdentifier:MyCellIdentifier];
[[cell textLabel] setFont:[UIFont boldSystemFontOfSize:11.]];
[[cell detailedTextLabel] setFont:[UIFont systemFontOfSize:11.]];
}
NSLog(#"players array %#",players);
for (int i = 0; i <= [players count]; i++) {
// NSData *imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[players objectAtIndex:i]valueForKey:#"image"]]];
// UIImage *image = [[UIImage alloc]initWithData:imgData];
//cell.imageView.image = image;
cell.textLabel.text = [[players objectAtIndex:i]valueForKey:#"name"];
cell.detailedTextLabel.text = [[players objectAtIndex:i]valueForKey:#"position"];
return cell;
}
return cell;
}
The NSLog gives always (null). My question is now, where should I put the code "NSArray *players = [self getTeam] . so that my tableview will fill up with data?
EDIT
It did give me back the right amount of sections, and numberOfRowsInsection. For numbersOfRowsIn section I created 4 methods. 1 method whichs gets all off the goalkeepers, 1 for the defenders, 1 for the wingers, and 1 for the attackers. Then In my tableview method I did the following.
- (NSInteger)gridView:(NRGridView *)gridView numberOfItemsInSection:(NSInteger)section
{
if(section == 0){
return [[self getDoelmannen]count];
}else if (section == 1){
return [[self getVerdedigers]count];
}else if (section == 2){
return [[self getMiddenvelders]count];
}else{
return [[self getAanvallers]count];
}
return [[self getAanvallers]count];
}
This works. But still have the problem for my cell self.
EDIT2
Okay I think my problem is with filling my players Array up. I do the following in my viewDidLoad
-(void)viewDidLoad{
_players = [self getTeam];
NSLog(#"players array: %#",_players);
}
Which gives the following log.
2012-10-17 12:11:22.099 RacingGenk[63122:c07] nil
2012-10-17 12:11:22.099 RacingGenk[63122:c07] players array: (null)
Here is my code for getTeam
- (NSArray *)getTeam
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Team"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"sortOrder" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *mutableFetchResults = [self.genkDatabase.managedObjectContext executeFetchRequest:request error:&error];
if (mutableFetchResults == nil) {
NSLog(#"nil");
}else if ([mutableFetchResults count] == 0){
NSLog(#"geen resultaten voor team");
}else{
NSLog(#"team names: %#",[mutableFetchResults valueForKey:#"name"]);
return mutableFetchResults;
}
return mutableFetchResults;
}
It looks like players isn't getting initialized. You can put your [self getTeam] call in the viewDidLoad method and make players a property.
If NRGridView is anything like UITableView, there are probably other methods that you need to overload.
For example, UITableView has tableView:numberOrRowsInSection:. Failure to return > 0 value from this method results in nothing being shown. Or numberOfSectionsInTableView:, which returns the number of sections and so on.
Check the documentation for the control you're using.
Update:
Since your executeFetchRequest:error: is failing, you should check if there's an error message instead of just printing out (nil):
NSLog(#"%#", [error localizedDescription]);

assign value from NSDictionary to NSManagedObject

My app requires to get data from a .Net WCF service when the device is connected to WiFi.If there's a new row added on the server,it should add it to its CoreData database. I am using a NSDictionary for comparing the local objects with the remote objects. The code is:
-(void)handleGetAllCategories:(id)value
{
if([value isKindOfClass:[NSError class]])
{
NSLog(#"This is an error %#",value);
return;
}
if([value isKindOfClass:[SoapFault class]])
{
NSLog(#"this is a soap fault %#",value);
return;
}
NSMutableArray *result = (NSMutableArray*)value;
NSMutableArray *remoteObj = [[NSMutableArray alloc]init];
for (int i = 0; i < [result count]; i++)
{
EDVCategory *catObj = [[EDVCategory alloc]init];
catObj = [result objectAtIndex:i];
[remoteObj addObject:catObj];
}
NSArray *remoteIDs = [remoteObj valueForKey:#"categoryId"];
NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];
request.predicate = [NSPredicate predicateWithFormat:#"categoryId IN %#", remoteIDs];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Categories" inManagedObjectContext:__managedObjectContext];
[request setEntity:entity];
NSMutableArray *results = [[NSMutableArray alloc]initWithArray:[__managedObjectContext executeFetchRequest:request error:nil]];
NSArray *existingIDs = [results valueForKey:#"categoryId"];
NSDictionary *existingObjects = [NSDictionary dictionaryWithObjects:results forKeys:existingIDs];
for (NSDictionary *remoteObjectDic in remoteObj)
{
Categories *existingObject = [existingObjects objectForKey:[remoteObjectDic valueForKey:#"categoryId"]];
if (existingObject)
{
NSLog(#"object exists");
}
else
{
NSLog(#"create new local object");
// Categories *newCategory;
// newCategory = [NSEntityDescription insertNewObjectForEntityForName:#"Categories" inManagedObjectContext:__managedObjectContext];
// [newCategory setCategoryId:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"categoryId"]intValue]]];
// [newCategory setCategoryName:[remoteObjectDic objectForKey:#"categoryName"]];
// [newCategory setDocCount:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"docCount"]intValue]]];
// [newCategory setCategoryType:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"categoryType"]intValue]]];
// [newCategory setSubCategoryId:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"subCategoryId"]intValue]]];
// [__managedObjectContext insertObject:newCategory];
}
}
[my_table reloadData];
}
The problem is,I am not able to extract values from the remote object and assign it to the NSManagedObject.I have commented the code which (according to me) should save the values in new object to the managed object. Can someone please help me achieve this?
Thanks
Here is an example of a save I did in a recent project. I have somethings in wrappers so fetching a managed object and saving look a little weird on my end. Really the only major difference I see is the act of saving. Are you saving the new NSManagedObject elsewhere in the code?
dict = (NSDictionary*)data;
#try {
if (dict) {
CaretakerInfo* info = [GenericDataService makeObjectWithEntityName:NSStringFromClass([CaretakerInfo class])];
[info setName:[dict valueForKey:#"name"]];
[info setImageURL:[dict valueForKey:#"photo"]];
[info setCaretakerID:[dict valueForKey:#"id"]];
[GenericDataService save];
}
else {
theError = [Error createErrorMessage:#"No Data" Code:-42];
}
}
#catch (NSException *exception) {
//return an error if an exception
theError = [Error createErrorMessage:#"Exception Thrown While Parsing" Code:-42];
}
If not it should looks something like this...
NSError *error = nil;
[context save:&error];
If you have anymore information about what's happening when you extract or assigning data that would be helpful (error/warning/log messages).

save records from WCF service in CoreData

I am new to iOS development and CoreData too. I am calling a .Net WCF service for displaying data in a UITableViewcontroller in my app.I am saving this data in CoreData. When I add a new record on the server,I want it to get displayed in the UITableViewController as well as saved in CoreData.But this doesnt happen.I have to do a "Reset Contents and Settings" on the Simulator and then run the application again. When I do this,the app displays the latest records from the service.It also saves the new record in CoreData.I am using SUDZC for interacting with the wcf service.The code for calling the service,displaying data in UITableViewController and saving it to CoreData looks like this:
- (void)viewDidLoad
{
[super viewDidLoad];
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
[my_table setDataSource:self];
[my_table setDelegate:self];
EDViPadDocSyncService *service = [[EDViPadDocSyncService alloc]init];
[service getAllCategories:self action:#selector(handleGetAllCategories:)];
}
-(void)handleGetAllCategories:(id)value
{
if([value isKindOfClass:[NSError class]])
{
NSLog(#"This is an error %#",value);
return;
}
if([value isKindOfClass:[SoapFault class]])
{
NSLog(#"this is a soap fault %#",value);
return;
}
NSMutableArray *result = (NSMutableArray*)value;
self.myData = [[NSMutableArray array] init];//array for storing 'category name'
self.catId = [[NSMutableArray array]init];//array for storing 'category ID'
self.myData=[self getCategories];
/*store data in Core Data - START*/
NSMutableArray *coreDataCategoryarray = [[NSMutableArray alloc]init];
NSManagedObjectContext *context = [self managedObjectContext];
Categories *newCategory;//this is the CoreData 'Category' object
for(int j=0;j<[result count];j++)
{
EDVCategory *edvCat = [[EDVCategory alloc]init];//this is the SUDZC 'Category' object
edvCat = [result objectAtIndex:j];
if ([self.catId count]>0) {
for (int i=0; i<[self.catId count]; i++) {
if ([edvCat categoryId] == [[self.catId objectAtIndex:i] integerValue]) {
checkFlag=TRUE;
}
}
}
if (checkFlag == FALSE) {
newCategory = [NSEntityDescription insertNewObjectForEntityForName:#"Categories" inManagedObjectContext:context];
[newCategory setCategoryId:[NSNumber numberWithInt:[edvCat categoryId]]];
[newCategory setCategoryName:edvCat.categoryName];
[newCategory setDocCount:[NSNumber numberWithInt:[edvCat docCount]]];
[newCategory setCategoryType:[NSNumber numberWithShort:[edvCat categoryType]]];
[newCategory setSubCategoryId:[NSNumber numberWithInt:[edvCat subCategoryId]]];
[coreDataCategoryarray addObject:newCategory];
}
}
/*store data in Core Data - END*/
NSError *error = nil;
if (![context save:&error])
{
[coreDataCategoryarray release];
}
else
{
//return [coreDataCategoryarray autorelease];
[coreDataCategoryarray autorelease];
}
self.myData=[self getCategories];
[my_table reloadData];
}
-(NSMutableArray *)getCategories
{
NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Categories" inManagedObjectContext:__managedObjectContext];
NSSortDescriptor *sortByName = [[[NSSortDescriptor alloc] initWithKey:#"categoryId" ascending:YES] autorelease];
[request setSortDescriptors:[NSArray arrayWithObject:sortByName]];
[request setEntity:entity];
entity = nil;
NSError *error = nil;
NSMutableArray *fetchResults = [[__managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
[request setReturnsObjectsAsFaults:NO];
NSManagedObject *aTabrss;
NSMutableArray *arForGetCategory=[[NSMutableArray alloc]init];
for (aTabrss in fetchResults){
[arForGetCategory addObject:[aTabrss valueForKey:#"categoryName"]];
[self.catId addObject:[aTabrss valueForKey:#"categoryId"]];
}
return (arForGetCategory);
}
What changes should I make in my code so that it reflects the latest data from the service and saves it to CoreData(sqlite) at the same time?
It seems like the class that you really need is NSUserDefaults:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsuserdefaults_Class/Reference/Reference.html