I've been looking around for a way to store an NSArray containing lots of NSDictionaries. So far I've come across a few different ways of doing it, the most popular of these seems to be the NSUserDefaults approach. That said, it just doesn't seem right to me. In my mind the NSUserDefaults should only really be used for storing the settings a user has selected.
Please can someone help me out with the best way to approach this problem? I'm certain that there must be some standard approach, however I can't seem to pin it down!
Apple does has a framework that provides generalized and automated solutions to common tasks associated with object life-cycle and object graph management, including persistence. ;-)
Seriously though, Core Data should be your first port of call, since it is optimised for the platform, and will scale too. Once you get your head around how it works, it's really fairly straightforward. Also, it's likely to perform better than any roll-your-own solution you come up with.
Please read Archives and Serializations Programming Guide. The top two choices will be to save the array as a property list, or to create an archive using NSKeyedArchiver.
Related
I will make a simple game app which will store some data as user progresses in levels. For example: each level has a number of sub-levels, sub-level stores 3-4 properties (strings and arrays) depending on user's progress.
The app is simple and it is not a lot to store (about 150 levels and sub-levels maximum with small amount of data in each) and I do not want to make it complicated with multiple classes representing levels and sub-levels plus SQLLite database. I thought of a simpler approach but good enough to manage data through my GameManager singleton.
Recommend what approaches to look at for my needs to store and manage data for this type of an app. Perhaps one of these or something else:
NSUserDefaults + NSDictionary
CoreData + SQLLite
etc...
Just want to make sure I am not missing anything
It's much better and less painful for you to use core data. Why do you say sqlite?? Core Data is just saving your objects in a sqlite file on an iOs device and in xml in Cocoa app.
To use plist files is kind of strange, as I think. You can put into it only a simple array, and what if you want to display photos besides your simple array? The preferred way is core data - 50% less code, as apple says. Use NSFetchedResultsController and you'll be good!
Another widely used practice would be to store your information in a property list (.plist). NSDictionary and NSArray come equipped with the capability to load from as well as write to a property list.
Here's a resource which may be helpful to you: Property List Programming Guide
Take a look into core data. It seems very difficult once you get started. But once you get into it, it gets pretty straightforward from there. Check out this tutorial he helped me get going. Hth
As an exercise, I'm trying to rebuild the Notes App and was wondering what the best file system for a notes app would be?
I guess these are the requirements:
1) Not all notes should be loaded at the same time (lazy loading); i.e. I don't want to have all notes in one huge NSMutableDictionary or NSMutableArray -- so ideally, I guess that a separate file for each note would be a good idea
2) Notes should be searchable. Again, I have no idea what is best suited, but my feeling is that searching through a huge string containing all notes may not be the best solution.
3) Export. I guess this is not really that important when thinking about the data structure, but if I wanted to do a dropBox or iCloud sync, is there any file system which is more suitable than another? Especially if I wanted the user to be able to edit separate txt files for each note they've done?
Any ideas and suggestions where to start would be very much welcome! Thanks in advance.
Core Data with spotlight export will be your best option.
The real trick is make the model support detailed searches with things like keyword entities and linked-list type structures. These are a lot of work but they can make searching almost instantaneous.
I know little about Core Data. Read: I've read a few tutorials, kinda understood how it works, but never tried to use it in any of my apps. That said, I'd like to know if it's worth the effort to use it in the app I'm developing. Note that I'm not asking if I should learn Core Data, but if it's worthwhile to invest time learning it for this specific app I'm making, or if I should use archiving instead, ship the app, and only then learn Core Data in my spare time.
Basically my app reads a list of items from a web service, and needs to save the last N items. The user should also be able to bookmark items, so that's another thing I should store somewhere. So, right now I'm just archiving a subarray with range 0-N of the latest items. Does it work? Yes. Is it efficient, and the best way to achieve this? That's my question for you actually.
My doubt comes from the fact that whenever I see someone asking 'Is Core Data overkill for my project?' everyone suggests to use it anyway.
If the amount of data you need to persist can easily fit into memory without degrading the apps performance then you should just archive the array and ship the app.
Core Data gives a lot of advantages when handling large and complex data sets. It gives a lot of advantages in maintaining and upgrading a shipped app. However, those advantages should not get in the way of shipping an otherwise completed app. Later, you can always write code to migrate a shipped version to a Core Data version. It's more work, but hey, at least you've got a shipped app to work on.
I've seen a lot of small startups/developers come and go and the major factor that separates the successful from non-succesful is that the successful actually ship/release product. You can spend forever polishing an app but the key thing is knowing when to say, "It's good enough" and get the thing into the user's hands.
If it's a small list and you have the data in NSDictionary or NSArray collections, use writeToFile:atomically: instead for flat file XML Plist storage.
I still think you should learn Core Data eventually, but.
Are there any other database engines that could be used on the iPhone, besides sqlite3? Something like textDb is for PHP, single-file and no server.
There are a slew of alternatives to SQLite, but there is little point to using them as others have pointed out.
Before pointing out some alternatives, some points:
First, SQLite is an excellent single-file, non-client-server, small-footprint SQL database. The performance is excellent, it is a relatively tiny runtime, and it is thoroughly fast. There isn't an embeddable SQL-interpreting alternative that is either all around technically superior or anywhere near as popular.
Secondly, if you are doing persistency in an iPhone application, you should very likely be using CoreData. There are certainly reasons not to, but they are pretty uncommon. Beyond being a higher level mapping to a relational store that is quite adeptly integrated with Cocoa Touch, Core Data solves a number of very difficult problems above and beyond persistency; object graph management, efficient memory use (i.e. push stuff out of memory when no longer needed), and undo support, to name a few.
Finally, if you do decide to use some other database persistency layer, keep in mind that the iPhone 3G and prior is an extremely memory constrained runtime environment. The very presence of any kind of additional library can significantly reduce the working memory available to your app. Whatever solution you choose, make sure it is optimized to use as little memory as possible.
So, seriously, if you are looking to not use SQLite or CoreData it is either because you have a very rare case where they aren't appropriate or because you are being curious. If curious, well... good for you!
If you are looking for alternatives, the SQLite documentation includes a set of links to similar products.
Pretty sparse list and it isn't because the author is hiding anything. There simply isn't a lot of motivation in the industry to try and re-invent this particular wheel because SQLite does a really good job. There is a reason why Google, Adobe, GE, FireFox, Microsoft, Sun, REALBasic, Skype, Symbian, Apple, and others have pretty much standardized on SQLite to solve their non-client/server relational persistency needs; it just works.
If you're looking for an alternative, I would say Core Data.
I had the same question for a long time and even used SQLite in some projects. After speaking with an Apple Engineer though, he pointed out that Core Data could do everything that I was using SQLite for (mainly just storing information and accessing it in a few different ways).
I would start with the with Core Data Programming Guide and see how it works for what you're looking to do.
I think your problem is that you are thinking of a software library more like a software product. People want choice between Internet browsers for all sorts of reasons. But when you have a software library, it's pretty much set up for one purpose. If it doesn't fulfill that purpose well enough, it shouldn't be a library.
Do you not like NSObject? Do you not like the Core Foundation library? Then write your own. However, to drag up an unfortunately overused analogy, don't reinvent the wheel, unless your job is making new and innovative wheels.
SQLite does perform acceptably, and so it is supplied as a library on the iPhone platform. SQLite works for what I need it to do. If it doesn't work for you, then maybe you have some reason you'd like to share?
Freedom of choice is fine if you want to choose between Internet browsers, but I would think that as a programmer, one should have a very specific reason for going out of their way, spending valuable time to fix something that already works. Even with my choice of Internet browser, I have specific reasons I choose one over another.
No. Everyone seems to be happy with SQLite.
In the development of my first serious iPhone application (Meaning I'd like to actually get it out on the AppStore), I needed a good way to represent my data. Instead of going with core data, I (stupidly, I think) decided to use classes to represent my data.
I created three classes, MMDot, MMShowMovement, and MMShow. The MMShowMovement holds instances of the MMDot class in an array, as the MMShow holds instances of MMShowMovement. Sounded like a nice way to do it, each class has a lot of logic that has to go with it, so I thought that classes seemed like a good way to go about representing all this data.
My question is, is there an easy way to save the instances of these classes so I can restore the data after the application is reopened? I have made applications on OS X using a NSKeyedArchiver, would it be similar on the iPhone? Would it be easier to start again using Core Data instead (These objects are very complex, especially MMDot with about 15 instance variables, now that I look at it, maybe not THAT complex)?
I'm really at a loss here.
You can absolutely use NSKeyedArchiver to persist your objects. I'm a fan of either method, the decision mostly lies with your application needs. I don't think it will be much work to re-model your objects in CoreData. Without knowing anything about your application I'd say if you are doing simple persistence with a simple model you may not need Core Data, if you have complex relationships and will be reading/persisting data frequently during an application session Core Data is probably the way to go.
If you have a lot of object instances, you are probably better off using Core Data - it will help cache things, help you with queries to get specific sets of objects, and so on. KeyArchiving is really a lot more useful if you are saving off a handful of instances, but have some downsides - in particular it's harder to track down memory leaks from Unarchived objects.
Core Data can also do paging of results for you too, so that you aren't fetching in the entre contents of a large array if you do not need it.
I was looking into serializing my classes the other day and went with using NSUserDefaults. I just give all the internals of my objects a unique key based on the object. Seemed to work fast for me.
Wrote a blog about it here: http://technolojiadev.blogspot.com/2009/12/serialize-this.html