I currently have my app settings stored in an Entity called Settings. Each of my settings is an attribute. I have one Settings object which I load in my app delegate, and I access it through the delegate throughout the project. I am thinking of moving the settings to NSUser defaults. I would probably not need the Settings bundle since I have everything setup in the app. Besides the use of the settings bundle, I was wondering if anyone can tell me what are the benefits of using NSUserDefaults over my current method? Is there any way my choice can affect/improve app performance?
If there are a substantial number of items to be saved then archiving or a plist such as you currently have may well be best.
One advantage of NSUserDefaults is that specific items can be accessed and saved from any method individually. NSUserDefaults also supports several non object types.
Typically if I need to save essentially most of a classes state I will use archiving.
There is no reason not to use a combination, choose the method of persistence of each item individually.
Generally there will not be a large performance difference.
For substantial data choose Core Data.
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 have severals configuration settings that I need to be able to access throughout my application. These settings can't and won't be editable by the user. I'm coming from a web application background and I don't know what approach is recommended.
If my application was for the web, I would create a file config file config.py or config.php then set everything I need to set then load it where I need it. For iOS, I came across NSUserDefaults where it is use mainly for user preferences (at least that what I see people using it for). However the data I wish to store are not preferences at all.
Should I create a class and store my values in it or use NSUserDefaults ?
It is perfectly fine to use NSUserDefaults to store application configuration information that is not a user-visible configuration option. That said, my recommendation would be to create a class on top of NSUserDefault so that 1.) it is easier to change the underlying implementation if necessary and 2.) you have the strings representing the variable names only in one place (to avoid accidental spelling differences) and you can refer to individual variables by specific getter functions.
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.
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).
What's the best way of dealing with variables in constant use in an iPhone app, like username/password in a twitter client?
If you are using them all over, you can store them in either the AppDelegate or an object referred to by the app delegate.
Another popular option if the data is only needed by a small section of the app, is to create a singleton class where you ask it for the current instance and store what you need there.
If you'd like the data to persist, then you really want to use either a database (CoreData is nice) or NSUserDefaults to hold values. Since you mentioned twitter usernames/passwords specifically, note that you should really hold onto data like that in the keychain, so that it is stored in encrypted form.