how do I create Reference attribute using CloudKit Dashboard - swift

I created a record using CloudKit Dashboard, so record is NOT created programmatically. Under "Default Zone, Model Data" (Sorry I need at least 10 reputations to post images.. :/ ) So here's the texted version.
"EventRef0 975f5715-3ccd-4c5f... DeleteSelf Reference"
So I have 3 reference field like this in records that I crated.
Now Under "Default Zone, Event." One of those record has the following header.
ID: 975f5715-3ccd-4c5f...
Created:Jan 20 2015 19:00 Created By: _ac6625... Modified: Modified By:
My Question is as following:
1) What do I put in the "Reference" Field of the EventRef0? The Event ID, which I currently have, or something else?
2) Is this is correct way to create multiple References, that is by creating 3 references for 3 Events that I want to reference?
3) When I want to fetch the Events, can I fetch all the CKReferences in one call to an array, and then fetch the Event data indexing that array, or do I have to make separate calls to get each event? I was hoping there is a way to get all the references in an array by keying on the "Reference" attribute. Not sure if that's possible. Preferably is Swift please.
Any help would be greatly appreciated. Thanks.

If you have a 'data' recordType what will have a reference to multiple 'event' recordType objects, then you should add a CKReference in the 'event' recordType where the CKReference points to the 'data' object. So the data object does not need to have a CKReference to the 'event' object. You can get all the event objects by querying the CKReference field for the id of the 'data' object.
Just query your 'events' recordType with a predicate like this:
CKReference* recordToMatch = [[CKReference alloc] initWithRecordID:dataID action:CKReferenceActionNone];
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"dataID == %#", recordToMatch];

Related

Core data: NSFetchedResultsController with objects are in a relationship

I have two entities CIDMPost and CIDMUser. CIDMPost has a one-to-many relationship with CIDMUser named invitees.
Now I have an instance of CIDMPost lets say postObject from where I can easily get the invitees by writing postObject.invitees which will return NSSet.
Now my requirement is I want those invitees (postObject.invitees) as NSFetchedResultsController to show in a UITableView with style Group. Also its need to satisfy the below.
Grouped by invitationStatus (an attribute of CIDMUser)
Order by invitationStatus ASC
Declaration:
I tried few things to fulfil my requirement but got a crashed and the reason was Invalid to many relationship. To know the solution of this crash I posted 'a question' an hour ago. But after few conversation with Daij-Djan I had come to know that the whole process I was trying is wrong.
Just fetch the users in your fetched results controller and apply the sort descriptors as desired filter by invitation with a predicate. Use the status field as the sectionNameKeyPath argument when creating the fetched results controller.
NSPredicate(format: "%# in invitations", post)
where post is the post object to which you want to display the invitees, and invitations is the reverse to-many relationship to the post to which users are invited.
(Note that I am assuming a user can get invited to more than one post, which seems logical. In your problem statement you mention a one-to-many relationship which it seems to me should thus be many-to-many).

Sorting entities in fetch request by id

