I have an xcdatamodel with a set of entities built in a static library.
I am including this static library in a project. I would like to create another model in main project, with entity named Task. I would like to have an attribute in the entity where I could store the NSManagedObjectID of an entity created in static library. With NSManagedObjectID I could easily fetch the main store and get the entity.
In the end there could be many Task entities refer to an objectID.
Is it possible ? I also understand that this is sounds like a relational model, which Core Data isn't, so is there a better solution for dealing with the subject?
thanks
The NSManagedObjectID is in itself not coding compliant. But you can get the URL representation of an object ID and store that. Like this:
myObject.externalTaskURL = [[task objectID] URIRepresentation];
Then in order to get the object ID back to retrieve the task object it refers to later (psc is your NSPersistentStoreCoordinator where the Task entities live):
NSManagedObjectID* taskID =
[psc managedObjectIDForURIRepresentation:myObject.externalTaskURL];
Make sure to never do this to a temporary managed object ID.
You can store a managed object ID as a NSURL in a transformable attribute.
Related
I'm a nwebie in Core Data, i have designed a navigation based application and some of the data i use are created on run time(come from a URL via JSON). I took a few tutorials an searched for almost a day but haven't still realized how to save the incoming JSON data to the Entity (or event?) in my Core Data model. I fetch the data in the DetailViewController class and i need to save this data to Core Data(I have prepared an Entity with 7 properties). Can anyone please help?(If you know a good tutorial or sample code i will be pleased)
EDIT This may be a little specific but i really have trouble with and need just a little help.
My data comes to the app from a kind of restful server(i wrote it in PHP), firstly user enters his/her login informations(which i have saved to the database on server before) and when the response data comes i will use different elements of it in differen views(for example the user_id will be used on a view and the buttonData etc on other views). My question is, how will i save JSON data into my core data model(has tree Entities for the moment). Thanks in advance
Note: I lokked arround a lot but couldn't find any answer&tutorial about an app like mine
The best way to do that would be to create entities corresponding to JSON structure. Easiest was is when each JSON object becomes an entity, and arrays become arrays of entities. Be reasonable, however, and don't introduce too much overkill for JSON subobjects that are essentially part of its superobject.
When you have created entities, you can start off with the parsing and translation. Use some JSON framework (starting from iOS5 there's one from Apple) and parse JSON string into object tree, where root item is either an NSArray or NSDictionary, and subelements will be NSArray, NSDictionary, NSNumber, NSString or NSNull.
Go over them one by one in iterational loops and assign according values to your core data entity attributes. You can make use of NSKeyValueCoding here and avoid too much manual mapping of the attribute names. If your JSON attributes are of the same name as entity attributes, you'll be able to just go over all dictionary elements and parse them into attributes of the same name.
Example
My parsing code in the similar situation was as follows:
NSDictionary *parsedFeed = /* your way to get a dictionary */;
for (NSString *key in parsedFeed) {
id value = [parsedFeed objectForKey:key];
// Don't assign NSNull, it will break assignments to NSString, etc.
if (value && [value isKindOfClass:[NSNull class]])
value = nil;
#try {
[yourCreatedEntity setValue:value forKey:property];
} #catch (NSException *exception) {
// Exception means such attribute is not defined in the class or some other error.
}
}
This code will work in trivial situation, however, it may need to be expanded, depending on your needs:
With some kinds of custom mappings in case you want your JSON value be placed in differently named attribute.
If your JSON has sub-objects or arrays of sub-objects, you will need to detect those cases, for example in setters, and initiate new parsing one level deeper. Otherwise with my example you will face the situation that assigns NSDictionary object to an NSManagedObject.
I don't think it is reasonable to dive into these, more advanced matters in scope of this answer, as it will expand it too much.
I suggest you to use this library : https://github.com/TouchCode/TouchJSON
And then if you want to make a factory to parse json and feed your code data, you can use selectors to call methods to fill all your attributes.
Chances are your JSON data gets converted to an NSDictionary or NSArray (or some combination of the two). Simply extract the key/values from the JSON structure and add them to your entity class.
This lib helps me lot
Features
Attribute and relationship mapping to JSON key paths.
Value transformation using named NSValueTransformer objects.
Object graph preservation.
Support for entity inheritance
Works vice-versa
I'm a nwebie in Core Data, i have designed a navigation based application and some of the data i use are created on run time(come from a URL via JSON). I took a few tutorials an searched for almost a day but haven't still realized how to save the incoming JSON data to the Entity (or event?) in my Core Data model. I fetch the data in the DetailViewController class and i need to save this data to Core Data(I have prepared an Entity with 7 properties). Can anyone please help?(If you know a good tutorial or sample code i will be pleased)
EDIT This may be a little specific but i really have trouble with and need just a little help.
My data comes to the app from a kind of restful server(i wrote it in PHP), firstly user enters his/her login informations(which i have saved to the database on server before) and when the response data comes i will use different elements of it in differen views(for example the user_id will be used on a view and the buttonData etc on other views). My question is, how will i save JSON data into my core data model(has tree Entities for the moment). Thanks in advance
Note: I lokked arround a lot but couldn't find any answer&tutorial about an app like mine
The best way to do that would be to create entities corresponding to JSON structure. Easiest was is when each JSON object becomes an entity, and arrays become arrays of entities. Be reasonable, however, and don't introduce too much overkill for JSON subobjects that are essentially part of its superobject.
When you have created entities, you can start off with the parsing and translation. Use some JSON framework (starting from iOS5 there's one from Apple) and parse JSON string into object tree, where root item is either an NSArray or NSDictionary, and subelements will be NSArray, NSDictionary, NSNumber, NSString or NSNull.
Go over them one by one in iterational loops and assign according values to your core data entity attributes. You can make use of NSKeyValueCoding here and avoid too much manual mapping of the attribute names. If your JSON attributes are of the same name as entity attributes, you'll be able to just go over all dictionary elements and parse them into attributes of the same name.
Example
My parsing code in the similar situation was as follows:
NSDictionary *parsedFeed = /* your way to get a dictionary */;
for (NSString *key in parsedFeed) {
id value = [parsedFeed objectForKey:key];
// Don't assign NSNull, it will break assignments to NSString, etc.
if (value && [value isKindOfClass:[NSNull class]])
value = nil;
#try {
[yourCreatedEntity setValue:value forKey:property];
} #catch (NSException *exception) {
// Exception means such attribute is not defined in the class or some other error.
}
}
This code will work in trivial situation, however, it may need to be expanded, depending on your needs:
With some kinds of custom mappings in case you want your JSON value be placed in differently named attribute.
If your JSON has sub-objects or arrays of sub-objects, you will need to detect those cases, for example in setters, and initiate new parsing one level deeper. Otherwise with my example you will face the situation that assigns NSDictionary object to an NSManagedObject.
I don't think it is reasonable to dive into these, more advanced matters in scope of this answer, as it will expand it too much.
I suggest you to use this library : https://github.com/TouchCode/TouchJSON
And then if you want to make a factory to parse json and feed your code data, you can use selectors to call methods to fill all your attributes.
Chances are your JSON data gets converted to an NSDictionary or NSArray (or some combination of the two). Simply extract the key/values from the JSON structure and add them to your entity class.
This lib helps me lot
Features
Attribute and relationship mapping to JSON key paths.
Value transformation using named NSValueTransformer objects.
Object graph preservation.
Support for entity inheritance
Works vice-versa
I want to read some data from Core Data for statistics. My datamodel is like in the tutorials found in the internet (a bit of clicking and voilĂ it is ready). But now I want to work with the data.
My function:
-(int)calcAve {
int ret=0;
ret = [[stats valueForKey:#"aveScore"] intValue];
NSLog(#"%d",ret);
return ret;
}
stats is the object connected from the .xib to the class, which. This object is bound to the entity Stats in the datamodel. [stats entity] returns the correct value.
aveScore is one object in the entity stats (no misspelling, checked it multiple times!). No the error shows me, that stats is not the correct datamodel:
this class is not key value coding-compliant for the key
What is wrong with this? Is there a simple way to read out the data from Core Data?
I am not sure what you managedObject in this case is. However usually you want to store more than one managedObject of the same class in a managedObjectContext. For example several recipes objects in a MOC. Every recipe has the properties.
Your call for value for key sounds reasonable. Check what that class of the stats object is. If it is not of the class NSManagedObject or your custom subclass of it you have a problem. You can only store NSManagedObjects within CoreData. You can check it like this:
NSString *className = NSStringFromClass([stats class]);
NSLog(#"class name: %#",className);
The way you are asking I suggest you try to read the CoreData docs again and look at the Recipes example in Apple's sample code library.
I have a Core Data object that contains an NSSet of other objects (e.g. Library object contains NSSet of Books). What's the best way to check if an instance of Library contains a book with a certain bookID?
Is it possible to be done with Key Value coding or do I have to enumerate all books and check them manually?
Yes, you can use KVC for this.
BOOL bookExists = [[set valueForKey:#"bookID"] containsObject:#"myBookID"];
I have this code:
NSEntityDescription *userEntity = [[[engine managedObjectModel] entitiesByName] objectForKey:#"User"];
User *user = [[User alloc] initWithEntity:userEntity insertIntoManagedObjectContext:[engine managedObjectContext]];
and I want to know the id of the object inserted to the managed object context. How can i get that?
Will that id remain the same for that object's lifetime or will it persist to the sqlLite database beneath this and be something that can be used to uniquely identify it during a fetch operation (my ultimate goal).
Any help appreciated // :)
If you want to save an object's ID permanently you need to:
Save the object into the context so that the ID changes from a temporary to a permanent ID.
Extract the URI version of the permanent ID with -[NSManagedObjectID URIRepresentation]. That returns a NSURL you can store as transformable attribute in another managed object.
You can get the object by using -[NSPersistentStoreCoordinator managedObjectIDForURIRepresentation:] to generate a new NSManagedObjectID object and then use -[NSManagedObjectContext objectWithID:] to get the actual referenced managed object.
The URI is supposed to identify a particular object in a particular store on a particular computer but it can change if you make any structural changes to the store such as migrating it to a new model version.
However, you probably don't need to do any of this. ObjectIDs play a much smaller role in Core Data than they do in other Data Model systems. Core Data maintains an object graph that uniquely identifies objects by their location in the graph. Simply walking the graph relationships takes you to a specific unique object.
The only time you really need ObjectID is when you're accessing object across two or more persistent stores. You need them then because relationships don't cross stores.
Read up on "managed object IDs" in the Core Data Programming Guide
You can get the object id from the object with something like:
NSManagedObjectID *moID = [managedObject objectID];
First, you are constructing your objects in a non-preferred manner. Generally you should:
User *user = [NSEntityDescription insertEntityForName:#"User" intoManagedObjectContext:[engine managedObjectContext]];
Second, when you create the object it will get a temporary id which you can access via [user objectID] as David mentioned. Once you save the context then it will get a new "permanent" id.
However this id can and does change over the lifetime of the entity (although not the instance). Things like migrating the data can cause this id to change. However, between saving the context and exiting the application the id will remain the same.