PDA

View Full Version : MagicalRecord




gummycat
Aug 29, 2012, 07:17 AM
I have a little test app that is using "native" CoreData (iOS 5.1). I was about to set out to create a wrapper around CoreData to simplify my coding when I stumbled upon the MagicalRecord wrapper for CoreData (https://github.com/magicalpanda/MagicalRecord) and really liked the approach that was taken.

I converted my test app to use MagicalRecord. This was very easy to do and worked very well. The only issue I am having is in how MagicalRecord uses a background saving queue to keep db activity off of the main thread.

The app is a very basic single-threaded parent child relationship using a navigation controller and some table view controllers. When I create a new parent, and then add a child record, the child record is not showing up in the child table view. This appears to be due to how MagicalRecord handles temporary ObjectIds such that the fetch is unable to find the new children since the parent's object id is not yet a permanent object id. I may not have this exactly right, but I believe that is the general issue.

I have read a number of posts, mostly on stack overflow and a number of people mention the same issue, but I am not sure of the solutions posted. Most seem to point to an actual issue within CoreData and how nested contexts do not always notify the parent context of changes (or something like that). The solutions people post seem to deal with multi-threaded scenarios while my test app is a much more basic single-threaded app. If I shut down the app and restart it, the objects then all have permanent ids and they all appear in the table views as expected. I believe I could use the MagicalRecord "reset" method to "fix" my issue, but that doesn't feel right to me.

I am tempted to revert back to using "native" CoreData without the wrapper, but it really is a nice library and I feel I am just missing something here.

The library also looks like it will serve very well for when I create a more involved multi-threaded app. It has some really nice background thread support.

Has anyone else used this library and had the same issue pop up?

Thanks for your time!

Michael



forum user
Aug 30, 2012, 03:19 AM
Could it be possible that you mix parent-child-contexts with parent-child-relationships?

How do you obtain the child entities in the child tableview? If by using a fetchedresultscontroller then you'll need to tell the FRC to reload. There is also a delegate that will handle changes to the FRC for tableviews. This part is independent of MagicalRecord.

gummycat
Aug 30, 2012, 08:16 PM
Could it be possible that you mix parent-child-contexts with parent-child-relationships?

How do you obtain the child entities in the child tableview? If by using a fetchedresultscontroller then you'll need to tell the FRC to reload. There is also a delegate that will handle changes to the FRC for tableviews. This part is independent of MagicalRecord.

Thank you for the reply. Yes, I understand exactly what you are talking about. I wasn't confusing parent child contexts with parent child relationships. I am very familiar with the difference (20+ years across many platforms and dbs... can't believe it's been that long... sigh). This app was working perfectly prior to migrating to MagicalRecord. It is not a parent child issue. Both table view controllers still work well - it's just an issue of when a new parent is added for the first time, the children that are then newly added to that new parent do not show up - but they are in fact stored in the persistent store. If the app is shut down, and then restarted, the children appear as expected because the child context is refreshed with the permanent object ids.

The best explanation I can give is this... by default, MagicalRecord manages two contexts. The default context and a saving context. When you create a new object, it is first created in the saving context with a temp id. When you save, the changes are propagated to the default context and then to the persistent store. The default context is updated with the new permanent object ids, but the saving context still has the temporary ids. So, the changes are not being merged back to the saving context properly. I may not have this exactly right, but that's the basic idea... the object ids are out of sync and therefor the frc is unable to resolve the children properly until the objects ids are in sync.

I actually believe it is a documented issue with nested contexts in CoreData from features introduced in iOS5. I think MagicalRecord just exposes the issue because of how it manages the two contexts by default.

If I end up sticking with MagicalRecord and figure a proper way around this issue, I will follow-up and post it to this thread.

Thanks!