Core Data: move object from one persistent store to another - ios5

I'm using Core Data in my app and would like to export only some of the data and import it on some other device.
To avoid migration issues, I'd like to do the following:
Export:
create a second export.sqlite-file with the same database model, but empty
add that file with addPersistentStoreWithType
copy some ManagedObjects over to that .sqlite
remove the added persistent store
Import:
- copy export.sqlite-file into app
- add that .sqlite-file with addPersistentStoreWithType
- copy data over
- remove added persistentStore
but how to achieve that? i.e. how can I tell my managed object so copy itself into the other store?

how can I tell my managed object so copy itself into the other store?
You can't, not directly anyway. You'll have to do something like:
For each object in the origin data store,
Create a new object in the target store with the same entity type
Assign the new object's attributes to the same values as the original object
Once you're done creating new objects, do a second pass to set up any relationships.
The relationships need to be done separately, because all of the objects in a relationship need to exist before you can create the relationship.

Related

Can I create an entity by default with core data?

I'm creating a project in Xcode 7.3.1 that uses core data to store a "UserProfile" entity with three attributes. I have set up default values for these attributes but is there any way that I can set it so that a UserProfile entity is created the first time the app is run by default? I will only ever need one of these entities but I will need to access and modify the attributes as the app is used.
Two things about this:
No, there is no way to have an instance of a Core Data entity created by default. Your code must create it.
If you will only ever have one instance, Core Data is a completely inappropriate tool. It makes no sense at all. Store the data in user defaults, or if you prefer, in a separate property list file.

Core Data: Rename Attribute without having issues with users and their current data

I just want to rename and add attribute on my table for a new version of my app and I want to keep the data if the app was already installed.
Firstly I just set the options:
let options = [NSMigratePersistentStoresAutomaticallyOption:true, NSInferMappingModelAutomaticallyOption:true]
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options)
And I created a new version model, so if I rename the attributes and add another attributes to my table on the new model, do the app gonna keep the data ?
Per Apple's Core Data Versioning and Migration Guide's section on Lightweight Migrations:
If you rename an entity or property, you can set the renaming identifier in the destination model to the name of the corresponding property or entity in the source model. You set the renaming identifier in the managed object model using the Xcode Data Modeling tool’s property inspector (for either an entity or a property). For example, you can:
... Rename a Car’s color attribute to paintColor
Your code requests automatic lightweight migration. If you want to rename an attribute, migrating like that will not retain data for that attribute. All other data will be retained. Core Data would see it as deleting the old attribute and adding a new unrelated attribute.
If you want to rename an attribute and retain data for that attribute, you can't use automatic lightweight migration. You would need to create a mapping model to tell Core Data how to migrate the data-- specifically, to tell it that the data from the old attribute name should move to using the new attribute name. Once you have more than one version of the mode, you can create a mapping model in Xcode to set this up. The overall process is described in Apple's guide to model migration.

programmatically create new table with ios-core data

Can Core Data allow me to create new table programmatically? or if I need that I need to use SQLite directly.
thanks
From a CoreData perspective, you don't really create new tables because database tables are only one possible type of persistence store associated with the core data model.
You can, however, create new core data entities programatically using the NSEntityDescription class. In the NSEntityDescription class documentation you will find this:
Entity descriptions are editable until they are used by an object graph manager. This
allows you to create or modify them dynamically. However, once a description is used
(when the managed object model to which it belongs is associated with a persistent store
coordinator), it must not (indeed cannot) be changed. This is enforced at runtime: any
attempt to mutate a model or any of its sub-objects after the model is associated with a
persistent store coordinator causes an exception to be thrown. If you need to modify a
model that is in use, create a copy, modify the copy, and then discard the objects with
the old model.
I've never tried to modify one at runtime, so I'm not sure exactly how well this works when you have an existing SQLite persistence store, if at all. But it's probably worth playing around with NSEntityDescription to see if it gets you close to what you are trying to do.
You typically create the managed object model graphically using Xcode's Data Model Design tool. (If you wish you can construct the model programmatically at runtime
Core Data programming Guide
You can however:
Create a Object Model Context (outside of the current one you are in/using)
Create one or more Entities
Create a SEPARATE persistent store for that model
Save entities etc...
Close the store when you're done
You can't change models on the fly as they are pretty much fixed when they're pulled into the runtime environment.

Core-Data: Want to persist new web xml stuff to my data store rather than replace existing

I have an application that loads core data, then calls the XML Web Service to get updated data. I basically want my app, rather than to erase all the data and load everything (including new) to persist, I want it to add only the new stuff onto the existing stack (without duplication).
What's the general consensus strategy for something like this?
I fetch an NSSet* of all persisted objects and then perform an intersection operation on that set of NSManagedObject instances with a new managed object, which is populated with the data from an individual XML element and its contents.
If there is something left from that intersection, that means I have that element already in my data store. So I update the existing, already-persisted managed object's properties with data from the XML element and save, discarding the new managed object.
If I have an empty set, the newly created managed object gets saved into the data store directly.
I don't have a hash value available to compare between the persisted data and the XML data, so this works reasonably well.
If each item in your xml data set has a unique key, you can just use that key to find the existing record and update it with the new info
Like Corey says, find a unique key to use in your data. Search the original data for that key and if it's not found, the object is a new one and can be inserted. If the object is already in the original data, discard it.
If there's a chance that the data will be updated over time (objects getting updated on the web side) then you'll have to compare the old (iphone) object and the new object with the same key. If they're the exact same, discard the new one. If not, replace the old one.
If there's no unique key you can use, you're going to have to do this comparison on all objects. I'm not sure of the quickest way to compare two managed objects, but you could try creating a managed object with the new (web) data and comparing it with each of the objects in the original.

How to hookup or create Sqlite DB with Core data model in iPhone

I am able to create the DataModel, Entities and Properties. How do I now create the DB? Do I have to create it manually making sure that all the properties and entities are mapped?
I am following the Recipes Core Data sample and have noticed a method in RecipesAppDelegate.m:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
}
I can see a reference to the DB file here.
When you create the persistent store coordinator, if you are using the SQLite persistent store type, the coordinator will automatically create the database for you if it does not already exist. You don't have to create the store file yourself.
EDIT: to clarify, the only thing you should be modifying is the Core Data object model (.xcdatamodel) file. An NSPersistentStoreCoordinator object, when it is created with a store file or the addPersistentStore: method is called on it, will do all the necessary setup of the backing store. This includes creating the file, any tables it may contain, etc.
Creating or modifying any type of persistent store yourself (especially SQLite stores) is completely unsupported by the SDK and the Core Data framework.