Core Data input fetches into labels - core-data

I want to store data from a text field. And then use this data to populate the text in a label inside a view controller. Is this possible? Ive messed around with it, but nothing seems to work. Any thoughts? Here are my two methods...
- (IBAction)saveButton:(id)sender {
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSManagedObject *noteEntry = [NSEntityDescription insertNewObjectForEntityForName:#"Notes" inManagedObjectContext:coreDataStack.managedObjectContext];
[noteEntry setValue:_notesField.text forKey:#"notes"];
NSError *error = nil;
// Save the object to persistent store
if (![coreDataStack.managedObjectContext save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
[coreDataStack saveContext];
}
Here is my view did load method:
- (void)viewDidLoad
{
[super viewDidLoad];
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"Notes"];
Notes *entry = [NSEntityDescription insertNewObjectForEntityForName:#"Notes" inManagedObjectContext:coreDataStack.managedObjectContext];
_outputLabel.text = entry.notes;
}

Your code in the saveButton: method seems OK. But your code in the viewDidLoad method seems wrong. Are you trying to do the following?
- (void)viewDidLoad {
[super viewDidLoad];
CoreDataStack *coreDataStack = [CoreDataStack defaultStack];
//First way to init your fetchRequest:
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:#"Notes"];
//Second way to init your fetchRequest:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Notes" inManagedObjectContext:coreDataStack];
[fetchRequest setEntity:entity];
//Having a NSEntityDescription object can be usefull if you need to group your data, for example
//Set some predicates, if necessary
//Set some sortdescriptors, if necessary
NSError *error;
NSArray *resultsArray = [coreDataStack executeFetchRequest:request error:&error];
NSLog(#"%#", resultsArray);
_outputLabel.text = [[resultsArray firstObject] notes]; //if your array can only have one object
}
The NSLog will give you the structure of your fetch array (I can't guess it). You will then be able to set _outputLabel.text.

Answer by #user1966109 is exactly correct answer what you are looking for. Since you need to show the text in a label and for that you need to set predicate to get a single row. Set the predicate as below
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"value == abc"];//considerin abc is the word you are looking for.
request.predicate = predicate;
//then execute the query.

Related

Saving array of images in core data as transformable

I want to add my imageArray into coredata as transformable but this is not storing properly.
My save button coding.
- (IBAction)saveButton:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *newEntry = [NSEntityDescription insertNewObjectForEntityForName:#"FoodInfo" inManagedObjectContext:context];
NSAttributeDescription *messageType = [[NSAttributeDescription alloc] init];
[messageType setName:#"photos"];
[messageType setAttributeType:NSTransformableAttributeType];
[imagesForShow addObject:messageType];
NSError *error = nil;
if (![context save:&error]) {
NSLog(#"Unable to save context for class" );
} else {
NSLog(#"saved all records!");
[context save:nil];
}
//[newEntry setValue:imagesForShow forKey:#"images"];
}
Here 'imagesForShow' is my array of images.
When iam going to fetch this image array , this showing nil
- (void)viewDidLoad {
[super viewDidLoad];
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc]initWithEntityName:#"FoodInfo"];
[request setReturnsObjectsAsFaults:NO];
arrayForPhotos = [[NSMutableArray alloc]initWithArray:[context executeFetchRequest:request error:nil]];
// Do any additional setup after loading the view.
}
What I am doing wrong with this code. Thanks.
In your save code:
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *newEntry = [NSEntityDescription
insertNewObjectForEntityForName:#"FoodInfo"
inManagedObjectContext:context];
NSAttributeDescription *messageType = [[NSAttributeDescription alloc] init];
[messageType setName:#"photos"];
[messageType setAttributeType:NSTransformableAttributeType];
[imagesForShow addObject:messageType];
I can't even figure out what this is supposed to do. It's completely wrong. You should never be allocating an instance of NSAttributeDescription unless you are constructing a Core Data model on the fly-- which you are not doing and which almost nobody ever does. Creating the new entry is OK. The rest, I don't know. You said that imagesForShow is your array of images, so I don't know why you're also adding an attribute description to the array.
In a more general sense, if newEntry has a transformable attribute named photos and imagesForShow is an NSArray of UIImage objects, then you could do this:
[newEntry setValue:imagesForShow forKey:#"photos"];
This is similar to a line that you have commented out, though it's not clear why it's commented out.
But whatever you do get rid of the code creating the NSAttributeDescription.

Core Data retrieving relationship data

I am really having trouble retrieving items that have been created through the Menu entity. This is the code I used to add an item to a specific Menu object
-(void)additem:(NSString *)entity :(NSDictionary *)aDictionary :(NSString *)menu
{
NSLog(#"additem");
NSError *error = nil;
Menu *menuItem = nil;
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Menu" inManagedObjectContext:managedObjectContext]];
[request setPredicate:[NSPredicate predicateWithFormat:#"mname=%# and msection =%#",#"Parents",#"Keydates"]];
menuItem = [[managedObjectContext executeFetchRequest:request error:&error] lastObject];
if (error) {
//Handle any errors
}
if (!menuItem) {
//Nothing there to update
NSLog(#"This class doesn't exist");
}
Items *anitem = (Items *)[NSEntityDescription insertNewObjectForEntityForName:#"Items" inManagedObjectContext:managedObjectContext];;
anitem.type = [aDictionary objectForKey:#"type"];
anitem.title = [aDictionary objectForKey:#"title"];
anitem.image = [aDictionary objectForKey:#"image"];
anitem.subtitle = [aDictionary objectForKey:#"subtitle"];
[menuItem addItemsObject:anitem];
[managedObjectContext save:&error];
}
I want to use a predicate to retrieve all the items that were created on a specific Menu object. Here is the code I am trying to retrieve it with.
- (void) readItems: (NSString *)section {
NSLog(#"readItems");
NSError *error = nil;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Menu"
inManagedObjectContext:managedObjectContext];
fetchRequest.resultType = NSDictionaryResultType;
[fetchRequest setEntity:entity];
[fetchRequest setReturnsObjectsAsFaults:NO];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"mname=%# and msection = %#",#"Parents",#"Keydates"]];
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
for (Items *item in fetchedObjects) {
NSLog(#">>>>>>%#",item);
}
}
Can anyone point me in the right direction.I know I pass section and don't use it. I have place the actual values in.
Your readItems: method specifies the entity for your fetch as Menu yet when you execute the fetch you are expecting Item (since you start iterating through fetchedObjects and casting them as Item).
Instead what you want to do is et your entity to Item and change the predicate to
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"items.mname=%# and items.msection = %#",#"Parents",#"Keydates"]];
Furthermore you should consider renaming your relationships. The relationship field specifies exactly what you would expect to see when you follow the arrow. Thus when I look at Items and follow its arrow to Menu I would expect the name of this relationship to be menu yet you call it menuItems. You have done this correctly for the relationship from Menu to Item.
That way we would end up with a more readable predicate looking like:
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:#"menu.mname=%# and menu.msection = %#",#"Parents",#"Keydates"]];
Happy Coding

Core Data Fetch Save relationship while inserting entity (simultaneously)

First question here and I've tried a bunch of stuff and can't figure it out.
Core Data with 2 entities with to-many relationship both ways
A<<---->>B
A entity has name as an attribute, and a relationship Bs
First Controller lists all A entities and i have a second controller to add A entities and I want to have it save a default B in its relationship.
In the prepare for segue I have this code:
if ([[segue identifier] isEqualToString:#"addAEntitySegue"]) {
AddAEntityViewController *addAEntityViewController = [segue destinationViewController];
addAEntityViewController.delegate = self;
addAEntityViewController.managedObjectContext = self.managedObjectContext;
NSManagedObjectContext *addingContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
self.addingManagedObjectContext = addingContext;
[addingManagedObjectContext setPersistentStoreCoordinator:[[fetchedResultsController managedObjectContext] persistentStoreCoordinator]];
addAEntityViewController.A = [NSEntityDescription insertNewObjectForEntityForName:#"A" inManagedObjectContext:addingContext];
UIBarButtonItem *saveButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:addAEntityViewController
action:#selector(save:)];
addAEntityViewController.navigationItem.rightBarButtonItem = saveButton;
}
In addAEntityViewController i have this to save
-(IBAction)save:(id)sender
{
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"B" inManagedObjectContext:self.managedObjectContext];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#",[defaults objectForKey:#"BDefault"]];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
//Set the batch size to a suitable number
[fetchRequest setFetchBatchSize:20];
NSError *error;
self.A.name = textFieldVal;
[self.A addBObject:[[self.managedObjectContext executeFetchRequest:fetchRequest error:&error] objectAtIndex:0]];
NSLog(#"A = %#", self.A.Bs);
[self.delegate addAEntityViewController:self didFinishWithSave:YES];
}
In the addAEntityViewController everything saves correctly even the NSLog(#"A = %#", self.A.Bs); statement shows the B. But when the delegate saves in the First Controller (AEntityViewController) it only saves the A.name but not the relationship A.Bs, I can't figure out what's wrong.
Here's the delegate method:
-(void) addAEntityViewController:self didFinishWithSave:YES{
if (save) {
NSLog(#"saveworkouts");
NSError *error;
if (![addingManagedObjectContext save:&error]) {
// Update to handle the error appropriately.
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
exit(-1); // Fail
}
}
// release the adding managed object context
self.addingManagedObjectContext = nil;
}
Like I said it saves the A entity but not the relationship to B even though the relationship to B saved correctly in the addAEntityViewController (the second View). An NSLOg of A.Bs is null.
First I believe that this line:
addAEntityViewController = self.managedObjectContext;
should be:
addAEntityViewController.managedObjectContext = self.managedObjectContext;
but that would also be wrong.
it should be getting the addingContext you created afterwards:
addAEntityViewController.managedObjectContext = addingContext;
I'm a bit surprised that your app didn't crash, as you are mixing managed objects from 2 different contexts.

fetch request for entity.attribute == #"somevalue"

How do I setup a fetch request to only pull the data from an entity's attribute with one particular value? This is the basic code I've used before.
-(void)fetchResults
{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:self.entityDescription.name];
NSString *cacheName = [self.entityDescription.name stringByAppendingString:#"Cache"];
// predicate code
if (self.predicate != nil) {
[fetchRequest setPredicate:self.predicate];
}
// end of predicate code
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:cacheName];
BOOL success;
NSError *error;
success = [self.fetchedResultsController performFetch:&error];
if (!success)
{
NSLog(#"%#", [error localizedDescription]);
}
}
I've been looking at this page: http://bit.ly/KevYwR is this the right direction?
Do I need to use NSPredicate or can I do without?
Thanks for any help, point in the right direction, etc.
Setting up a NSFetchRequest is equivalent to a SELECT statetement in SQL language.
Here a simple example:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"EntityName" inManagedObjectContext:moc]];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
// error handling code
The array results contains all the managed objects contained within the sqlite file. If you want to grab a specific object (or more objects) you need to use a predicate with that request. For example:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"attribute == %#", #"Some Value"];
[request setPredicate:predicate];
In this case results contains the objects where attribute is equal to Some Value. Setting a predicate is equal to put the WHERE clause in a SQL statement.
Note
I suppose that the name of the entity is EntityName and its property is called attribute which is of type string.
For further info I suggest you to read the Core Data programming guide and NSFecthRequest class reference.
http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/NSFetchRequest.html
Hope it helps.

Coredata for getting all the values of a field

I have an entity ("Settings") and I want to get all the values in just one field ("Status").I am using coredata. Can anyone help me, please?
Declare this in .h file:
NSMutableArray *eventArray;
and in .m file
- (void)fetchRecords {
// Setup the fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Define our table/entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Settings" inManagedObjectContext:managedObjectContext];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"Status" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[fetchRequest setEntity:entity];
[fetchRequest setEntity:entity];
NSError *error;
// Get array of results.
NSMutableArray *theResults = [[managedObjectContext executeFetchRequest:fetchRequest error:&error] mutableCopy];
if (!theResults) {
// Handle the error.
// This is a serious error and should advise the user to restart the application
}
// Grab unique neighborhoods through NSSet.
NSSet *uniqueElements = [NSSet setWithArray:[theResults valueForKey:#"Status"]];
// Dump NSSet uniques into new array.
NSMutableArray *sortedResults = [[NSMutableArray alloc] initWithArray:[uniqueElements allObjects]];
for(int i = 0; i < [sortedResults count];i++)
{
NSLog(#"%d. %#", i+1, [sortedResults objectAtIndex:i]);
}
// Save our fetched data to an array
[self setEventArray: sortedResults];
}
At first, u can get Array of values:
NSFetchRequest *requestSettings = [[NSFetchRequest alloc] init];
[requestCodesList setEntity:[NSEntityDescription entityForName:#"Setting" inManagedObjectContext:managedObjectContext]];
NSArray *setting = [managedObjectContext executeFetchRequest:requestCodesList error:&error];
if (error) NSLog(#"Failed to executeFetchRequest to data store: %#", [error localizedDescription]);
Next, u transfer u array in NSString:
ComponentsJoinedByString: Constructs
and returns an NSString object that is
the result of interposing a given
separator between the elements of the
array.
(NSString *)componentsJoinedByString:(NSString *)separator
code is:
NSString *settingChanged = [setting componentsJoinedByString:#","];
And after u can using this anywhere in u UI (binding, setStringValue e.t.c)

Resources