I have a model named Store. In this I have attributes such as name, location, phone and so on. I want to sort the stores on Id´s like you do in SQL, however is this possible? Normally the frameworks add an auto Id for you. If Core Data does that how do I get a hold of the value, and is it possible to sort on this value?
Do I need to add a field to the model and handle this myself, which I do not want.
I saw something about using a Date field and let it have a default value of "NOW", is this how you do it? In that case of do you add default value?
Sorting by id (or primary key) is an unsupported scenario. Please see CoreData: How to sort NSManagedObject by its primary key? for a similar, duplicate thread.
It seems you like to have the id as a proxy for the created date. I recommend you add a property timestamp of type NSDate and initialize it to [NSDate date] when you create a new managed object instance. Then you simply sort by that.
newStore.timestamp = [NSDate date];
and
[NSSortDescriptor sortDescriptorWithKey:#"timestamp" ascending:YES];
Incidentally this is the default implementation of the old Apple project templates.

Core Data primary key ID for a row in the database

Suppose I have a list of books stored in Core Data. I want to search for a book by it's primary key ID.
I know the sqlite file created by Core Data has an ID column in each table, but this doesn't seem to be exposed to me in anyway.
Does anyone have any recommendations?
-[NSManagedObject objectID] is the unique ID for an object instance in Core Data. It can be serialized via -[NSManagedObjectID URIRepresentation]. You can retrieve the objectID from a persistent store coordinator with -[NSPersistentStoreCoordinator managedObjectIDForURIRepresentation:] and then get the object from a managed object context with -[NSManagedObjectContext objectWithID:].
BUT
You should keep in mind that Core Data is not an ORM. It is an object graph management framework. That is uses SQLite (and unique row IDs) as a backend is purely an implementation detail. The sooner you can get yourself out of the SQL/RDBMS mindset, the faster you will be happy with Core Data. Instead of trying to find an object from a stored ID, consider why you need that object and what object needs it. If an instance of class Foo needs to be able to get to an instance of class Bar, why not just create an association from the Foo to the Bar and set the appropriate Bar instance as the target of the association on the appropriate Foo instance. Let Core Data keep track of object IDs.
As Barry Wark said, remember always that Core Data is not an orm. Pure SQL details are not exposed to the user and every row is just an object. By the way, sometime you should need to access the "primary key", for example when you need to sync the coredata db with external sql databases (in my case I needed it in a callback function to change the state of an object after INSERT it with success in the remote db). In this case, you can use:
objectId = [[[myCoredataObject objectID] URIRepresentation] absoluteString]
that will return a string like: x-coredata://76BA122F-0BF5-4D9D-AE3F-BD321271B004/Object/p521 that is the unique id used by Core Data to identify that object.
If you want to get back an object with that unique id:
NSManagedObject *managedObject = [managedObjectContext objectWithID:[persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:objectId]]];
NB: Remember that if the receiver has not yet been saved in the CoreData Context, the object ID is a temporary value that will change when the object is saved.
This is the way you can get the object id as String using Swift from a NSManagedObject:
entity.objectID.uriRepresentation().absoluteString
in Swift this will be done by getting ID of the row as URI then get last path of URI
entity.objectID.uriRepresentation().lastPathComponent
the output of last path will look like this
p12
this output is string so you can remove the p using:
trimmingCharacters()
// Like this
let id = entity.objectID.uriRepresentation().lastPathComponent.trimmingCharacters(in: ["p"])

Core Data - Associate a Quantity to a Relationship

I have a Core Data entity called "Item" and it represents an item in a store so it has a name, price, and a few other attributes.
I would like to be able to create lists of these items and I am having some trouble figuring out how to do it.
The problem is that I need to be able to associate a quantity for each item in the list AND I need to be able to add the item to multiple lists.
So for example, say I have an item called "Bread" and I want to add it to two different lists with different quantities associated with each relationship.
I see that the documentation for Core Data says that a userInfo dictionary can be associated with a relationship but I can't seem to locate any information that would indicate whether or not that would work for me.
Any ideas?
This is probably not the best place for a userInfo dictionary. Instead, create a new entity, which has a list releationship, an item relationship, and a quantity attribute. When you add Bread to a list, you actually add this 'link' object, and hook up the Item and List relationships, then set its quantity.

Can I tell Core Data to use a specific unique ID for an y object when saving it?

Example: I read data from an XML file. This data has unique id elements. I want to store those objects with their original unique id. How would I do that?
I figured out I could ask the managed object for it's ID, like this:
NSManagedObjectID *moID = [managedObject objectID];
but here the problem is: The XML tells me with the id element which object this is, and I need to look up in the database of core data if this object already exists in there, or not. So is it the only option to make an id attribute in my managed object model for that entity and then query for that? Then I will have two id systems right?
Don't worry about the ObjectID of Core Data. This is an internal unique ID which is not guarantied to be constant during the object's life cycle (e.g. it will change when you save the object to sql store). Just create a new mandatory attribute in your model and flag it as indexed so retrieval will be fast.
In the entity associated to this kind of objects, simply add another attribute of type string, call it objectID or similar and declare it to be mandatory.