How to add database layer in core data application - iphone

I am fairly new to core data technology and i searched a lot on how to add the database to a core data application.so can anybody guide me on how to integrate the database layer? i have seen the iphone tutorial on core data (i.e books example) but i am not able to understand how to .sqlite file has been included in that application

The SQLLite file is automatically generated at startup by core data, by the persistent store manager.
If you have a project generated to start with Core Data, look in the App Delegate at the persistentStoreCoordinator method - that's where it manages the file created and sets the path where it will exist. If there's an existing one it will make use of it, though you'd have to copy over a pre-loaded one into the writable path it sets up for the database.

Core Data is NOT a database, it is a persistent object store. You have no control over how the data is stored in the file. (So trying to get it to use your own designed database is a bad idea.) You only get to chose wether it uses XML, binary or sqlite as its backstore.
To see how your app gets the data from the file, look in the app delegate. (That is where most sample code put it.) You'll find some methods for the managed object context, and the persistent store coordinator. The latter will create the file if needed. Besides the save call during quit, or other relevant times, you don't have to do much with it. (You can do some stuff, but I can't recommend that when you're new to Core Data.)

Related

moving data to core data

i have a .sqlite file with all the data i want to be used with my iPhone app .
but i feel i should be using Core data for what i want done.
is it possible to some how move all the data that is held within my .sqlite file to core data's .sqlite file ?
i have created only 2 fields in my .sqlite file and 2 attributes in the core data file, but i don't think i can replace the coreData's sqlite file as core data added additional fields to it.
what is the best way to handle this .
thanks
Since you generated the database yourself, the best way to move the data into a Core Data store is to use Core Data itself to re-generate the data. You can do this either through a throw-away app or within your app itself.
The fact that Core Data on the iPhone uses SQLite as a backing store is an implementation detail. Trying to recreate the core data store yourself may to cause very obscure bugs, you'll be much safer by allowing Core Data to generate the database.
#ExtremeCoder's answer is an option, but even writing an app to read from SQLite and store into Core Data would be a better choice than what that blog suggests.
Check this out: http://ablogontech.wordpress.com/2009/07/13/using-a-pre-populated-sqlite-database-with-core-data-on-iphone-os-3-0/

How to see core data tables and how to delete the data from a real device

