Sorting entities in fetch request by id - iphone

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.

Related

how do I create Reference attribute using CloudKit Dashboard

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];

Saving NSDate and NSNumber and/or in the same core data attribute

It has to be specified while creating the core data model in IB what Kind of attribute it will be, theres choices like String, Date, Integer, Decimal etc.
My question is, how do i store lets say an NSDate in the same attribute, and at some other time, add a new entity but this time with an NSNumber for that attribute.
In other words, i'd just want an equalent of id Object in coredata, where after fetching, i'd check if [[Object isKindOfClass[NSDate class]] or an NSNumber.
I've heard of transformable, but i'm not creating customized Objects to be stored.
Any light on this would be great
This is a very bad idea. Actually, dates are represented as numbers in SQLite, but Core Data could be using a different kind of store, so you are just making too many assumption of how things are going to work.
It would be much cleaner and easier to specify additional attributes for your entity, a number and a date. You could then easily check if any of them is nil or contains a value. Even introducing a third attribute to tell you if the object has a date or number would be preferable to your setup.
I have come across this scenario in the current project. If your values contain int, float, boolean you can use NSNumber as attribute and if it contains NSDate then attribute should be as a string in the entity.
Hope this help.

How do I get a sectionNameKeyPath from a subset of a one-to-many relationship?

I am trying to get a set of values from a one-to-many relationship for my section names. My fetchRequest entity is set to the single entity, and I would like to use (for example) #"to_many.attribute1" for the sectionNameKeyPath. However, I only want to use a certain subset of those to sort the entity.
Is there a way to add a predicate to the sectionNameKeyPath?
Or do I, as I'm afraid I might, need to recreate my data model so that data is easier to access?
One option I've used when my sectionNameKeyPath needs to reference something that is non-trivial is to add a new attribute to my model and mark it as Transient.
Then you can add a category to the managed object which has a getter that calculates the field based on your rules.
#implementation MyObject (SectionKeyPathAdditions)
-(NSDate *)toManyAttribute1Date // This is the new transient attribute name
{
NSDate *dynamicReturnDate = [NSDate date];
// use app logic to grab the subset of valid dates from attribute1
return dynamicReturnDate;
}
Your predicate would be something like:
ALL to_many.attribute1=="something"
The ALL and ANY operators search sets which is what a to-many relationship returns. Although, you can't daisy chain them e.g.
ALL to_many.another_to_many.attribute1

how to create a auto-incremented attribute in xcode managed object model

Hey, what i want to do is to make a int that will be the ID of the entity and auto increment itself whenever a new entity is added (just like a SQL identity property). Is this possible? i tried using indexed (checked on attribute) however there is no description to what indexed even does.
EDIT:
I am adding annotations to a map, when you click the pin the annotationview with a chevron shows up. Now when you click this button i would like to load an associated picture. However the only way i know how to link the picture to this button is to give the picture a unique id, and then set the button.tag to this id and then load based on the button.tag.
This kind of concept is contrary to the principles of Core Data - the idea is that you're managing sets of entities with properties, not rows in a database or other things that need to be uniqued. (If you're using the SQLite store, Core Data will create an ID for you behind the scenes, but you can't access it.)
You should probably reconsider (or at least give more details about) the problem you're trying to solve, because as it stands, Core Data will not let you autoincrement a variable.
If you absolutely must, you can manually increment on insert by having some NSNumber ID field on your entity, then every time you insert a new entity, get the existing entities sorted by that ID and limited to one result (using a NSFetchRequest with various options), grab that entity's ID, add one, and set it as the new entity's ID. It's a lot of work, though, and probably error-prone.
Edit: Based on the extra information, I'd say rather than trying to autoincrement an ID yourself, find some other guaranteed-unique property of the annotation and either use that directly or write a hash function that uses it to generate your unique ID. For example, use the latitude & longitude to build a single integer that uniquely represents that point within your system. Other than that, there's no way around having to increment the ID yourself.
I agree that this is a sticky problem - I haven't ever come across something like this in Core Data before, and I can see where autoincrementing might be useful :)
This is the simplest way, but takes some effort.
Create an "index" attribute in your Entity. Make it a String
When you create a new one, generate a GUID using CFUUIDCreate() and CFUUIDCreateString()
Assign the GUID to the "index" attribute
Voila, you now have a nearly-perfect unique ID, ready to use for caching locally and using as needed
CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef uuidStringRef = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
NSString* guidString = [NSString stringWithString:(__bridge NSString*)uuidStringRef];

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.