I have been designing my app to store local user data which is changed / sorted and referenced regularly to be stored as global variables held by the app delegate and referenced through:
appDelegate = [[UIApplication sharedApplication]delegate]
Which seems to work though is most likely not best practice, is there any downsides to just holding the same data in NSUserDefaults, SQL Lite seems a bit heavy for my needs considering the data itself is a couple of small arrays of custom objects and is refreshed on start up and throughout the app.
Is there a general best practice for local storage, or does it really depend?
I recommend using Core Data. Although the first experience may be a little confusing, the investment will be worth it.
What you're doing is fine. A better practice would probably be to have a singleton class that contains all the related data. Then anywhere you need the day you just call [[globalData instance] arrayOfData] and have it. That way you abstract the data from your app delegate into a centralized place.
NSUserDefaults is used to store information between app launches. Use it to store settings or things that you read each time the app launches or use it to save the state of the app so a user can relaunch and be in the same place after they exited. There isn't really any noticeable performance issues unless the data you are storing is rather large.
for my needs considering the data
itself is a couple of small arrays of
custom objects and is refreshed on
start up and throughout the app.
As your current requirements are limited to small arrays and custom objects, NSUserDefaults could be used.
But while using NSUserDefault we should take care of these two facts.
1.) For custom object you will need to use Encoding Protocols for directly saving them using NSUserDeraults.
2.) NSUserDefaults some times shows strange behavior if we don't synchronize it properly. you can use its `[NSUserDefaults synchronize].
Core Data should be used when you are working many with interrelated custom objects. Because its concept of object relationship mapping and direct object management is quite good.{at lower layer it uses SQLite}.
SQLite on the other hand is relatively easy to implement and has C api for interaction with system. Here you will need to break down custom object into attributes and run queries.
Related
I am writing an application which needs data persistance. I am using CoreData as my framework for this. I am currently trying to design my data structures for the app, of which I am planning on having 2.
The main data in my app is a sheet of various information which is input in a wizard format. I wish to use a MutableArray to hold the form data.
Secondly, I wish to have an individual instance (singleton) of MyClass available at any time, which I will use as a temporary placeholder to accept data being input during the wizard. Once the user completes all the steps, it will create a new object in the array for it.
What I gather from CoreData is that I need to use the ManagedObjectContext as a bridge between my application and the disk on the iOS Device. My question is:
"Should I use one instance of this context in the app delegate and just reference to it from any view who needs to talk to the files, or do I make a new context on every ViewController."
Right now I am not fussed on memory efficiency, but I wish to be as efficient as I can before I release the app.
If you have a singleton Shared instance as an access layer, you could also make it to be the communicator to your core data context.
I recommend using a UIManagedDocument to setup the managed object context. It is a bit more work at the beginning but for example you could implement iCloud access more easily.
But you can of course also just hold a managedObjectContext (without managed document) in your singleton, or - as in the per designed core data app - in your app delegate (which you can access by the uiapplication shared instance from anywhere).
There is really not one right way, I think. You could look at the Stanford c193p lectures (available on iTunes) and watch the core data sessions to get to know the managedDocument approach.
I'm storing just one NSArray to NSUserDefaults, but this array may eventually have many objects inside.
Could it be a problem using NSUserDefaults?
I would say use Core Data just because you want to simplify your life when dealing with anything more than a hundred data objects within two or more categories or "entities".
Using Core Data means that you're not dumping the entire data set into memory when you load it. Instead, you're using what are called faults which fire when necessary to load additional relationships and associated data.
Migrating the data is also another big benefit of Core Data. When you need to change the data structure, you just create a simple migration and it's done automatically for you. If instead you had an NSArray or NSDictionary in the user defaults, you'd have to iterate over the entire thing and try to change the data structure or migrate an old key name to a new key name. Not an easy task.
Another benefit of Core Data is that it works seamlessly with UITableView and UICollectionView to intelligently search and load only relevant items within your data set which helps improve overall app performance. This is all done via NSFetchedResultsController.
Working with one type of NSArray such as People that only has a hundred people in it shouldn't be a big deal and you can use NSUserDefaults for that as long as the People array doesn't have a lot of associated data stored within it.
Honestly, every app I create that needs any kind of data storage other than basic user preferences uses Core Data now. I don't waste my time on Property Lists or user defaults anymore and I would recommend you not to either.
NSUserDefaults is named as it is for a reason. It's designed to store a handful of user preferences and settings for your app, not the bulk of its data. If you're storing anything that resembles a database, NSUserDefaults is not the way to implement it -- use Core Data, as per #iWasRobbed's answer.
NSUserDefaults only use to store limited amount of data.if you have large amount of data you should go with coreData.
I am really confused on what the Core Data actually is. Or I guess my question is, when dealing with a database, would you use Core Data? Like if I wanted access values from a database would I be using Core Data to access those values? How would I approach this problem?
Thank you so much for the help.
Core Data is an framework that does the work of "object persistence". In other words, it's code you can use that takes care of saving a collection of objects to disk and loading them again later. It does a lot of work to allow you to store lots of data and load only the objects you need at a time, and unload ones when memory is tight.
Core Data can use a database to accomplish this, but that's it's business, not yours. When you use Core Data, it is a black box. You tell it to save the data and then step out of the way.
If you want to interact with an existing database, such as a MySQL database on a web server, that's a completely different matter. You might use Core Data to store local copies of objects on your device, but in that case Core Data won't care that the objects are copies from some other database. It doesn't care.
It is a convenient, native means of storing data in your iOS applications. Don't think of it as sqlite although you can view the files it creates with various sqlite tools. Instead think of it as a tool for manipulating an object graph of information important to your app.
I've used it in two main ways. First to store a bunch of static data that is important to an app, in one case that was a large amount of location data for an indoor mapping application. What arrived as a massive CSV file of waypoints was converted to core data. Core Data was incredibly useful for this because it allowed preparing a sqlite file which was shipped with the application containing all the infomation. Updates from a web service arrive as more CSV that is added to the Core Data to keep information current. At runtime the location information object (the waypoint a user is at) is retrieved with a predicate (i.e. the point they tapped on) and that object, through its Core Data relationships, indicates where it is possible to go from that point. Core Data provided the information necessary to perform A* routing through the indoor map.
Second it is great when you have a bunch of objects arriving as JSON and you want to be able to store and access those objects later. Let's say you have a typical app where you have a User and some information about the User, let's call it Thing. Users have Things. When you want to know something about a User you retrieve the Core Data record using a predicate - typically "name" or similar - and you get all the information you stored about the User back. Again you can make use of relationships to explore the user's connections and make displaying information easy. Perhaps the User has many Things, then you can say "user.things" and you get a NSSet of NSManagedObjects representing those Things.
You use it like a database. Its utility is that it is easy to access from anywhere in your iOS code, it is easy to store and easy to retrieve information also. Faulting lets you retrieve one object and navigate to any object connected through relationships by following the relationships. Because you define the attributes and relationships yourself in the data model editor it is easily customized for what you need to store. To me it is one of the most used and most useful parts of iOS.
When you want to automate display of information from Core Data you can use a NSFetchedResultsController to initiate a fetch and to respond through delegate methods to changes to the underlying data. If you set up a UITableView to use a NSFetchedResultsController as data source, you can have the table automatically update whenever the objects displayed in the cells changed. Very useful for apps where you periodically update information and want what is displayed to be kept current.
When your object model changes it is possible to maintain all of your existing information and migrate it to the new model. Core Data manages automatic (lightweight migration) when it can, or if you have made more radical changes you can supply rules to handle the migration.
The limitation of Core Data is that it is not great for storing binaries. If you have images that you need to store, far better to store a path to the location of the image than trying to store the actual data.
Yes, if you want a local database on your device, Core Data is the appropriate technology. It probably makes sense to start your research with the Core Data Programming Guide.
You can alternatively use SQLite (which Core Data uses in the backend), but Core Data offers some material advantages and is the preferred database interface for iOS. If you decide to pursue SQLite for any reason, though, I'd suggest you contemplate using the FMDB Objective-C SQLite wrapper.
But Core Data is generally the way to go.
I'm about to implement caching on my app, I imagine there are already good patterns on how to do that.
I think I'm going to use Core Data but I was wondering the best way to do that.
Most of the doc I found are just for Core Data tutorial.
What I do is to generate the NSManagedObject but then I also use a similar class with my additional methods, this to be decoupled from future fields addition keeping the generated one independent.
Is there some tutorial on the best way to handle object caching with Core Data?
Thanks in advance.
For keeping the hand-written code separate from the machine-generated code when using Core Data, have a look at mogenerator. Very useful.
As far as caching goes, Core Data's pretty decent, and with judicious use of batch faulting and pre-fetching, you can fairly easily manage the number of trips to the persistent store. The faulting mechanism works well in my experience, so be wary of premature optimisation when it comes to Core Data.
The advice Apple gives here is good, in particular use the profiling tools to see the part of your app that isn't working efficiently, and then address that specifically, rather than spending time writing code for a problem that doesn't exist.
Caching to file system is discouraged on iOS. Use Core Data for permanent storage, not temporary caching when possible.
There are however two in memory caching facilities provided by Apple.
NSURLCache for caching responses using the URL loading system (NSURLConnection and friends.). Simply create a new instance, and set it using +[NSURLCache setSharedURLCache:].
NSCache for caching any object. Just create an instance, add and fetch cached object using keys like form a normal dictionary collection. Supports both count and cost limits, as well as locking cached objects using the NSDiscardableContent protocol.
You could also use a in-memory NSPersistentStore for Core Data if you like to work with managed objects, that are only to live for one execution of the app.
So I have been doing lots of reading and found out NSCache is not persistent which is a slight problem for what I need to do. I have heard that I will need to use Core data instead... but I don't have any experience with core data so am wondering if its the only solution for persistent data.
The app will allow the user to search through a catalog, by typing in a search parameter in the code and select a distributor for their search parameter. What I want to do when the app loads is download the list of distributors and save them to a "cache" the will be persistent (till when the header I will make at some point changes and demands the app to update the cache), so that if the user turns the app of or the phone next time then open it the manufacture.
Now that I'm getting abit deeper into my app I'm getting abit lost in things for instance how would setting up a cache work with regards to NSURLConnection.
Any suggestions or code examples would be greatly appreciated..
This previous answer of mine might help you decide.
To sum it up:
If your data is small, static and low-complexity, use a collection class and write it to disk using the built-in class methods
If the data is static, low-complexity but large, SQL may be a good solution especially if you already know it.
If the data is dynamic and complex regardless of size, then Core Data is your best choice.
Viewed purely from the technical perspective, Core Data is always the best choice for iOS/MacOS API apps. Core Data is not just a persistence API, it is an API for creating the model layer of the Model-View-Controller design paradigm that the Apple API uses. It not only persist the data, but models it, validates its and provides an easy interface to the rest of the API.
If your going to be writing iOS apps, you need to eventually learn Core Data. However, it does have a learning curve and you should pick the method right now that will let you ship a usable app.
You can also check out sqlite. Here's another question that discusses getting started with sqlite on the phone: Where's the best SQLite 3 tutorial for iPhone-SDK?
The advantage to sqlite is that it is fairly easy to pick up. The downside is that you have to write queries for everything, and that can be a pain. It doesn't save objects, just data, numbers or text.