Two questions about Core Data:
1. Is it possible to see the actual data(the db tables) that is stored when using core data?
2. When using the iPhone simulator i can delete the core data db by resetting the simulator. But how can i delete the core data db when using a real device?
Your Mac comes with a command line tool sqlite3. You can use it to do queries against the core data database. Not sure if that violates any rules against reverse engineering that might exist in any license agreements.
You can delete the db for convenience during development by deleting your app from the device and reinstalling it. If you don't want to do it by deleting the app, you will have to write some code in your app to delete it I think.
You can directly view an sqlite store using any sqlite tool including the command line sqlite3 tool. However, (1) Core Data uses a custom undocumented schema so looking at the store doesn't tell you much and (2) the structure of the sqlite store file itself has little relationship to how the managed objects behave in memory. Core Data isn't an sql wrapper. It just takes the managed objects apart to store them in SQL. SQL is just an option and Core Data works fine without it.
To "delete the core data db" you simply delete the persistent store file. Look where you initialize the persistentStoreCoordinator (in the Xcode templates, it's in the app delegate.) The URL for the persistent store/s will be there. Just close down the Core Data stack and then delete the store file with NSFileManager. Then restart the Core Data stack.

Creating .sqlite file from Core Data store?

I've seen tutorials in books and on websites that offer .sqlite files for download. The sqlite files are used for Core Data.
How do I get a .sqlite file FROM an app or core data store on TO my desktop?
If you are going to create a pre-populated sqlite file to be used with Core Data then you must create it with Core Data. It is trivial to create a basic desktop application for data entry and use that to create the file and then embed it in your iOS device.
Do not attempt to duplicate the data structure or linkage within the file by hand. You might get it to work but you will spend way more time trying to get it to work and it is going to eventually fail. The internal structure of a Core Data sqlite file should be considered like a private API. The structure is not public and can change without notice.
If you are specifically trying to create a Core Data store, you use this method:
NSPersistentStoreCoordinator
addPersistentStoreWithType:(NSString*)storeType
configuration:(NSString*)configuration
URL:(NSString*)storeURL
options:(NSDictionary*)options
error:(NSError**)error
You must have already associated a NSManagedObjectModel with your persistent store coordinator object. If the store at storeURL does not exist, it will be created; otherwise it will be opened.
These might help: http://www.sqlite.org/cvstrac/wiki?p=ManagementTools
I like to use this Firefox plugin:
https://addons.mozilla.org/en-US/firefox/addon/5817/
You can create a new .sqlite file, change existing databases, and browse through your data.
There's a command line program download-able from sqlite.org (in the standard download) that can be used to create a blank database with a schema. Usually the database file is compatible across operating systems and devices.

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.

How do I initialize a store with default data in a CoreData application?

I'm doing an iPhone application. In this app, I just want to have a database to be used as a looked up table for values in my app. The only thing the database will do was to supply me the values I needed depending on the query of the program. It won't do any addition or deletion in the database. My question was how do I initialize a default data on the application using CoreData. So that when the program starts It already had all the values needed.
If you have other suggestions of what is better do or what are other alternatives, please tell me.
Thanks.
I would create a simple Mac application, starting from the template for a Core Data document-based application. Copy your existing .xcdatamodel over the default one in the project (or add the new data model and be sure to rename anywhere that refers to the default model). Open up the XIB file for the document window in Interface Builder and drag the Core Data Entity item into it from the Interface Builder library inspector. From the resulting dialog, choose an entity to display and select an interface to display it in.
What this will do is create a fully functional interface for adding, removing, or editing the properties of that entity type. Everything should be hooked up via Cocoa Bindings so that you don't need to write a line of code for this to work. You can add interfaces for each entity type in your model this way.
This will let you quickly enter and edit data within a Core Data document, which you can then save out to disk and add as a resource to your iPhone application. The SQLite database structures are fully compatible between the desktop and iPhone Core Data implementations, so I've found that this is a quick and easy way of testing your iPhone Core Data code.
Please refer to the Core Data Programming Guide, or see below (copy from the PG):
"
How do I initialize a store with default data?
There are two issues here: creating the data, and ensuring the data is imported only once.
There are several ways to create the data.
You can create a separate persistent store that contains the default
data and include the store as an application resource. When you want
to use it, you must either copy the whole store to a suitable
location, or copy the objects from the defaults store to an existing
store. For small datasets, you can create the managed objects
directly in code.
You can create a property list—or some other file-based
representation—of the data, and store it as an application resource.
When you want to use it, you must open the file and parse the
representation to create managed objects.
You should not use this technique on iOS, and only if absolutely necessary on Mac OS X. Parsing a file to create a store incurs unnecessary overhead. It is much better to create a Core Data store yourself offline and use it directly in your application.
There are also several ways to ensure that the defaults are imported only once:
If you are using iOS or creating a non-document-based application for
Mac OS X, you can add a check on application launch to determine
whether a file exists at the location you specify for the
application’s store. If it doesn't, you need to import the data. For
an iOS-based example, see CoreDataBooks .
If you are creating a document-based application using NSPersistentDocument, you initialize
the defaults in initWithType:error:.
If there is a possibility that the store (hence file) might be
created but the data not imported, then you can add a metadata flag
to the store. You can check the metadata (using
metadataForPersistentStoreWithURL:error:) more efficiently than
executing a fetch (and it does not require you to hard code any
default data values).
"
As mentioned above, generally we need to create a pre-populated default store with code, then use it as a
resource file, and copy it from resource bundle to document directory if the coredata file is missing. Please search the CoreDataBooks code example in your Xcode Organizer (or Apple Developer Center), and look at the - (NSPersistentStoreCoordinator *)persistentStoreCoordinator method.
I racked my brain for hours attempting to solve this. What I came up with was simply not to save the database. That way, it will be initialized each time the app is opened. If you save it, it will continue to duplicate.
I would write a tool that populates a database with the data you want in it, generate the db at build time and stuff it in your resources folder. If you are not going to write to it you can just leave it there and access it directly, if you ever did want to write to it you would need to copy it somewhere you are allowed to write (like the documents folder).