store objectID in CoreData - iphone

If I wanted to store a list of objectsID's of different entities in CoreData what would the data type be for the objectID so I could use it in an NSFetchRequest to later retrive the Entity?

You can not store NSManagedObjectID, but you can store the object's URI representation, and use that to retrieve the object id using NSPersistentStoreCoordinator's managedObjectIDForURIRepresentation: method. Since you seem to want a list, i would save it in a new entity and store the necessary information to identify the id and the entity name it belongs to, among other relevant information.

Related

What is the CoreData type that can be used for saving CKServerChangeToken?

I have an entity in CoreData called "ServerToken" that has two attributes zoneName and token. In the token attribute, I plan to store the CKServerChangeToken object. I plan to use the CKServerChangeToken for retrieving incremental changes from CloudKit. Can someone throw some light on... What type should be set for the token attribute to be able to store the CKServerChangeToken object?
Note: This question is not a duplicate of the below so question. The answer in the below link uses UserDefaults and I intend to use CoreData for saving the CKServerChangeToken.
Save CKServerChangeToken to Core Data
You can use transformable core data type, by which you can define your desired type in the NSManagedObject custom class.
See this related thread:
How to save Array to CoreData?

Unique id of core data to save in server

In my application I have to send values of my NSManagedObject to server & after getting a success result from server I must update a filed in my NSManagedObject.
On the server side the id field is an integer type. Is there any possible id in Core Data which i can send to sever and update the value again in my iPhone?
Is NSManagedObjectID suitable for this ?
NSManagedObjectID is really not appropriate for this. It's not numeric and doesn't convert to a numeric form. And if you're communicating on a server-- can the user use the same server account from more than one device? Because NSManagedObjectID is only valid on the device where the object was created. You can't create a managed object and tell it what object ID to use.
If you need a unique, numeric ID, you need to create one yourself. Add a numeric attribute to the entity description and use it for your own ID values. Core Data does not provide this, but it's easy to do it yourself.
NSManagedObjectID is fully under Core Data's control. That means you have little if no control over it. Say you're creating a database from fresh using data from the server, there is no way to instruct Core Data to reuse specific NSManagedObjectIDs (so you'll have to update the IDs on the server). NSManagedObjectID is meant to be used within Core Data in most cases.
You should use your own unique IDs, and this is pretty easily done with the following code:
NSString* uuid = [NSUUID new].UUIDString;
NSString* entityID = [[NSString alloc] initWithFormat: #"%#/%#", self.entity.name, uuid];
You can use either the uuid directly or use another ID scheme like /YourEntityName/<uuid> or whatever suits you.
NSManagedObjectID is unique enough for that purpose, no problem. But it changes its value exactly once - at leat it may. That is when a transient object becomes persistent. So make sure to save the context before you fetch the NSManagedObject's ID.

Fetching an NSManagedObject with Unique Identifier?

Do NSManagedObjects come with any kind of unique identifier?
I need to fetch a couple of objects but there is a large chance they have identical attributes, so how can I, after fetching these objects, differentiate them?
Thanks.
Yes. Every NSManagedObject has an -objectId accessor which returns an NSManagedObjectID instance. These uniquely identify the object in question. You can then retrieve the object again using either of NSManagedObjectContext's methods -objectWithID: or -existingObjectWithID:error:.
Note that if the object has not yet been saved after insertion, the object ID will be a temporary ID that will change when it's saved. You can force a persistent ID to be assigned with -[NSManagedObjectContext obtainPermanentIDsForObjects:error:], although this is just as expensive as an actual save.

keeping track of accessed objects in CoreData via objectID?

I want to have table in CoreData that holds a list of other CoreData objects I have accessed, for instance I have Clients and I want a table RecentClients that is simply holding this list and the date they were accessed.
Can I store the objectID and then do a fetch request based on that?
EDIT:
See Ben's answer below and then go here:
http://cocoawithlove.com/2008/08/safely-fetching-nsmanagedobject-by-uri.html
You'll want to convert the NSManagedObjectID to a string by calling its -URIRepresentation method. You can then convert the string back to an NSManagedObjectID using NSPersistentStore's -managedObjectIDForURIRepresentation: method.
If you store the strings, you should be able to do what you're describing, though you won't use a fetch request; you'll use -[NSManagedObjectContext objectWithID:]
How are you planning on storing the access date? If you make it an attribute of your Client entity, you can bump it each time the object is accessed and then use an NSFetchedResultsController that fetches Clients ordered by the access date. The downside is, of course, that you're modifying the instance every time you access it, which may not be ideal.
You could just create the RecentClients as another entity in your Core Data model. It would then have a one to many relationship with the Client entity.

Strategy problem: Retrieving data from XML to update local Core Data DB?

I need some advice how to go about this:
1) I retrieve an XML from a web server.
2) I want to store all the entities (i.e. Friends) from that XML locally on the device, using Core Data.
3) So I parse the XML and make an Managed Object for every Friend in that XML
4) But I want to make sure that I don't add one Friend multiple times into the DB. How could I achieve that?
-------------- my strategy thoughts on this ----------------
A) While parsing the XML, I create an Managed Object of the Friend entity as soon as there is a Friend element started. At that point I don't know which friend it will be, until the NSXMLParser stepped through all the upcoming attributes like firstName, id, etc.; After the End-tag for the Friend element, I have that friend in my Managed Object Context. Then I make an NSFetchRequest to see if that friend is stored already. Problem is, that the new friend is already part of the context, so probably Core Data will return always a match!?
B) I need two different Managed Object Contexts so that the parsed Friends first go into MOC_A, and then I query MOC_B (the actual local store) without that the new parsed friends disturbe my query to the local store. So I can find out if the friend already existed.
C) While parsing a friend from the XML I just create a new Managed Object instance WITHOUT adding it to an Managed Object Context (possible ?!). Later, when the friend is pares completely, I check against Core Data if it is stored. If not, I add it. Otherwise I throw the object away.
D) I need another strategy.
You should use a new indexed attribute in your Core Data entity to store the unique ID from the XML. Before adding an object, you will have to manually check if an object with that ID already exists.
UPDATE
The key is to not add a managed object to the context until you have determined that it is new.
This is pretty straightforward given the unique ID, but it sounds like you can't parse for the unique ID first. In that case you should use a temporary mutable dictionary (NSMutableDictionary) to store the data as it's parsed.
If you determine that the friend is new, you can create it and copy the data over from the dictionary. If the friend is not new, you can discard the dictionary.