Magical Record persistance issue - ios

I have following Problem:
First up... i use MagicalRecord for the whole CoreData thing
I have two Entities: A and B
They have a relation between each other
I create one instance of Entity A
I create several instances ob Entity B and set the relation
I don't call [[NSManagedObjectContext defaultContext] save];
It's fine
The relation is ok... I can check it using the findByAttribute method
If I call this save then the relation is destroyed...
the same check using findByAttribute does not find results any more
I have absolutely no clue what I am doing wrong or if it's a bug in CoreData / MagicalRecord...
I made a sample project showing the problem.
https://github.com/bliblablo/MagicalRecordsProblem
You can see the problem by following this steps:
click "create"
click "add"
click "check"
see the log output for results
click "save"
click "check" again and see the problem in the log :)
Any help is really appreciated!!!
Thanks a lot!

Sounds like the problem I was having with temporary ObjectID's not getting refreshed in the default context.
See my answer on NSPredicate not executed for details.
If you haven't already sorted it out, try checking the ObjectID of the NSManagedObject instances at various points. Especially if you (or Magical Record) are using the object as part of an NSPredicate to do the later fetches.

I think this is not MR bug. It is a bug from core data. See this post.
http://wbyoung.tumblr.com/post/27851725562/core-data-growing-pains

Related

Change relationship of NSManagedObject to different context

This is a follow up to an earlier question: Core Data: change delete rule programmatically.
I'd like to rephrase my question, and will do that here.
Briefly, my app allows updating entries from a 3rd party database, but I'd like to keep user annotations. So my workflow is:
iterate over all entities
download external xml and parse it into a new entity
if user annotations, change their relationship from old entity to new entity
delete old entity
During the import, the old entity is in the main context, the new entity is in a temporary import context.
Number 3 gives me problems, if I just change the relationship, then they don't show if I update my UI. If I use the objectID to get the annotation and then change the relationship as follows:
NSManagedObjectID *objectId = oldAnnotation.objectID;
Annotation *newAnnotation = [importContext objectWithID: objectId];
[newEntry addAnnotationObject: newAnnotation];
It's still not working - it's not showing up.
EDIT: if I change the context in the second line to newEntry.managedObjectContext, I get an Illegal attempt to establish a relationship 'foo' between objects in different contexts error.
What am I missing?
UPDATE: After some late-night hair-pulling debugging, I found that I when I was fetching the newEntry, I was actually fetching the oldEntry, therefore none of the changes would show up. The answer below by #Mundi pointed me in the right direction.
Copying the old annotations worked using my code above, followed by copying the attributes. For some user input with relationships in itself, I had to do a "Deep Copy", which I found here: How can I duplicate, or copy a Core Data Managed Object?.
I think creating a new entity and deleting the old one is a problematic strategy. You should try to properly update the existing entities and only create new ones if they do not yet exist.
Whenever I need an object from a different context, I fetch it. That being said, your object id code should work. However, there could be all sorts of other glitches, that you should check:
Did you save the importContext?
Did you save its parent context, presumably the main context?
Was the modified object graph saved to the persistent store?
Are you checking the results after you have saved?

CoreData loses relationship - only after reload

I am struggling with a problem since multiple hours - when I try to save some data to my CoreData - everything is fine, BUT when I restart my app, the relationship is lost.
It's an 1:n relation, the inverse relation is here (having multiple inverse relations, and all others are fine)
When I check with a sqlite-viewer, the chances are saved into the database, but when I reload the app, that 1 relation is gone.
There is also another question here, BUT: the solution did not work for me (and it seems that the solution not works for everybody) - and its 3+ years old.
Thanks in advance
Here is more information. The relation is between TaskCraft and Craft, like in this picture:
My CoreData Objects Are:
TaskCraft
#NSManaged var taskcraft: [TaskCraft]?
Craft
#NSManaged var craft: Craft?
My options:
Ill can reproduce the error all the time: When ill save the data to CoreData, my database look like:
When ill reload my app, and there is any CoreData-Fetch, my DB look like:
In this fetch i do not modify any of that NSManagedObjects.
Ok problem solved for me. Ill created (by Xcode) all the NSManagedObjects again, changed all NSSets to the real class names, deleted the simulator cache, and tried again.
Now it works fine, no relation is dropped anymore.
Very strange, but i am happy now.

