What object is returned by using Fetch Request in Core Data? - iphone

Apple Documents says "If a context already contains a managed object for an object returned from a fetch, then the existing managed object is returned in the fetch results"
My Question is If I have updatd the object in the context but not saved the context yet then what object will Fetch Request return? Updated object from Context or New one from Datastore.

Your quote answers that question; it will be the one in memory. With that comes the caveat that if you make a new NSManagedObjectContext and perform the fetch request on that context, you will get the object from the data store.

It depends on the includesPendingChanges setting of the fetch request. By default,
includesPendingChanges is YES, which means that the fetch will get currently unsaved
changes.
However, if you use the NSDictionaryResultType result type for the fetch request,
this implicitly implies includesPendingChanges = NO, and you will get only results
from the store.

I guess it returns Updated object from Context.
Note: Due to low reputation i have to put as answer.

Related

AngularFire docData read value once

What is the correct way to read the content of a document as value without subscription ?
Keep in mind that when persistence is enabled the Observer receives two values, first value is the locally persisted one and the second is the actual value that is stored in the database.
You can use get() method to retrieve the contents of a single document.
For More details you can check this StackOverflow thread

Get Deleted Object in AbstractMongoEventListener

I want to run some logic when an Object get deleted from MongoDB. I am using SpringData Mongo.
I am using AbstractMongoEventListener as the object can be deleted from collection through number of ways and I am overriding the
public void onBeforeDelete(BeforeDeleteEvent<Object> event)
method. But there are no method in event object which will return the Object I am going to delete.
event.getSource() and event.getDocument() returns the document. How can I get the object.
Somehow this Event seems to be messed up. In difference to the other MongoMappingEvent<T> descendents, this one inherits a MongoMappingEvent<Document> through AbstractDelteEvent<T>. I cannot explain this difference.
But as I also was in need to retrive the Documents before deleting them, I used the debugger to find, it is possible to retrive the Document Ids, using some hackish shit undocumented get("Key")-chain.
event.getDocument()
.get("_id", Document.class) // BSON Document!
.getList("$in", ObjectId.class) // ObjectId.class or what ever Type your Id is.
With that you can retrive a list of the ids of your documents. Take the repository or what ever, and use those ids to fetch the documents.
I do really not like using those string-key-things that I have not found in a documentation, as who knows when they will be removed.
I would love to remove this answer as soon as someone provides a less hackish way.
Be aware, that when you are using an #EventHandler, it can not consider the type parameter.

Dependency between data store

TL;DR
What's the best way to handle dependency between types of data that is loaded asynchronously from different backend endpoints?
Problem
My app fetches data from a backend, for each entity I have an endpoint to fetch all instances.
For example api.myserver.com/v1/users for User model and api.myserver.com/v1/things for Thing model.
This data is parsed and placed into data store objects (e.g. UserDataStore and ThingDataStore) that serve these models to the rest of the app.
Question
What should I do if the data that comes from /things depends on data that comes from /users and the fetch operations are async. In my case /things returns the id of a user that created them. This means that if /things returns before /users, then I won't have enough data to create the Thing model.
Options
Have /things return also relevant /users data nested.
This is bad because:
I'll then have multiple model instances User for the same actual user - one that came from /users and one that came nested in /things.
Increases the total payload size transferred.
In a system with some permission policy, data that is returned for /users can be different to /things, and then it'll allow partially populated models to be in the app.
Create an operational dependency between the two data stores, so that ThingsDataStore will have to wait for UserDataStore to be populated before it attempts to load its own data.
This is also bad because:
Design-wise this dependency is not welcome.
Operational-wise, it will very quickly become complicated once you throw in another data stores (e.g. dependency cycles, etc).
What is the best solution for my problem and in general?
This is obviously not platform / language dependent.
I see two possible solutions:
Late initialization of UserDataStore in ThingDataStore. You will have to allow for creation an object that is not fully valid. And you will also need to add method that will give you an information whether UserDataStore is initialized or not. Not perfect, because for some time there will exists an invalid instance.
Create some kind of proxy or maybe a buider object for ThingDataStore that will hold all information about particular thing and will create ThingDataStore object as soon as UserDataStore related with this instance will be received.
Maybe it will help you. Good luck!

Checking for existing value in NSFetchedResultsController / Core Data

