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
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
I am making a fitness app that will save your weight, reps, and sets performed for each exercise you perform. I will also use this to track the progress made using this data. Does anyone have any clue how to do so? I've made apps before, but never required the saving of persistent data. Any info would be much appreciated.
You should investigate Core Data and User Defaults.
In your case it sounds like you will need a database so Core Data is the way to go
This seems like a perfect job for Core Data
The Core Data framework provides generalized and automated solutions to common tasks associated with object life-cycle and object graph management, including persistence.
https://developer.apple.com/library/mac/#documentation/cocoa/conceptual/coredata/cdprogrammingguide.html
Depending on how much data you're considering generating and how complex the data itself is, if the amount of data is "small", a simple dictionary might work. They can be saved and read pretty easily. However, there are limitations on what data types you can have in a dictionary (or an array) that you then write out. And, from a performance perspective, if you get too much data, writing and reading it can be slow...
I'll re-iterate the recommendation for Core Data, but wanted to mention the other options for completeness. :-)
I'm new to Core Data, and I'm trying to make sure that I've got my data model and its usage set up properly.
I basically have two file types in my App ... one contains settings type data and a second contains data sets that the user will be working with (kind of like documents, although I can imagine the user working across 10s or even 100s of these files simultaneously).
I've been reading books on Core Data, and I remember reading that typically an app has a single NSPersistentStoreCoordinator, a single NSManagedObjectContext and a single NSManagedObjectModel.
I currently have a single managed object model with configurations for the various file types I have. I had been planning on also having one of the NSPersistentStoreCoordinators / NSManagedObjectContexts, and when I create new Core Data objects, I would make sure that each one was added to the correct persistent store.
However, I've seen examples where each file has its own NSPersistentStoreCoordinator and NSManagedObjectContext.
Are there advantages and disadvantages to having multiple NSPersistentStoreCoordinators and NSManagedObjectContexts in a single thread application?
Initially, I had been hoping to be able to move objects from one persistent store to another during user cut and paste type edits, but that doesn't seem possible either way.
Any advice is greatly appreciated!
Edit
Here is some more information about what is confusing me. When I read the documentation about NSPersistentStoreCoordinator, it says:
The coordinator is designed to present
a façade to the managed object
contexts such that a group of
persistent stores appears as an
aggregate store.
In my case, this is not what I want. I want my documents to be perceived as separate documents, and I don't want the queries to be confused between each other.
In addition, with only one persistent store coordinator and many persistent stores, if I forget to assign an entity to the correct store on creation, I find myself with bugs since entities are arbitrarily assigned to a valid store when they are created. I'm not sure what would happen with relationships that point to objects in different stores (probably an assertion failure?).
To me, it seems that having a single context / persistent store coordinator per store would be less prone to bugs, and allows me to keep the data for each document isolated from each other.
The only thing that a single persistent store seems to buy me is that I can perform a save operation for all stores simultaneously which would be preferable. With multiple contexts / store coordinators, I would need to perform separate save operations.
If you use the OSX NSPersistentDocument class, it seems to enforce a separate context / store coordinator per document.
Anyway, from all my research, it seems that separate store coordinators / contexts would work better for my App, but the reason I posted this is because I am new to Core Data and this approach does seem to go against the recommended flow and I'm worried that I'm missing some gotchas that will come back to bite me.
More Thoughts / Information
As I think about this more and read more feedback from others (thank you everyone!!!), my current thoughts are as follows.
For myself, there really doesn't seem to be that much difference between the two approaches and I currently believe that I could make it work well either way.
With a single store coordinator, I need to make sure that newly created entities are attached to the correct store (not really a big deal). With multiple store coordinators, I need to make sure that newly created entities are added to the correct context (of which I will have many of them). With the way my code is structured, either approach should be relatively easy for me.
I personally want to search a single store at a time. If I have multiple store coordinators, this is automatic. If I have a single store coordinator, I need to make sure to constrain the fetch request. (either way, not really a big deal).
The documentation for the store coordinator implies that its advantage is making multiple stores appear as one. For my app, I do not need or want that so this is not really a consideration for me (although if I wanted to add cross-store searching capabilities in the future, it would be best to keep everything in a single store coordinator).
To me, none of the above reasons are really good arguments either way, and if they were the only arguments, I would probably try to do things the more conventional way and stick with a single store coordinator.
However, one final reason (and the main reason that I originally posted this question) is that I am planning on taking advantage of some features in iOS 5 that seem to require multiple store coordinators. I want to be able to weak-link my app to be backwards compatible, so it seems that having my iOS 4 code closely resemble the iOS 5 code would be preferable.
The more I think about this, with the support for multiple OS versions, I could probably still implement things either way with the correct abstractions.
Thank you everyone for your feedback! I'm slowly getting the hang of Core Data which has mostly been a great experience, although its given me my share of headaches as well!
Generally an app will use only one PersistentStoreCoordinator and it is initialized in app delegate.
For more details and clarification please check the apples doc on Core Data
I can't honestly think of a reason why you would want to have a second coordinator unless you are performing some pretty serious concurrent, multi threaded tasks on the same model. From what you described above, you may only need to create a separate context for certain managed objects, or possibly separate stores if you need them to be completely independent.
You will hardly ever interact directly with a persistent store coordinator as most of your operations are done on the context level and then persisted when you are ready (again via context) through the store coordinator.
You've obviously done your own research so I am not going to tell you to check documentation XYZ (Core Data is well documented for basic level stuff but anything slightly more advanced and you are on your own), but my main point is that having a separate store coordinator for each of these models will probably increase the complexity of your code instead of making it easier to manage which seems to be your main motivation in the original question.
I don't see any real technical limitation to having multiple NSPersistentStoreCoordinator instances in your app as long as they are all pointed to a unique location on disk.
However, taking that approach is definitely not common and is going to add a lot of complexity to your app that may not be necessary. From what you've described about your data model, I don't see any reason why you'd need multiple NSPersistentStoreCoordinators.
Be sure to read the CoreData Programming Guide and know that you'll need to create a unique NSManagedObjectContext per thread, rather than per NSPersistentStoreCoordinator as you described in your question.
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.
I'm creating an iPhone app and I'm trying to choose between 2 solutions for a persistent store.
Core Data, or SQLitePersistentObjects. Basically, all my app needs is a way to store an array of model objects and then load them again to display in a UITableView. Its nothing too complicated. Core Data seems to have a much higher learning curve than the simple to use SQLitePersistentObjects. Are there any obvious benefits of using Core Data over SQLitePersistentObjects in my case?
As the author of SQLite Persistent Objects, I say: use Core Data.
I wrote SQLPO when Core Data didn't exist on the phone. Although I'm proud of what I did with SQLPO and even though I do like some things about its approach better than Core Data's (specifically not having to maintain separate class files and data model), the engine underlying Core Data is much more mature and has many more engineering hours invested in it. That's why I abandoned SQLPO development when Core Data came to the iPhone SDK.
I haven't done benchmarks, but I would guess that used correctly, Core Data is going to perform better in nearly all high-volume situations.
SQLPO is faster to develop with since all you do is create the header files, but unless your data needs are relatively light, I say you'd be better off using Core Data.
See this question. My answer to that question also applies to yours.
Core Data VS SQL Statement, which one is gd for iphone development?
Some infromation on my experience with SQLitePersistentObjects.
An app initially developed for iOS 3.x utilizing SQLPO works just fine. Easy to use etc.
Now I am in the process of bringing this app to iOS 4 and things started to get strange.
I now see DB corruptions at unpredictable rates.
Looking into the SQLPO code shows that there is only one sqlite3_close statement and this is called when the DB can not be opened.
I am planning to add a method to close the DB explicitely and call this from my app delegates terminate and for iOS4 didMovetoBackground methods.
Might help to avoid DB corruption issues with SQLPO.
I recently had to make the same decision. I was storing instances of a simple object with a couple of properties. From my research I understand that using Core Data will help you better manage more complex objects with multiple relationships. I ended up using Core Data only because I wanted to learn more about it (but for simple objects there wasn't much of a learning curve).
SQLitePersistentObjects aka SQLLite Persistent Objects is not the same as doing straight SQLite at all. It's an ORM in its own right. I haven't used it yet, but I wanted to correct the completely wrong answer that the previous poster gave.
And I'm seriously considering using because Core Data is a pain.
See: http://iphonedevelopment.blogspot.com/2008/08/sqlite-persistent-objects.html