Best way to have a lookup table in an iphone app without loading it to memory - iphone

I have an iphone app with a large(6-7MB) keyvalue file that I would like to avoid loading into memory. It is used very rarely, and chewing up that amount of RAM seems unnecessary.
Right now it is a flat text file with lines in the format
KEY VALUE
but I am happy to store it however works best.
What is the best approach for this? SQLite is an option, but that seems quite a heavyweight solution. I'm told that coredata is a good interface to SQLite, but it seems to me that this would still involve loading the entire file to memory as an nsdictaionary

First, SQLite is not a "heavyweight" solution. Its memory requirements are quite low, and its performance is good. If you use SQLite, you'll probably want a wrapper like FMDB or PLDatabase to make it easier to use in Objective-C.
Next, Core Data is not a wrapper for SQLite. It uses SQLite internally, but that's an implementation detail that is not exposed in the Core Data API. Core Data would work in this situation, but if you think of it in SQL-style terms then I guarantee that you'll screw it up.
If you're only using the table rarely, the simplest approach would be to save it as JSON or as a property list and just read the whole thing on demand. As long as you're careful to unload it when you're done and you're not already pushing memory limits, I wouldn't worry about it. If you might get to where you need it more often, consider either SQLite or Core Data-- either will allow you to look up the values you need without loading the whole thing into memory.

How would you search for a key witout loading all keys into memory?
You could implement your own indexing scheme, or just use SQLite (whose code is likely to be already in memory because of some other app or service).

Six or seven MB isn't big. Thus you could just load it into a dictionary and then when you are through ensure that it is deleted/unlinked. Alternately you could just write your own query and read the file lines yourself scanning for the key. But 6-7 MB isn't big.
If you have control of the file content, just use the existing Apple frameworks to write it as a plist and then to read in the plist as a dictionary and do your queries.

Related

object c (iphone development) / difference of sqlLite and file system

i'd like to make some application that store data in device.
so i want to use some storage. but there are two ways i can store my data.
first one is saving them to file system by XML structure, and the other one is by using sqlLite library. but i have no idea. because i don't know the strength and weakness each of them. for example location of stored data, and which one is faster to get the data i want. i just store text data. so please recommand which one is better.
sorry for my english skill. thank you!
SQLite !!! No doubt about that.
For easy maintenance, querying capability and lot more.
SQLite has the basic features of a database engine, it's lightweight. Specially designed for mobile platform. So some features like regex in database etc is not included.
File and Database. Always preference goes to database.
DATABASE ALWAYS...
As you said SQLite is one option, and you can use SQLite directly with iOS. But I hope you have heard about Core data, which is a higher level wrapper to make Database easier.
But there is no comparison between Database and files
This would be Perfect answer for your question and for iOS I would suggest SQLite will be the best one as it has everything in one file,
performance loss is lower than XML as cache gets bigger.
It depends on the amount of data (and its structure and complexity) that you are going to store. For rather small amounts, not more than a handfull of records or two, I would use an NSDictionary and the load and save methods that come with it. Those persistant storage will be in XML, btw.
For more data or rather complex data, especially when you do not need to load all the data at the same time, then you should go for a database solution. That chould be sqlite. Or you may opt for core data which (per default) is based on sqlite.
I would suggest core data (unless you aim for portability such as android). You will have to invest in learning core data. Which may appear to be confusing from start. But once you have started with that you will certainly find core data quite convenient. It takes a lot of work from you that you have to care for manually when using native sqlite.

multiple plist files in one app

