Im using a NSManagedObject as an attribute within my ViewController, declared like this:
#property(retain, nonatomic)NSManagedObject *person;
Im propagating the content of a fetch to a UITableView, when the user taps the contact he is looking for, this is what happens:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
self.person = [contacts objectAtIndex:indexPath.row];
Contacts contains the result of the fetch, which is done like this:
NSArray *contactsArray;
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [(OAuthStarterKitAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Contacts" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
testForTrue = [NSPredicate predicateWithFormat:#"SOME CONDITION"];
[fetchRequest setPredicate:testForTrue];
[fetchRequest setFetchLimit:10];
contactsArray = [[NSArray alloc]initWithArray:[context executeFetchRequest:fetchRequest error:&error]];
When the user taps the contact, self.person has that value, but when I try to use that value in another method it's nil, and the address is 0x000000.
This only happens on iOS 5, on iOS 6 person has the value of the contact selected and I can use elsewhere.
Any ideas?
Thanks.
Instead of getting the NSManagedObject, which is always dependant of the life cycle of the context I just stored de NSManagedObjectID and then get the NSManagedObject by using the function objectWithID. And it worked!
Related
I am working on Sqlite and I have added some questions and answers data. I am matching that data in a textfield. When I type the correct answer it's working fine, but what about approximately correct answers? I don't know how to do it.
Example: If I type CORRECT then if it matches, it works fine. But...
If I type CORRET, then it has to show "Answer is approximarely correct"
How to solve this? Can anyone help me. And I am matching Data from Sqlite.
Thanks & Regards.
Fetch the data from coredata with this code and compare with the textfield data as;
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = [appDelegate managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:#"MileageTrack" inManagedObjectContext:context]; //Where MileageTrack is my coredata entity
[fetchRequest setEntity:entity];
NSMutableArray *array = [[NSMutableArray alloc] init];
int i=0;
NSError *error;
NSArray *objects = [context executeFetchRequest:fetchRequest error:&error];
for (MileageTrack *info1 in objects) {
NSMutableDictionary *dict1 = [[NSMutableDictionary alloc] init];
[dict1 setObject:info1.tripusage forKey:#"answer"];
if([[dict1 objectForKey:#"answer"] isEqualToString:textfield.text])
{
NSLog(#"correct answer");
}
else
{
NSLog(#"wrong answer");
}
This following sqlite command can help you.
[NSString stringWithFormat:"select username from tblData where name is %%#%",name];
this command will bring all your data,
like,
if you type "correct"
it will take 1correct, 2correct, anycorrect, correctany.
if it doesn't word try with %%;
in my iOS app i have a core data, and i have notice that sometime, in a specific view, when i retrieve information from core data, are not always up to date, i'm explain well:
if i update some value in the core data, and then i go in in a specific view to view this information, that information are not up to date, now i show how i access my database:
.h
#property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;
.m
#synthesize managedObjectContext;
- (NSArray *)sortInformation{
if (managedObjectContext == nil) {
managedObjectContext = [(AppDelegate *) [[UIApplication sharedApplication] delegate] managedObjectContext];
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"MyEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
....
and then i display my information in a table view, all work perfectly, there is only this problem, that SOME TIME seems that the update i have done in another view is not read in this view, but if i close the app, and i close it from the background, and then i reopen it all works fine...so i have saved the update in the core data correctly, so i think the problem is in this view, maybe i have an old reference of the core data and not the update version, maybe the problem is this:
if (managedObjectContext == nil) {
managedObjectContext = [(AppDelegate *) [[UIApplication sharedApplication] delegate] managedObjectContext];
}
that refresh only if the variable managedObjectContext is nil so only if the view is deallocated...so never, because is one of my root view controller in a UITabbarController, so my question is, how i can access to the core data to have always a update version of it?
no need to refresh the context just call save method on managedObjectContext like [managedObjectContext save];
or if you are using more than one managed object context you should merge changes done by the context
On the implementation of the database class you can do like this
-(id) initWithContext: (NSManagedObjectContext *)managedObjContext {
self = [super init];
[self setManagedObjectContext:managedObjContext];
return self;
}
the managedObjContext is pass and set
On your app delegate when call the database class it should be something like this
database = [[Database alloc] initWithContext:self.managedObjectContext];
Then you are good to accessed the database like this
- (NSArray *)sortInformation {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"MyEntity" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSMutableArray *mutableFetchResults = [[[managedObjectContext_ executeFetchRequest:request error:&error] mutableCopy] autorelease];
[request release];
return mutableFetchResults;
}
How do I fetch all child entities of a parent?
I have a table populated by a parent entity in Core Data. When the user touches a cell I intend to show another table with all children of that parent.
How does the NSFetchRequest look like for this please?
Edit:
model is like this:
student>>dates [one to many, one student have many days]
So I want all dates for any given student (selected by touching in student table cell for that student), then populate dates table with dates for that student.
Thanks!
Assuming that the entity and the class names are Student and Date, and the reverse relationship for Date->Student is called student,
Student *aStudent = ...;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity: [NSEntityDescription entityForName: #"Date" inManagedObjectContext: [aStudent managedObjectContext]]];
[fetchRequest setPredicate: [NSPredicate predicateWithFormat: #"student == %#", aStudent]];
You don't need a separate fetch request for this. All of the objects from the to-many relationship (don't call them child entities, that is misleading and incorrect) are available by accessing the relationship from the student object - something like student.dates. This gives you an NSSet, you can sort it and turn it to an array if you need to.
Within your first table delegate, when you touch a specific cell, I'll inject the specific parent property to the second table controller. For example:
SecondController secondController = ... // alloc-init
secondController.studentToGrab = ...
where SecondController declaration has a studentToGrab property like the following:
#property (nonatomic, retain) Student* studentToGrab; // use strong with ARC, if non-ARC remember to release it
and in definition synthesize it.
Then in your second controller, within viewDidLoad method you could do:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"YourNameEntityForDate" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"student == %#", studentToGrab];
[fetchRequest setPredicate:predicate];
// you can also use a sortdescriptors to order dates...
NSError *error = nil;
NSArray *resultArray = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (error != nil) {
NSLog(#"Error: %#", [error localizedDescription]);
abort();
}
// use resultArray to populate something...
A remark when you deal with table you could also use NSFetchedResultController class. It has advantages when used for displaying data in tables.
If you have custom classes, you could traverse the generated relationship (return [student dates]). That will get you an unordered NSSet on iOS4, or, you can do it with a fetch request (note I use ARC so no releases/autoreleases here):
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Date"
inManagedObjectContext:moc];
[fetchRequest setEntity:entity];
NSMutableArray *predicates = [NSMutableArray arrayWithCapacity:3];
[predicates addObject:[NSPredicate predicateWithFormat:#"student == %#", aStudent]];
// You might add other predicates
[fetchRequest setPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:predicates]];
// and if you want sorted results (why not, get the database to do it for you)
// sort by date to the top
NSArray *sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"dateAdded" ascending:NO]];
}
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *sorted = [moc executeFetchRequest:fetchRequest error:&error];
if (error) {
// Handle the error, do something useful
}
return sorted;
I have a table populated with coredata (all staff), but I need another table with only staff from one center (there are 3 centers),
the center is an attribute in my entity,
so how can I show this list? (populate table with staff from x center?) do I use NSPredicate?
thanks
I give you a function which returns you array according to center type what you need to a column called center in your entity.
and in folloeing function you need to pass center name like #"x" or #"y".And function give you what you want.
- (NSMutableArray *)getRecordsByCenter:(NSString *)cen{
NSMutableArray *fetchResults;
NSString *entityName=#"YourEntity";
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:globalManagedObjectContext];
[fetchRequest setEntity:entity];
fetchResults = [NSMutableArray arrayWithArray:[globalManagedObjectContext executeFetchRequest:fetchRequest error:nil]];
[fetchResults filterUsingPredicate:[NSPredicate predicateWithFormat:#"center == %#",cen]] ;
[fetchRequest release];
return fetchResults;
}
another iPhone newbie question...
I have the following:
NSPersistentStoreCoordinator
NSManagedObjectContext
NSManagedObjectModel
Is it possible to run queries directly on the store (since its a sqlite DB)? I'm trying to delete all the records from a tableview, and figured a "DELETE FROM table" would be nice and quick as opposed to looping through the records and removing them manually (which i'm also struggling with).
Thanks for your time,
James
Core data acts as a wrapper for the underlying data store, so it's not really a great idea to begin circumventing core data. Additionally, core data adds additional information to your DB, so directly accessing the DB may (or may in the future) cause problems.
To delete all records via core data, I have the following:
+ (void) deleteAll {
NSManagedObjectContext *managedObjectContext = [(myAppDelegate*)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:[[self class] description] inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSError *error;
NSArray *items = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];
for (NSManagedObject *managedObject in items) {
[managedObjectContext deleteObject:managedObject];
NSLog(#"%# object deleted",[[self class] description]);
}
}