Is there a good application for managing a SQLite 3 database with BLOB data type? - iphone

I want to create and manage a database with images and or audio clips. I know it's not the best idea and I know there are better options, but it's the easiest way to have the data separate from the programming and I'm not the one writing the code. So I need an application that will allow me to edit the database that the application is calling, and the application needs to call random audio or image file. I JUST NEED TO KNOW OF AN SQL EDITOR.

Super bad idea to put large files in a database, it will kill performance and could well blow away the memory limits an application has. You also cannot stream them out of the database the way you can from the file system.
Instead, consider this approach - as Alex suggested, work with separate files and strings that represent file names. You could put both the database and the files into a single directory, that your coder keeps as a folder reference in XCode - so all content in the folder you change is added to the coding project automatically. Note that if you change any existing file, due to a bug in XCode he'll be required to do a Clean BUild before building again or it will not copy changed assets (mostly a problem for the DB).
Then you can easily use any SQLLite client to maintain the database of filenames and other data. "Base" is a nice standalone app.
I would highly recommend you use some source control system like Git so that you could check in changes and the programmer could get his project updated right away without the confusion of emailing files around.

You could use Core Data instead. It uses a SQLite backend, by default. Instead of using BLOBs, you can simply store an NSString* that is a path to the object in the application's Documents folder. When you want to retrieve a stored image or other large binary data object, you can load an NSData* instance from the path value directly. Keeping large files outside the database will give you much better performance.

Related

iOS - populating a core data database

I have used extensively core data in my applications. Generally I need to submit the applications using a pre-populated database.
I generally create zillions of lines of code to populate the database, then I extract it from the applications directory and include it on the bundle. Is there a easy way to do that? Is there any way to populate a core data database created on Xcode using, for example, a CSV file and an external app?
thanks.
The usual way is to create the entries at the first launch.
If you want to import data from a CSV file, then you need a parser.
I can recommend this one: https://github.com/davedelong/CHCSVParser
You don't have any easy way to do that with Xcode.
Basically what I do in this kind of case: I build a second target dedicate to pool the database and create object with a fixed persistent store url relative to the workspace in the filesystem.

How should I manage and reference many images files in an iPhone app?

I'm developing a reference iPhone app that will contain many photos (ball park estimate of 75-100 photos). All of the photos will be stored locally along with at least one or two other versions of these photos in different image sizes representing the same image.
As a newbie to iPhone (and C) development, I'm unsure as to the best way to store these images for reference in the application. Is it possible to create folders/packages/bundles for them to live in?
FWIW, the app is run from an XML file, although I am considering a SQLite database as it is becoming harder to maintain with XML.
The most obvious solution is to write the image files to your applications' documents folder. You come up with a name for each file (or obtain it from XML), and then you use methods for dealing with image classes to obtain jpgs/pngs and save the files. You maintain references to the filenames strings elsewhere, persisting those in a .plist or archiving them in a dictionary (again, storing that archive in your documents folder).
CoreData now allows you to store files externally (which is better than storing larger images directly in SQLite) but it will manage and track them for you. That'slightly more sophisticated, but since XCode bundles CoreData templates, you can put those together very quickly and easily.
Use The concept of Lazy Loading to download all images and save them in to root directory...All The best!!!

How to manage the data to fill a Core Data database with a lot of data (Edit: changed title)

I hope all of you have had a good Christmas :-)
In my app i have a database, using Core Data, that requires a lot of data, at least 1.500 records consisting of 6 fields. That means at least 9.000 lines of data. All data is pure text.
During the development phase i have 250 records to test on.
The way i do populate the DB at this point is that i have a text (.txt) file, which i edit in Word and then reads into my database. This is very inconvenient for many reasons such as if i save it, by mistake, in the wrong format it all screws up (i have Swedish characters that changes).
Given the amount of records i will need i would like to ask for advice how people do these things and what to use? Is there some sort of (free) database available that i could use etc.
Cheers
For editing use notepad, notepad++, or gedit. You won't have issues with MS Word specific characters.
I am not too familiar with Core Data, but I believe it uses SQlite on the backend.
I have implemented SQLite directly into a few developments that I have worked on. It might be worth your time to take a look.
Can you give more details about your app? Platform, how often data is accessed, how often it is modified, etc.
Hmm, one way to get started on this might be to fill the Core Data store a single time, and then, whenever you need to run your tests, just copy this store file out of your application bundle into your documents directory. I maintain a "Reset All" function in a game I've worked on using this method, and it works great for very quickly populating Core Data.
Hej,
currently I am developing an app with very similar requirements - a prepopulated Core Data database with 1200+ entries with more or less the same amount of fields.
The data I receive is in xml format. I've written a small mac app which features the same core data model as the iphone app does - it will read the xml and create core data entries accordingly. I then take the database file my mac app created and add it to my iphone apps bundle, from where it will be copied to the documents folder on the first launch (or whenever a reset to the factory data is required).
This is working perfectly, I think you could do something very similar. The only difference would be that, instead of parsing xml, you'd need to write something that reads your textfile. Fear not, it's easy to do!
I've taken the approach to add a unit test that determines if the database exists. If the database doesn't exist, the test creates it from a text file (usually a plist or csv).
This approach enables me to: alter the underlying data via text, "clean" the database by simply deleting it, and run tests against the data. Since you're using CoreData, there might be some additional benefits by ensuring your schema matches the dataset; I once found I'd accidentally set an attribute to not allow nil.

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).