I have some code that calls an API and gets a set of results back, let's call them 'message' objects. Each message has a unique ID.
Unfortunately, I cannot guarantee that the server will not give me back a message I have not previously received and stored in my core data database.
The unique ID is set up as an NSNumber field in my 'Message' entity.
Is there a way 'on-the-fly' to check the database to see if a 'Message' already exists with a given unique ID?
Currently I'm creating an instance of a helper object each time I need to check, and simply creating an NSFetchedResultsController returning filtered results via an NSPredicate. If any results are returned, I move on, or store in the database. I suspect this is a slow approach...
Any help?
Looks like this is what I need:
NSUInteger count = [self.managedObjectContext countForFetchRequest:fetchRequest error:&error];
This gives me back the count without actually doing the query - much better.

What's the difference between -objectRegisteredForID: and -existingObjectWithID:error:?

What's the difference between getting an managed object with
- (NSManagedObject *)objectRegisteredForID:(NSManagedObjectID *)objectID
and
- (NSManagedObject *)existingObjectWithID:(NSManagedObjectID *)objectID error:(NSError **)error
What are "registered" objects? What's the difference between "registered" objects and "unregistered" objects?
What are "registered" objects?
Judging from the results I've gotten using these methods, a registered object is one that has been fetched into the MOC. If an object exists in the persistent store but has not been fetched, feeding its objectID to the objectRegisteredForID method will return nil.
How could you even have its objectID if it had not been fetched? Well, I visited this question when implementing a Revert routine. I dumped any unsaved changes by replacing the database with an older copy, cleared the context and then reaccessed it. But I wanted to be able to restore the user's selection of objects to the cache of a table. So, before doing the reversion, I stashed the objectIDs that the user had selected in an array. Then, after the reversion, I rebuilt the table cache using the stashed objectIDs.
When I called objectRegisteredForID using these stashed objectIDs, it always returned nil. (But if I tested this before getting a fresh context, it would return the corresponding object -- which at that point was a fetched, loaded object. Hence my inference as to the meaning of "registered.")
When I called objectWithID using these stashed objectIDs, everything was fine unless the object had been deleted post the last save, in which case it would no longer exist in the database and the invalid but non-nil return would cause exceptions later.
So I used existingObjectWithID:error. If the object still existed, it would be returned. If it no longer existed, the return would be nil and the error's localizedDescription would be "Attempt to access an object not found in store."
Years after the fact:
As Wienke suspects, registered objects are those already in memory for that context. So objectRegisteredForID: will return an object only if somebody else has previously obtained that object.
objectWithID: will return an object if it currently exists in the persistent store.
So the really important distinction is:
objectWithID may go to the persistent store.
Note the corollary: objectWithID may have to perform a fetch. That means locking the store. So:
if the store is already locked by somebody else, objectWithID may block, whereas objectRegisteredForID will never block; and
supposing you had an array of 30 object IDs and you performed objectWithID for each, you'd potentially do 30 separate trips to the store — it'd be much faster to check whether the objects are already registered and then, if any aren't, use an NSFetchRequest to get the rest. Notice that a self in X query can accept an array or set of object IDs to return actual objects even though that wouldn't technically exactly match the normal Objective-C meaning of 'self'.
Falling back on NSFetchRequest is also generally preferable if you have any relationship paths you're going to need prefetched. So there's potentially quite a lot of performance to be gained.
To your first question:
objectRegisteredForID: is the quick & easy way to get the object -- it either returns your object or it returns nil letting you know that it could not. You use this when you either already know why the result might be nil or you don't care.
existingObjectWithID:error: is similar, in that it returns either your object or nil but, in addition, if you pass an error parameter, it will tell you WHY it returned nil. You may want to do this if you plan to do any sort of error reporting (a log message or alert), or error handling (perhaps you plan to take different actions, depending on which kind of error is returned.
EDIT: In addition (per docs), if there is not a managed object with the given ID already registered in the context, the corresponding object is faulted into the context.
I suggest that you break out the "what are registered objects?" portion of your question to a separate question in order to facilitate both getting a better answer (based on the subject line matching the question) and to help future spelunkers who may come looking for an answer.
I was recently confused as to why registeredObject(for objectID: NSManagedObjectID) was returning nil, but there was a simple explanation: the NSManagedObject instances I fetched were not retained: I extracted the information I needed from them and let them be deallocated, which seems to "unregister" them from the managed object context, though they could easily be retrieved using other methods on NSManagedObjectContext. I find the CoreData documentation truly terrible: "registered" is just one of many distinctions that are not clearly explained.