I have an ios app that has alot of static content and static settings. right now, I save them in multiple plist files that I update when I release app updates. It's convenient for me to save the content & settings in plist files rather than having them as arrays or dictionaries in the source code.
It came out that I have a plist for each module in my app and a generic plist file for settings. around 8 plist files for the entire app. mostly small plist files.
They are really small plist files and I only change them when I release an update, so I don't see a reason why I should use core data or sqlite for it.
Does it reasonable to save all my content and settings in plist files and can it be a performance issue? Should I cache the plist data to make sure I phrase the files only once, or it's a relatively cheap call?
Reading and writing plist files (especially small ones) is highly optimized, and you probably won't take a performance hit doing so.
If you have any doubts, you can always run your app through Instruments to see if processing the plists takes too long.
Depending on how often you need to read the plists, it might be a good idea to cache their contents, but it depends on your specific usage. Caching them means using more memory all the time, as opposed to just when you need it at the expense of loading a plist.
If this pattern is working for you, then there's no need to change it. There's nothing wrong with storing your information in disparate plist files, particularly if there is no coupling between the data stored by one module and the data stored by another.
The main benefit of using Core Data/SQLite is that it is relational. It understands how your state is related to other bits of state, and provides API's for querying, sorting, browsing, and filtering it efficiently. If your data is non-relational, however, then there is little to be gained by stuffing it in a relational database.
As for performance, if you are re-processing your plist files every time the user goes to view some bit of state, then that can be very inefficient. Personally I'd recommended keeping an in-memory array or dictionary that represents your plist state, and writing the in-memory data back to the plist whenever a change is made. Then reading is always fast, because you just use the in-memory copy.

Shipping static data with an iPhone app

I'm making a game and I need to be able to ship some data about the game's various ships and details about them that the app will use. I'm looking for what the ideal way to do this would be. Now I've narrowed it down to using either SQLite, Core Data, or Property Lists. Now the thing I want to keep in mind as well is memory. Because it's a game I need to be careful about this and because of the fact Property Lists need to be loaded all into memory I'm afraid they might not be ideal. I know SQLite is supposed to have better performance than that and I've heard that Core Data performs even better than that. So my question is what do you think the best way to ship static data with an iPhone app is?
I would say it depends on the amount of data that you need to provide. If it is a lot of a data, I would definitely go for sqlite. If it is just a couple of ships, sqlite might be a little over the top.
For a such a small amount of data why dont you consider writing your own file format, or using something easy to parse such as csv, will be easy to edit in any spreadsheet program, and to cut down filesize / load times convert it into a binary format.
Assuming that not all ship-data is needed at the same time (and as such, having them all in one file would be a waste): Maybe you should use a separate data file for each ship or each class of ships?
Since this would solve the storage-efficiency at a different level, plists might be a viable option.

Core Data: Overkill for simple, static UITableView-based iPhone App?

