Core data + iCloud: exclude certain attributes from sync? - iphone

I am trying to implement core data sync using iCloud. However, there is one attribute that I don't want to sync. Is there a proper way to tell iCloud to sync most managed objects and attributes, but not others?

Right now, Core Data + iCloud does not support this kind of configuration. You may have to split your Data into two Persistent Stores (lokal, cloud).

One workaround would be to add the things you do not wish to sync to an entity that includes a unique device identifier.
In this way, they still get synced, but you can use just the data pertinent to the specific device and ignore the data from other devices.

Related

iOS Core Data: Confused about Core Data and database

I am really confused on what the Core Data actually is. Or I guess my question is, when dealing with a database, would you use Core Data? Like if I wanted access values from a database would I be using Core Data to access those values? How would I approach this problem?
Thank you so much for the help.
Core Data is an framework that does the work of "object persistence". In other words, it's code you can use that takes care of saving a collection of objects to disk and loading them again later. It does a lot of work to allow you to store lots of data and load only the objects you need at a time, and unload ones when memory is tight.
Core Data can use a database to accomplish this, but that's it's business, not yours. When you use Core Data, it is a black box. You tell it to save the data and then step out of the way.
If you want to interact with an existing database, such as a MySQL database on a web server, that's a completely different matter. You might use Core Data to store local copies of objects on your device, but in that case Core Data won't care that the objects are copies from some other database. It doesn't care.
It is a convenient, native means of storing data in your iOS applications. Don't think of it as sqlite although you can view the files it creates with various sqlite tools. Instead think of it as a tool for manipulating an object graph of information important to your app.
I've used it in two main ways. First to store a bunch of static data that is important to an app, in one case that was a large amount of location data for an indoor mapping application. What arrived as a massive CSV file of waypoints was converted to core data. Core Data was incredibly useful for this because it allowed preparing a sqlite file which was shipped with the application containing all the infomation. Updates from a web service arrive as more CSV that is added to the Core Data to keep information current. At runtime the location information object (the waypoint a user is at) is retrieved with a predicate (i.e. the point they tapped on) and that object, through its Core Data relationships, indicates where it is possible to go from that point. Core Data provided the information necessary to perform A* routing through the indoor map.
Second it is great when you have a bunch of objects arriving as JSON and you want to be able to store and access those objects later. Let's say you have a typical app where you have a User and some information about the User, let's call it Thing. Users have Things. When you want to know something about a User you retrieve the Core Data record using a predicate - typically "name" or similar - and you get all the information you stored about the User back. Again you can make use of relationships to explore the user's connections and make displaying information easy. Perhaps the User has many Things, then you can say "user.things" and you get a NSSet of NSManagedObjects representing those Things.
You use it like a database. Its utility is that it is easy to access from anywhere in your iOS code, it is easy to store and easy to retrieve information also. Faulting lets you retrieve one object and navigate to any object connected through relationships by following the relationships. Because you define the attributes and relationships yourself in the data model editor it is easily customized for what you need to store. To me it is one of the most used and most useful parts of iOS.
When you want to automate display of information from Core Data you can use a NSFetchedResultsController to initiate a fetch and to respond through delegate methods to changes to the underlying data. If you set up a UITableView to use a NSFetchedResultsController as data source, you can have the table automatically update whenever the objects displayed in the cells changed. Very useful for apps where you periodically update information and want what is displayed to be kept current.
When your object model changes it is possible to maintain all of your existing information and migrate it to the new model. Core Data manages automatic (lightweight migration) when it can, or if you have made more radical changes you can supply rules to handle the migration.
The limitation of Core Data is that it is not great for storing binaries. If you have images that you need to store, far better to store a path to the location of the image than trying to store the actual data.
Yes, if you want a local database on your device, Core Data is the appropriate technology. It probably makes sense to start your research with the Core Data Programming Guide.
You can alternatively use SQLite (which Core Data uses in the backend), but Core Data offers some material advantages and is the preferred database interface for iOS. If you decide to pursue SQLite for any reason, though, I'd suggest you contemplate using the FMDB Objective-C SQLite wrapper.
But Core Data is generally the way to go.

sync app captured images with icloud

I am just learning core data and already I have the following task.
I have an app which syncs core data with iCloud.
Now I should provide feature according which user should be able to link images
from camera roll with some entity. And as a result, that images also should be synced
with iCloud.
I know that I can create "image" entities, "connect" my existing entities with that and sync.
But I know that images storing to core data is not preferable.
Therefore, I think the another option is to store images to some directory and sync that it.
I'd like to know is the second option is possible to implement and integrate with already existing code.
Also if it is possible please provide some examples.
Thanks.

Preserving core data after app update

