Core data FIFO? (first in first out) - ios

Im sitting with this issue bugging me. I have core data working fine, but when it fetches, in my case, the users, they come back in different orders. Normally would use the standard unique identifier, but core data doesn't have this. So....
Do I manually create an ID entity_property and assign it incrementally, or is the "object id" being made in incremental order; incremented maybe by 1, or just random IDs? hence making me able to use object id.
My goal is to get my fetched array in the same order the users was inserted.
Thanks

You'll need your own technique for generating the unique ID. Run that code in your NSManagedObject subclass's -awakeFromInsert, which is called once, when the object is inserted into the datastore. You can add a timestamp, or the value of an incrementing counter.
There's no built-in support for an autoincrement ID. You'll need a class variable, and increment that yourself in -awakeFromInsert. You'll also have to persist that value across launches, either as its own Entity or within the persistent store's metadata.
You might benefit from using an ordered relationship, if those users have a one-to-many relationship with some other entity.
The NSManagedObjectID is unique within the store, but will change when the NSManagedObjectContext is saved (and the NSMOID goes from temporary to permanent). No promises are made about its sequence or pattern of construction. And it can change during a managed object model migration. So don't depend on it for anything you need to control.

core data does not return ORDERED data. so, if your data is "string" or "date" type then you can simply sort your data by ascending/descending after fetching from code-data.

Related

Save multiple values per key in CoreData

I'm currently looking into CoreData and need to save multiple values per key. In my case I just need to save a couple of strings, max 9, for a single Key in CoreData.
Specifically, I want to save players for a game. My game object already contains relationship objects to these players, but I also want to save the Player names as records on the game object itself, as players can be deleted by my users and I want my game objects to be immune for that.
I know in Cloudkit you can set the value of a certain key to e.g. "set of strings", and this can be done in CoreData relationships to when creating a one-to-many relationship. I was wondering if there is a by-the-book way to do this in regular CoreData key-value pairs as well.
It's easier to think about CoreData as objects rather than low-level data storage. It's not really designed as a key/value system (except in the sense that any object's properties can be thought of as a dictionary).
For the example you give, it might be more in keeping with CoreData's object persistence style to flag deleted players as unavailable rather than removing them, so that your history remains intact.
You could use an attribute of type Transformable to store your set. NSArray and NSSet conform to NSCoding so CoreData can take care of all data transforming, archiving and unarchiving for you.

CoreData object modeling with multiple timeframes for weather data

I do have some JSON file http://jsonblob.com/530664b3e4b0237f7f82bdfa I am pulling from forecast.io.
I am little confused how I should be creating my CoreData entities and relationships.
In below setup, I made my Location entity as the parent entity and created a separate entity for Currently, Minutely, Hourly, Daily. However I have decided it's best to hold all the information regarding the weather data in one entity, so I created a Data table for that purpose and tied it to Daily and Currently in the image below.
Before going further, I paused and would like to get a second opinion on it. Is this a valid way of going forward with this?
EDIT: Based on Wain's response I changed my model to this
Currently Minutely and Hourly add little value as they don't have any attributes or relationships. It's also generally easier to add a type attribute rather than having a number of sub entities because you can easily filter the type using a predicate while doing a fetch. If you're going to add more in the future then there could be a case for keeping sub entities.
Once the entities are trimmed down then you only have a Location and Data with a relationship. You should make that relationship bi-directional so that Core Data can manage the data store contents better. (this applies to all relationships, even if you keep the sub entities you already have).
Other than that, fine :-)

How to fetch the last entry of each entity in core data iOS

I am making a chat application in iOS. I saved the last conversation of every friend. My core data entity has 3 fields - jID, message and timestamp. I don't set indexing on any field.I just want to fetch the last message of each jID. So,please help me and also tell me whether to set indexing on any field so that fetching process would be appropriate.
You could also add a one-to-one relationship between your entity and the last conversation (you will have to maintain it yourself, if you reveal your model I might be able to be a bit more specific).
A property that is used to filter data, and is used to access elements by, should probably be indexed.
This mean that you probably would want your jID and timestamp indexed.
If you want to fetch the last object, you'll need to have them ordered. Timestamp would be fine for this. And if you want to fetch the last object, reverse the ordering and just fetch the first instead.
If you want to use jID, the ids will have to be in some kind of order.

CoreData - Is there a good way to upsert items?

Just wondering whether there is a good way to upsert items in a CoreData db?
Or is there a way for me to consider a CoreData db as a set?
I mean, if I insert an item into the db and if there is already an identical redundant item there, the db ignores it. Any way to conveniently do it? or I have to query each time when I insert in order to avoid redundancy?
I recently read this article
https://www.upbeat.it/upsert-in-core-data/
Basically, first create a constraint on the name, then you specify the TrumpMergePolicy in the Core Data context.
managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
No - Core Data doesn't have a way of knowing how you consider an item "identical" or "redundant." The definitions of those words can change with almost every entity you create - for example, departments in a business might have unique names, but multiple people can have the same name (and frequently do).
You can take advantage of Core Data's querying power, however, and do a quick query with an NSPredicate to find out whether a record with your chosen identifier already exists. You might factor this query out to its own method (perhaps on your managed object subclass) so that you can call it conveniently.

Core Data modeling issues (how to update attribute based on a relation's relation?)

I have an entity (Order) that has a to-many relationship with an entity Item, which has a to-many relationship with an entity Note. If the price changes for a Note, or a Note is added, the 'price' attribute for the associated Order must update.
Right now, my solution is to have all Order objects sign up for NSManagedObjectContextDidChange notifications, and check all the inserted/changed objects to see if any of those objects is one of the Order's Item's Notes. However, this is very inefficient and hacky, and is leading to a few more performance issues that can be optimized away, but I'm starting to realize that my solution is what's faulty, not necessarily the issues.
So, what's the best way to do this?
EDIT: To answer the questions brought up by Rog: I'm looking to propagate the changes to model data, which are observed by view controllers via KVO. The problem I'm noticing is, if the price of a Note related to an Item is adjusted, there's no facility to account for this in Core Data. If I use keyPathsForAffectingPrice on Item, and return "notes", that only accounts for if notes are inserted/deleted, not if the Note price is adjusted.
If this wasn't Core Data, I'd write my own accessor for note price to just say [self.item willChangeValueForKey:#"price"], self.price = x, [self.item didChangeValueForKey:#"price"]; but that isn't possible since I can't do custom accessors in Core Data, right?
We problably need more details about your code to be able to help - i.e. are you looking at ways to propagate changes to your model data or to the UI?
Are you using a fetchedResultsController at the moment?
The way I see it, if your Order contains Items and the Items contain Notes, any updates to your "child" attributes will be effective immediately (provided you have your reverse relationships setup properly).
Then if you're looking at ways to updating your UI accordingly, then we need to know how you are currently fetching and populating your views with your Coredata entities.

Resources