CoreData iCloud changes not saved - ios

I m making an app with CoreData and iCloud integration. I went through the Apple Documentation to adapt my already working app to integrate iCloud synchronization.
Inserting objects and deleting seems to be working fine. When I delete the app and reinstall it on my phone all synchronized data are correctly restored.
My issue is when I modify an NSManagedObject. The context which I used to query CoreData to fetch my object does not detect any changes on my objects when I modify a field. Therefore the context is not saved. If I try to force saving context even when no changes are detected, nothing is saved.
I went through stack oververflow and found that the context must have a stalenessInterval set to 0.0. This did nothing to my app. Do you have any idea on what could be wrong ?
I noticed that the context carried by the NSManagedObject seems different than the one I used to fetch data. If I call save method on this context, nothing happened either.
I am completely lost, since I thought it would ba as easy as inserting and deleting objects.
Thanks for your help !
(ps: I code with Swift but even Objective C code is acceptable as answer :) )

I was actually trying to use two databases whereas I should have used configurations to separate entities saved to the cloud and those saved locally.
For those who wants more information on CoreData with iCloud i suggest to go through this video from Apple WWDC 2012 which helps a lot getting into this subject.

Related

Is core data migration necessary?

I am making an app that will store scores (kind of like a quiz app) - I will be playing around with core data and storing values to work out the best way to use core data. I know that if you start storing and fetching from core data and you then add/delete entities without migration, problems occur.
But, as I am only testing, I do not mind deleting the app of my device, and then reinstalling (which will cause me to lose data) - will this help me avoid the need of migrating (because when I download, it is seeing the new core data for the first time)
Thanks!
As you said "I do not mind deleting the app of my device, and then reinstalling (which will cause me to lose data)" so you dont need migration at all. Migration is needed when you have a already published app on appstore and you dont want to create a mess for people who have already installed your app.

Simperium iOS CoreData Relationships Randomly Null