I have a rather simple iPhone app consisting of numerous views containing a single, grouped table view. These views are held together in navigation controllers which are grouped in a tab bar. Simple stuff.
My table views do little more than list text (like "Dog", "Cat" and "Weasel") and this data is being served from a collection of plists. It's perhaps worth mentioning too that these tables are 'static' in the sense that their data is pre-determined and will only ever be amended—and if so, very rarely indeed—by the developer (in this case, moi).
This rudimentary approach has reached its limits though, and I think I'm going to need something a bit more relational. I have worked a tad with Core Data in the past, but only with apps whose data is determined by user input.
I have four closely related questions:
Is Core Data overkill for an app consisting mainly of a selection of simple table views?
Do you recommend using Core Data to manage data which is predetermine and extremely unlikely to ever change?
Can one lock Core Data down so that its data can't change, thereby relinquishing my responsibility as the developer to handle the editing and saving of the managed object context?
How do I go about giving Core Data my predetermined data, and in a format I know that it can work with?
Thanks a bunch guys.
The answer is simple. If you do not need to persistent to an out of date format (like MSWord, etc.) then you should be using Core Data. Raw SQLite is a headache that is not worth the effort 99.999% of the time.
Core Data is more efficient than plists and allows greater flexibility if the project ever evolves.
It is also very easy to pre-populate a Core Data sqlite file using a OS X machine; you know, the machine you are using to develop your application in the first place :)
NNW's use case is a singular exception to this rule that, if I were a betting man, I would bet has the Core Data team's attention and will be corrected in a future update. An update, by the way, that you will get for free if you use Core Data.
You might consider using the SQLite API directly, rather than Core Data, as it may be easier to pre-populate a database that way. You can create and modify a SQLite database on any platform (Mac, Windows, Linux), and just copy it to your application's bundle as a resource.
You can find tutorials/examples that will create a user's database by copying a SQLite database out of the application bundle. In your case, you can just use the one in the bundle. Just be sure to open it read-only.
I would recommend sticking with plists since your data will rarely change and when it does it will be developer-driven.
Core Data is very powerful, but there will be a moderate amount of plumbing and infrastructure you'll need to set up to make it work.
Core Data places its store outside of your app bundle (as it must to run on the iPhone), so all new installations will need to load data into the store on the first run. This data will probably have to be stored as resource plists anyway, so you aren't saving yourself the trouble of generating those plists. Turns out that wasn't true and you can store read-only parts of the persistent store in the App bundle.
Since I don't know exactly what kinds of limitations you're running in too, Core Data may be the solution, but I'm guessing it won't be. If object relationships are the biggest difficulty you're dealing with, you should read up on object archiving as a way to store your entire object tree in a form that can easily be saved as a resource in your bundle and recreated when necessary.
You should read why NetNewsWire switched
The two main takeaways from that post:
I bet Core Data is the right way to go 95% of the time. Or more. It’s easy to work with. It’s fast (in most cases).
And:
(Rule: always work at the highest level possible.)
I recommend using plain SQLite. It is simpler, easier to maintain and you can build the database on non-mac systems, using many popular GUI editors. For me, using Core data is still a pain. Code to populate your tableviews from a static SQlite database is simple, straightforward, and transparent, while Core Data needs more boilerplate code which you don't even understand completely at first and overall has a lot of hidden complexity which you don't really need.

Property list or sqlite for static data?

Is there any "Best Practice" approach to storing persistent static data for iPhone apps?
I have an app that reads a dictionary of approximately 1000 items many of which are arrays. I started out using a single plist for this and it has become somewhat unwieldy especially since much of the values are HTML strings.
Is there a better way for me to approach this? I plan on scaling this app significantly and I obviously don't want to change my approach midstream.
I've googled for iphone data storage and variants but have come up short for anything even touching on a best practice.
It sounds like you intend to distribute some data with your application. A property list is probably the easiest to maintain, but it will be loaded into memory all at once. This could eat up a lot of the device's memory.
An sqlite database, on the other hand, will load only the data you request. I'm not sure how your data is structured, but you could quite easily create key-value pairs with a single database table. (A single table with a key column and a value column) Then, if it were me, I'd write an Objective-C class to wrap the database queries so I can write easy statements like:
NSString *welcomeText = [[MyData sharedData] dataWithKey:#"WelcomeText"];
Getting the data into the database in the first place doesn't have to be difficult. You can use the command line sqlite3 utility to bulk load your data. There's a command called .import that will import your data from a text file.
Hope this gets you moving in the right direction!
I'd go with a sqlite solution. The apps I am working on now, which are just apps to help me learn iPhone development, mostly all use sqlite. I use the sqlite plugin for firefox to help with maintaining the database, which works surprisingly well. https://addons.mozilla.org/en-US/firefox/addon/5817
As Alex suggested using a wrapper class would also be the best way to go.
Don't forget with 3.0 you can use a CoreData layer around SQLlite which may make it more appealing to you.
If you don't need to store any relational information about your data, why not just use files? There will be some wasted filesystem space, but plain files might be the most memory and CPU efficient solution, depending on the size and number of your items.
I've never developed an iPhone app but I have played around in the filesystem. I have seen sqlite databases floating around various places of the phone. I'm pretty sure it uses a sqlite database to store your calendar entries.
I would use sqlite. It is already there, easy to use, and will provide the most flexible path for expansion in the future.
I use sqlite for static data in my iPhone apps all the time.
All I did was save state when the app is shut down. I used a file for that.
sqlite sounds perfect for your app. sqlite is pretty easy. I've used it in Adobe AIR apps.