I am using core data to store favorites chosen by the user. I would like to know that if I send an app update, how can I keep the data of the favorites preserved after the app is updated by the user?
I have read that you could use versioning, but I'm not sure if this the correct method.
Any help will be appreciated! Thanks
If your app maintains the same bundle identifier and you don't copy over the core data store file, you keep it.
If you changed your Core Data model, then you do need to worry about versioning. Depending on changes you may need to write rules for migrating data in the old store to the new format. As you have probably experienced, if you change data structure and do not migrate (or wipe existing data), you crash.

Relationships between static application data and updatable user data with Core Data

I am developing an iPhone application that has a large database of items which the user can mark as favorite or add to certain lists.
Currently, the SQLite file is first copied from the bundle to the document directory to make it writable and used as a Core Data persistent store. However, I will run into problems when I need to deploy an application update down the track to add extra data or fix minor errors, where the user data will be lost or the application data needs to be synchronised.
After some research I found that perhaps I could add the application data as a read-only persistent store in the bundle and add a second writable persistent store to the documents directory for user data - Core Data would combine the data for me. But then I came across this in the documentation:
When you add stores, you specify the different store attributes by
configuration. When you are creating your configurations, though, remember
that you cannot create cross-store relationships.
I presume that means that I will not be able to maintain relationships between items and lists or items and a 'favorite' record. I guess I could go to the extra effort of traversing the relationship manually. Has anyone had experience with this?
Core Data provides an architecture to support versioning of managed object models and migration of data from one version to another. If your changes to the model are pretty simple, you can use "lightweight migrations", which are pretty easy.
Read more in Apple's documentation here: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreDataVersioning/Introduction/Introduction.html

How to have multiple apps - one Core Data?

I’m an experienced developer, but new to Mac. I just don’t want to go down one path only to find out that I made some fundamental error or incorrect assumption later on.
I want to ultimately build and sell an iPhone app using Core Data. The app will be free with content available through in-app purchase. Here is what I want to be able to do:
OPTION 1
Build a Mac OS X utility app that points to the same Core Data object model, but has its own “master” database.
Populate the master database using the Mac app.
Export a subset of the master data from the Mac app to a flat file (XML?) that is a subset of the master data.
When the user purchases that data, download from the cloud and import that data into the local iPhone data store.
Number 2 should be easy enough. I have read about the XML Parser that should help me with #4. I need help with #1 and 3.
For #1, I can’t figure out how I can maintain one object model for both apps with Xcode. That data model must accept model versioning. Do I just create two Projects, one Mac and one iPhone, and point them both to the same .xcdatamodel file and the magic happens for me?
For #3, is there any sample code that someone can share that will iterate through an array of objects to create the XML?
OPTION 2
Another option I am considering was discussed below. Instead of worrying about import/export, simply create individual sql files for each set of new or updated data.
I could maintain a separate "metadata" database that has information about the individual sql files that are available to the app.
Then, I can dynamically access the individual SQL files from the local documents directory. This is similar to an iBooks model where the sql files equate to individual books.
I'm thinking I could have only two active database connections at a time... one for the metadata and the other for the specific "book". I am not sure if this will scale to many (tens or hundreds) sql files, however.
Any help is appreciated!
Jon
UPDATE: I just saw the answer from Marcus Zarra at:
Removing and adding persistent stores to a core data application
It sounds like Option 2 is a bad idea.
For (1), you can use the same object model in both apps. Indeed, if you use the same Core Data generated store, you are required to do so. Simply, include the same model file in both apps. In Xcode, the easiest way to do this is to put the model file external to the project folders of each project and then add the model file without copying it to the project folder. This will ensure that both apps use the same model file for every build.
For (3), you need to first create an "export" persistent store using the same model as the reference store and add it to the reference context. In the model, create an "Export" configuration. Create a subentity for every entity in the model but do not change any attributes or relationships. Assign those entities to the Export configuration.
You will need to add a "Clone" method to each ManagedObject subclass for the reference entities. When triggered, the method will return a subentity populated with the reference objects attributes and relationships (the relationship objects will be cloned as well.)
Be aware that cloning an object graph is recursive and can use a lot of memory.
When you save, because you assigned them to the "Export" configuration, all the cloned export entities and their relationships will be saved to the export store. You will have cloned not only the objects but the related object graph.
Include the model and the export store in the iPhone app. Write the app to make use of the export entities only. It will never notice the absence of any reference objects.
For (4), I wouldn't mess around with using XML or exporting the data outside of core data at all. I would just use the export Core Data SQL store created in (3) and be done with it.
You can give a NSManagedObjectContext instance and instance of NSPersistentStoreCoordinator. This class has options allowing you to specify a file location for sotring data and a format (SQLite, Binary, or XML)
How do you plan to actually transfer data from Mac to iPhone? Is this something you do during development, or something people do during daily use? If the latter, you are probably better off building decoupled export/import into your app right away. So the Mac would serialize data into XML or JSON, push it somewhere in the cloud (not sure if local network/bonjour transfer is easier or useful, cloud is more universal), and iPhone fetches the data and deserializes it into the local schema/repository. You should not plan to work on the SQL layer with Core Data. Different platforms may use a different storage backend.