How can I add a Subcategorie to a Categorie?
And how can I get the specific Subcategorie's of a Categorie?
I need something like
get Subcategorie.denumire where Categorie.denumire == "somename"
and
add mySubcategorie to Categorie.denumire where Categorie.denumire == "somename"
How can I do this? How can I get the name of a subtable's parent table and the names of the subtables of a table?
When you generate NSManagedObject Entities, Goal class will have an NSSet called toMinorGoal (assuming, your toMinorGoal is unordered relationship). Also, XCode will generate 4 accessory methods to add/remove MinorGoal objects to/from relationship.
If you need to fetch MinorGoals object, you would just need to get Goal object and then access its toMinorGoals NSSet that will contain all of its MinorGoal objects. Alternatively, you can just fetch MinorGoal objects, but these will return every single one of them (if you don't specify how many you want).
This is an approximate example of generated accessors XCode will provide you with:
- (void)addtoMinorGoaObject:(MinorGoal *)value;
- (void)removetoMinorGoalObject:(MinorGoal *)value;
- (void)addtoMinorGoal:(NSSet *)value;
- (void)removetoMinorGoal:(NSSet *)value;
Hope it helped you.
After a few day's of trying different solutions I finally figured this out thanks to this tutorial on CoreData :
http://www.raywenderlich.com/934/core-data-tutorial-for-ios-getting-started
I fetched all the subtables Subcategorie of the table Categorie like this:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Subcategorie"
inManagedObjectContext:self.managedObjectContext];
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"categorii.denumire == %#",self.title];
[fetchRequest setPredicate:predicate];
[fetchRequest setEntity:entity];
NSError *error;
self.listaElementeBD = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
self.title is the denumire of the Categorie, hope this helps.
Related
I have been persisting some records in core data.
Records have to-many relationship.
searching the persist data by to-many relationship seems to be simple and I used "SUBQUERY" to achieve it. I am facing problem with grouping records.
I need to group "ZCMORecord" by stringValue of "ZCMORecordValue"
Since "ZCMORecordValue" is a to-many relationship.
I even need to group ZCMORecords with one or more "ZCMORecordValue".
NSManagedObjectContext *context= [[[UIApplication sharedApplication]delegate ]managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *valueDesc = [NSEntityDescription entityForName:#"ZCMORecord" inManagedObjectContext:context];
[fetchRequest setResultType:NSDictionaryResultType];
[fetchRequest setFetchLimit:PAGE_SIZE];
NSPropertyDescription *recordRelationShip = [fetchRequest.entity.relationshipsByName objectForKey:#"recordValueSet.stringValue"];
[fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObjects:recordRelationShip,nil]];
NSError *error;
id fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
Getting errors when I try this.
SELECT clauses in queries with GROUP BY components can only contain
properties named in the GROUP BY or aggregate functions
I need to fetch records in group.
I could't figure out what to set in "setPropertiesToGroupBy:" and "setHavingPredicate:" to achieve proper results.
OKAY!! Example of how I Store my data
ZCMORecordValues
id stringValue<NSString> dateValue<NSDate> record
name Alex - record1<ZCMORecord>
DOB - 10/10/1990 record1<ZCMORecord>
name Anto - record2<ZCMORecord>
DOB - 05/05/1990 record2<ZCMORecord>
name Max - record3<ZCMORecord>
DOB - 10/10/1990 record3<ZCMORecord>
name Mary - record4<ZCMORecord>
DOB - 01/01/1990 record4<ZCMORecord>
Now I want to group my "ZCMORecord" with with respect to DOB.
Any suggestion on changing the model to facilitate grouping is also welcome
The easiest way to do this is to use a NSFetchedResultsController, fetch the record values and pass the stringValue as the sectionNameKeyPath.
I have this core data entity called Countries. This entity has a field called nameOfCountry that contains country names in english. I need to localize this to other languages, so I have created a transient property called nameOfCountryLocalized.
On the Countries class I am importing this category
Countries+NameOfCountryLocalized.h
#import "Countries.h"
#interface Countries (NameOfCountryLocalized)
#property (nonatomic, strong) NSString * nameOfCountryLocalized;
#end
Countries+NameOfCountryLocalized.m
#import "Countries+NameOfCountryLocalized.h"
#import "Countries.h"
#implementation Countries (NameOfCountryLocalized)
#dynamic nameOfCountryLocalized;
-(NSString *) nameOfCountryLocalized {
[self willAccessValueForKey:#"nameOfCountryLocalized"];
NSString *nameLocalized = NSLocalizedString(self.nomePais, nil);
[self didAccessValueForKey:#"nameOfCountryLocalized"];
return nomeLocalizado;
}
-(void)setNameOfCountryLocalized:(NSString *) nameLocalized {
[self willChangeValueForKey:#"nameOfCountryLocalized"];
[self setNomePaisLocalizado:];
[self didChangeValueForKey:#"nameOfCountryLocalized"];
}
#end
when I try to access nameOfCountryLocalized using this from a tableViewController
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Countries" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"nameOfCountryLocalized" ascending:YES];
[fetchRequest setSortDescriptors:#[sort]];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:#"Root"];
_fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
I see this error:keypath nameOfCountryLocalized not found in entity
any clues?
The NSFetchedResultsController cannot sort by a transient property. The FRC applies the sort to the underlying SQL store. With a transient property the FRC can group results of a fetch into sections. This group is created by assigned the transient property to sectionNameKeyPath.
Pulling all entities into an array will become a pain once your data grows. The FRC does provide nice support for larger data sets and you don't really want to loose that.
You might be ok assuming that your users don't switch language very often. If that is the case I suggest you write the localized country name into the store as a "normal" property and the FRC can do the sort on that property.
Although when a user does switch language then you would need to update all Country entities.
Your Countries class is not an entity. It is a class for an individual object in the database.
You really should rename it to Country, as it's incorrect to refer to NSManagedObject subclasses as plural. There's a reason Apple didn't name the class NSManagedObjects.
Because your property is added to individual objects but not the entities themselves, it is only available after objects have been fetched from the database. It cannot be used as part of fetching the objects.
You're going to need to fetch the results first (all of them) into an NSArray and then sort the objects by applying the NSSortDescriptor to the NSArray. You might want to do this by creating a wrapper class around NSFetchedResultsController.
Alternatively, put a nameOfCountryLocalized property in the actual database, with english values, and then if the user doesn't use english write to the database changing everything to the correct values. This would allow you to use NSFetchedResultsController exactly as you're trying to do now. I recommend this approach if your database is huge... but it's not, there are only a couple hundred countries in the world so performance is a total non-issue.
To learn about Core Data, I'm making a quiz app but it doesn't use a table view. I have the data for two quizzes seeded in the application. When a user clicks on a button on the view, I want to fetch a quiz, depending on which button he/she presses, but I'm not sure what I can put in for the predicate
if ([sender.currentTitle isEqualToString:#"sports"]){
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Quizdata"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat: #"(SELF = %#)", ????]; ///unsure what to put here
[fetchRequest setPredicate:predicate];
self.fetchedObjects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
NSLog(#"fetched object %#", fetchedObjects);
}else if ([sender.currentTitle isEqualToString:#"entertainment"]){
NSLog(#"entertainment%#", sender.currentTitle);
}
I have two entities, for example Quiz.h, which I made classes for based on the attributes of the entities
#dynamic quizId;
#dynamic name;
#dynamic quizData;
and a QuizData.h entity
#dynamic answer1;
#dynamic answer2;
#dynamic answer3;
#dynamic answer4;
#dynamic correctAnswer;
#dynamic question;
#dynamic score;
#dynamic unique;
#dynamic quiz;
I had hoped to be able to fetch one of the two quizzes by doing something similar to what I'd do in Rails
Quizdata.where(quizId => 1)
Is it possible to only fetch the sports questions the way that I've done it (i.e. without using a table view). The reason why I thought tableView might be important is that it'll have object ids. I can't figure out how to get CoreData to retrieve every question for quizId 1.
I had previously imported data like this with json
{ "question" : "Do you like basketball", "answer1": "yes", "answer2": "no", "answer3": "maybe", "answer4":"of course", "correctAnswer": "yes", "unique": "2", "name": "sportsquiz", "quizId": "1"},
and then inserted and saved it with the two classes
Sure ...
I don't completely follow the logic on your Model As i'm not seeing a relationship between Quiz and QuizData.
If you had one, you would have an NSSet in Quiz containing a collection of QuizData. The you would simply perform an NSFetchRequest like this;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Quiz" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"quizId >= %#", [NSNumber numberWithInt:1]];
[fetchRequest setPredicate:predicate];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
FetchedObjects would contain an array of "Quiz" objects whose quizId >= 1. If you had set up your relationships correctly, each quiz object would contain a collection of quizData objects.
The main thing to remember is that Core Data is an Object Graph. As such, you would add quizData Objects to your Quiz object (as opposed to setting a relationship field and adding the relationship key to the Quiz object).
I'm just getting started with Core Data and am not sure how this works. I basically have a Person entity and an alarm entity. Each person can have many alarms. What I want is to go to a detailViewController of the person object and see their alarms. Because NSSet isn't sorted, I have a method to return the alarms sorted like so:
- (NSArray *)sortedTimes {
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Alarm" inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSSortDescriptor *timeDescriptor = [[NSSortDescriptor alloc] initWithKey:#"time" ascending:YES selector:#selector(compare:)];
[request setSortDescriptors:#[timeDescriptor]];
NSError *error = nil;
NSArray *objects = [self.managedObjectContext executeFetchRequest:request error:&error];
// Can I do this???
//self.person.alarms = [NSSet setWithArray:objects];
// for (NSManagedObject *obj in objects) {
// NSDate *date = [obj valueForKey:#"time"];
// NSLog(#"date: %#", [date description]);
// }
return objects;
}
What I'm wondering is, in the line self.person.alarms = [NSSet setWithArray:objects]; is that ok? I guess I'm not sure as to what actually is happening. My executeFetchRequest returns an array of the objects I want. Can I just go ahead and assign it to the person entity's alarm property? I wasn't sure if there was a relationship from Person->Alarm that I should not be mucking with, or if something like this is perfectly legal. Thanks!
First of all, your fetch request returns all alarms, not only the alarms of self.person. You have to add an predicate to the fetch request:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"person = %#", self.person];
[request setPredicate:predicate];
(assuming that person is the inverse relationship from the Alarm entity to the Person entity). But you don't really need a fetch request to get the sorted alarms of a person. A more direct way is
NSArray *objects = [[self.person.alarms allObjects]
sortedArrayUsingDescriptors:#[timeDescriptor]];
Now to your question: The statement
self.person.alarms = [NSSet setWithArray:objects];
just re-assigns the same set of alarms to the person. This effectively does not change anything, because it is the same set. In particular, it does not guarantee that self.person.alarms will now be sorted by time.
Remark: It you want to display a table view with the alarms of a person, you can also use a NSFetchedResultsController (FRC) as table view data source. The advantage of using a FRC is that the table view is automatically updated if objects are inserted, removed or updated.
Have a look at the NSFetchedResultsController and NSFetchedResultsControllerDelegate documentation which contains all the required code templates.
my program has a sqlite database with two related tables. One called "Rank" and other one called "Requirement"
I want to fetch all rows from the "Requirement" table that has a relationship with the specific row in a "Rank" table. Following is my code, it grabs the whole table, but I get the specified rows only according to the above mentioned rule.
-(NSArray *) getAllRequirementsForTheRank:(Rank *) rank
{
NSError *error;
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init]autorelease];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Requirement" inManagedObjectContext:self.context];
[fetchRequest setEntity:entity];
NSPredicate *searchType = [NSPredicate predicateWithFormat:#"Rank = %#", rank];
[fetchRequest setPredicate:searchType];
NSArray *scoutRequirementArray = [self.context executeFetchRequest:fetchRequest error:&error];
for (Requirement *r in scoutRequirementArray)
{
NSLog(#"Requirementttt : %# :", r.requirementName);
}
return scoutRequirementArray;
}
If you have the relationship modelled in core data, just get the linked objects from the relationship property. You don't need another fetch request. rank.requirements will give you an NSSet of everything you need. (I'm assuming names for your object and properties here).