NSManagedObject cannot change attribute

I am running into an issue with CoreData (using MagicalRecord) trying to change an attribute. I think this is the result of the object having relationships to two parent entities.
The object is a manual, this has a to-many relationship to both a car and library. The library contains all manual objects. A car has 1-3 manual items.
Every manual has a UID and the same object is shared between the car and library.
For some reason, once the object is set into the relationship for both, I cannot change the title (NSString) attribute of the manual.
I checked to make sure I am in the same context. Not sure what the issue is.
This is what I am logging:
NSLog(#"Manual Title: %#",manual.title);
//prints Old Manual
manual.title = #"New Manual"
NSLog(#"Manual Title: %#",manual.title);
//prints New Manual
I'm saving this inside a MagicalRecord saveUsingCurrentThreadContextWithBlockAndWait other unrelated NSManagedObjects in the same method are being saved.
When the app loads the data into the UI, it still reads "Old Manual"
Any suggestions?
Thank you for your time.
It turns out the issue was two-fold with the MagicalRecord methods I was using:
1) Instead of saveUsingCurrentThreadContextWithBlockAndWait I should have used saveWithBlockAndWait
2) When I was fetching the manual object, I wasn't passing the context, so I changed MR_findFirstWithPredicate to MR_findFirstWithPredicate:inContext
Hopefully this will save someone else some time

Need clarification on Cocoa error code 1570

With help from the great posts here, I understand the error. But I need some clarification please.
Say my managed object context (schema) has 3 tables (entities), and say each entity had 3 attributes of which one attribute for each entry is NOT optional.
So now for the first time, my app creates a managed object for the first entity, filling its mandatory attribute; app has not created managed objects for the second and third entities yet - didn't have to yet. When I try to save the context at this point, I get error code 1570. Is it because I have not filled out values for the second and 3rd entities?
I am not sure if this helps you.
But The cocoa error 1570 means that mandatory fields are not filled in. So please make sure your mandatory fields are not nil.
iphone Core Data Unresolved error while saving
Yep it was a mandatory field that was not filled in. The post above showed me which field.
If you have previously run it on your device (or simulator) with the attribute set as mandatory and then changed it to optional, delete the app from the device before running again. That was the problem for my app.
Hope that helps someone! :-)
In my case, I was setting a mandatory BOOL property directly as YES or NO, but you should use
NSNumber numberWithBOOL
in order to make it work.

Core Data Annotation - Repairing Missing Delete Propagation

I have a program that works perfectly fine. No crash, no bug or anything, but when it comes to deleting an NSManagedObject, the following message appears in the console.
Core Data: annotation: repairing missing delete propagation for to-one relationship
And then, some details about the relationship.
Once again, this does not make the app crash and the program goes on running as expected, but still, that makes me worried. Should I do something about it or is it alright to have some annotations from Core Data?
Thanks in advance :)
You should adopt a better strategy on deletion.
Go to your .xcdatamodeld, select the concerned relationship
Select your entity and relationship using an inverse relation
Choose what to do on Delete Rule
I had the same problem and it went away, as soon as i added an inverse relationship for the relationship in question.
You must save context after deleting a managed object.
After deleting something:
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSError *error;
if (![appDelegate.managedObjectContext save:&error]) {
NSLog(#"Error in Appdelegate>getLocalVersionAddFirstVersion");
}
Just as a new object is not saved to the store until the context is
saved, a deleted object is not removed from the store until the
context is saved. (Apple Documentation)
For me it was a slightly different problem: there was an orphan detection in place that removed the newly created object right away when it was saved, because I forgot to add the new parent relationship to the isOrphan() function. Strangely enough it lead to exactly this error ...

Resources