I am currently having an issue with Simperium on iOS with CoreData. Upon launching the app for the first time, Simperium tries to sync with CoreData.
Sometimes it will work 100% correctly, and other times it will set some of the relationships to "nil" despite the Simperium data on the server NOT saying that. This is then NEVER fixed unless I re-install the entire application. And then I roll the dice again to see if the relationships are linked properly on startup.
I cannot find a pattern in this. The relationships that are nil are completely random. Sometimes this entity over here will have nil relationships, and then the next time I try it a different entity will have nil relationships.
All relationships are optional and there is nothing wrong with my CoreData file.
Has anybody had an issue like this? I found the exact same issue in a bug from 2014, but it's been forever since then.
Exact same issue I am having can be found here: https://github.com/Simperium/simperium-ios/issues/250
Side Note: If you read that issue, he also clarifies that he has a problem with editing the CD file WHILE Simperium is syncing, causing nil relationships. Has anybody confirmed this happening? If so this might be my problem.
It's highly likely that this glitch is caused by the scenario you've described (editing the CD file while Simperium is Sync'ing).
Core Data deals, internally, with locks to maintain data integrity. Accessing the sql storage directly might result in data corruption (i'm assuming you're editing the file via either a Firefox plugin, in the simulator, or accessing the file via a Filesystem API).
Please, try to reproduce the issue without accessing the Core Data's sqlite file directly (always go thru NSPersistentStoreCoordinator / NSManagedObjectContext).
If you do succeed, and there's effectively a bug, we'd love to get it fixed! (In which case, please, open an issue the main repository, including as many details as possible).
Thanks for your interest in Simperium!

How to create a second persistent store in Core Data for sync with CloudKit using Swift?

I am writing a simple app using Core Data, and I want to sync data through CloudKit. The way I thought is: add the "NSManagedObjectContextDidSave" observer for Core Data, when the context saved, it also launch the sync function for CloudKit. If upload succeed, there is no more work, if upload failed, I want to save the changed objects into a second persistent store for later sync again.
So, my question is how can I save those changed objects into a second store in Core Data? Is this way possible to implement the sync function?
I did some search the about the related questions, but few can meet my requirement.
I am a freshman for iOS, my first thought is parent/child context, after search and study, I found this is not the right way, what I need is two separate databases, when I save the uploaded failed objects into syncDB( another just named it localDB, the default one), it should have no effect on localDB, when next time sync succeed, the uploaded objects will be delete from the syncDB, so the best state is syncDB keeps empty, which means all changed objects have been synced to the CloudKit.
Another issue I learn from search is we can't save relationship between different stores, but I do need this, for example, I have Car Entity, and it has a relation "category" to Category Entity, the inverse is "cars". Does this relationship can also save into the second store?
In summary, my situation is I need two stores which using the same Entities, one is "LocalDB" for normal use, another is "SyncDB" for CloudKit sync. I just begin learning iOS and swift, maybe my question is not good for stackoverflow, but this really puzzled me, I got stuck here for many days. Any help is appreciate, and any other sync solution is also welcome, thank you!

From UIManagedDocument to traditional Core Data stack

I created a new App using UIManagedDocument. While on my devices everything is fine, I got a lot of bad ratings, because there are problems on other devices :(
After a lot of reading and testing, I decided to go back to the traditional Core Data stack.
But what is the best way to do this with an app, that is already in the app store?
How can I build this update? What should I take care of?
Thanks,
Stefan
I think you may be better off to determine your issues with UIManagedDocument and resolve them.
However, if you want to go to plain MOC, you only have a few things to worry about. The biggest is that the UIMD stores things in a file package, and depending on your options you may have to worry about change logs.
In the end, if you want a single sqlite file, and you want to reduce the possibility of confusion, you have a class that simply opens your UIManagedDocument, and fetches each object, then replicates it in the single sqlite file for your new MOC.
Now, you should not need a different object model, so you should not have any migration issues.
Then, just delete the file package that holds the UIManagedDocument, and only use your single file sqlite store.
Basically, on startup, you try to open the UIManagedDocument. If it opens, load every object and copy it into the new database. Then delete it.
From then, you should be good to go.
Note, however, that you may now experience some UI delays because all the database IO is happening on the main UI thread. To work around this, you may need to use a separate MOC, and coordinate changes via the normal COreData notification mechanisms. There are tons of documents, examples, and tutorials on that.
EDIT
Thanks for your answer. My problem with these issues is, that I'm not
able to reproduce them. All my Devices are working fine. But I got a
lot mails, about problems like this: - duplicate entries - no data
after stoping and restarting the app - some say, that the app works
fine for some days and stops working(no new data). These are all
strange things, that don't happen on my devices. So for me the best
way is to go back to plain MOC. My DB doesn't hold many user generated
data, all the data is loaded from a webservice, so it's no problem to
delete the data and start of using a new DB. – Urkman
Duplicate entries. That one sounds like the bug related to temporary/permanent IDs. There are lots of posts about that. Here is one: Core Data could not fullfil fault for object after obtainPermanantIDs
Not saving. Sounds like you are not using the right API for UIManagedDocument. You need to make sure to not save the MOC directly, and either use an undo manager or call updateChangeCount: to notify UIManagedDocument that it has dirty data that you want to be saved. Again, lots of posts about that as well. Search for updateChangeCount.
However, you know your app best, and it may just be better and easier to use plain Core Data.
Remember, if you are doing lots of imports from the web, to use a separate MOC, and have your main MOC watch for DidSave notifications to update itself with the newly imported data.
UIManagedDocument is a special kind of document, an UIDocument subclass, that stores its data using Core Data Framework. So it combines the power of document architecture and core data capabilities.
You can read more about document based architecture from Document Based App Programming Guide for iOS and I recommend WWDC2011 Storing Documents in iCloud using iOS5 session video. I also recommend Stanford CS193P: iPad and iPhone App Development (Fall 2011) Lecture 13.
What is created when you call saveToURL:forSaveOperation:completionHandler: is an implementation detail of UIManagedDocument and UIDocument and you should not really worry or depend on it. However in current implementation a folder containing an sqlite database file is being created.
No. All entities will be contained in a single database file also more generally called: a persistent store. It is possible to use more than one persistent store, but those are more advanced use cases and UIManagedDocument currently uses one.
UIManagedDocument's context refers to a NSManagedObjectContext from underlying Core Data Framework. UIManagedDocument actually operates two of those in parallel to spin off IO operations to a background thread. When it comes to the nature of a context itself here's a quote from Core Data Programming Guide:
You can think of a managed object context as an intelligent scratch pad. When you fetch objects from a persistent store, you bring temporary copies onto the scratch pad where they form an object graph (or a collection of object graphs). You can then modify those objects however you like. Unless you actually save those changes, however, the persistent store remains unaltered.
But it really is a good idea to take a look at the lectures and other material I posted above to get a general picture of the technologies used and their potential value to you as a developer in different situations.

Dealing with Managed Objects between two MVC's with one database

Current Setup:
MVC-1, onViewDidLoad, creates a Managed Object, fetches data from the Managed Object and updates various UI elements.
MVC-2: Same exact setup. I copied and pasted the same code from MVC-1 into MVC-2.
Issues I am seeing:
After launch and opening MVC-1, all the code is executed without any errors. The ManagedObject is created, the fetch requests on the ManageObjectContext work and the UI is properly updated. However, when switching to MVC-2 it seems that none of the data, that MVC-2 is suppose to fetch, is actually being updated. All the UI Elements in MVC-2 have the same data from the last time the application was launched.
Furthermore, if I launch the application and open MVC-2 first I get the same results, only MVC-1 does not appear to be updated this time around.
What is it that I am over looking? I have explicit saves to the database being made. I am (at least I think I am) creating two different ManagedObjects. Do I need to somehow close one before creating the other? Any advice would be very helpful. Thanks.
Figured it out.
I was saving the MOC, however I was not writing the NSManagedDocument to disk (I am using a ManagedDocument as a container for the Core Data database).
So naturally, when I switched to the MVC-2 I would not have the updated data.
I now save the MOC, write the MD to disk and close the MD at viewWillDisappear.
Thanks for the help gusy.

Resources