Where do you put global application data in an iPhone app? - iphone

I have an app that allows the user to view, manipulate and manage a collection of Schedule objects. Different parts of the app need access to this data. I've experimented with making the collection a singleton, but I didn't find that very clean.
I recently changed to storing the global data in the AppDelegate class and using:
MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.myGlobalData doSomething];
Which eliminates the need for my global data to be a singleton, but is really just taking advantage of the UIApplication singleton.
There really isn't just one primary view controller where it makes sense to store it in my case. So I was wondering what different strategies people use to address this.

If you've got a central data model that needs to be accessible to multiple controllers, there's nothing wrong with using a singleton to manage the data-- a "sharedManager" is exactly what the scenario demands. This is essentially what Apple does with their address book API for manipulating contacts. They use a C-style API but it involves getting a reference to the shared address book database and then using that in future calls.
Using the app delegate works too, but as you note it's really the same thing. You're designating the app delegate singleton as the owner of the data model, which is OK too.
NSUserDefaults can be abused in this way but that's really not its purpose. Aside from being kind of ugly, it also puts restrictions on the type of data you can store. Your own model can store whatever data you like, but NSUserDefaults is not quite so flexible.
Using SQLite or a property list or whatever to store the data to a file is really orthogonal to the question of how to manage it. From your description a singleton approach sounds reasonable, and that singleton can write to files in whatever way makes sense for the data you're working with.

Many people store everything in the AppDelegate and access the data through [[UIApplication sharedApplication] delegate].
If the data are supposed to be persisted, you could also use the NSUserDefaults singleton.
If the data are big, maybe you need SQLite.
This is for "global" data as you asked.
If your view controllers are organized in tree, a better way would be passing the required data from parent UIViewController to child UIViewController.

Related

IOS ManagedObjectContext Placement

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.

Simple iPhone Application

I'm in the process of the building a simple iphone application and I had a few questions.
I need to parse through results from an API key search, and manipulate them in my program. The API is from rotten tomatoes, and I can't find a parser that works with ARC. I know the JSON kit works well for previous versions of XCode, but I really like ARC and have done my application to date using it.
1) Is there a solid parser for such results or is it something I'm going to have to do manually?
The basic structure of my app includes a search page and personal list of things, using a mutable array of objects to populate a table view.
2) whats the best way to design the classes and implementation? I know this is a vague questions so let me be more specific. I have one object with several attributes, and I want to both access a remote server and rotten tomatoes API, and store local data internally. So I have my storyboad with a controller for each tab view (there are two). Then I have my object class. Do i need to create a controller specifically for it or can I manipulate (create and delete) in other controllers?
I can give some more specifics about the application, I'm just feeling a little overwhelmed as it is my first time working with Xcode. Any help would be appreciated.
May i suggest you the NSJSONSerialization Class., it should work well with ARC as it is compatible with iOS 5 and above.
Or you can set the ARC flag to no in .m files that you would like it to be switched off. For that purpose you can refer a great answer here.
You can set a compiler flag on the implementations that aren't going to be used in ARC.
Use: -fno-objc-arc
About the first question, you can turn ARC off on specific files, this allows you to mix ARC enabled with non-ARC enabled classes in the same project,
Please refer to the answer of this question
How can I disable ARC for a single file in a project?
About the second question
Do you have two different classes that access the same api services?
If yes i suggest that you create a common remote-request class, this class will do the request for you.
For example:
Let say we have class1 (for tab1) and class2 (for tab2)
And we have classCommonRequest(for both the requests)
App delegate will hold a reference to the classCommonRequest
class1 and class2 can both access this class by using
YourAppDelegate *delegate = (YourAppDelegate *)[[UIApplication sharedApplication] delegate];
//get your refrence of request handler class
MyRequestHandler *request = [delegate myRequestHandler];
//then use functions in it
[request fetchSth];
If your question was more specific i could give you better answers :)
I hope this helped anyway

iOS iPhone MVC basics

Does anyone know of a good way to start with a basic model but not use Core Data yet? I have a simple application that doesn't need to save any data (at the moment), but I don't think Core Data would be overkill for it.
I don't want to use the App Delegate to store data, nor do I want to store data in individual views. I was hoping to find some sort of "transitioning" type of solution that would let me switch over to Core Data in the future.
I've seen some simple examples, but they require storing an instance of the model within a particular view controller. I plan to have several views, so I want to find a better way.
The data model for an app can be as simple as a dictionary, or an array of dictionaries, or a plain old C-style array of characters for that matter. Or, to take it one step further, you might create a custom model class that not only stores the data but also knows how to manipulate it as necessary for your application.
How each controller gets access to the model is a different question. Some people like to use a singleton (I don't) so that they can access it globally. A (IMO) better approach is to instantiate the model in an object like the app delegate or root view controller, and then pass either a pointer to the entire model or a pointer to part of the model to view controllers as needed. An address book app might pass just a Person object to an address detail view controller, for example.

Iphone, for regularly updated data is NSUserDefaults still the easiest option?

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.

iphone global settings - best way to implement it?

I'd like to have some settings that I can access from anywhere in my app. Is there a best way to implement this? Right now I'm just sticking properties in my app delegate, then access them with:
ClientAppDelegate *appDelegate = (ClientAppDelegate *)[[UIApplication sharedApplication] delegate];
settingValue = appDelegate.setting;
If they are persistent, use NSUserDefaults. If they are not, wrap them in a class and give every class that needs them a pointer. In every case you should probably make it possible to change the connection to the configuration object so that (1) the dependency gets obvious (“aha, this code’s behaviour depends on the configuration”) and (2) you can supply a custom configuration object for testing purposes. There is a great series of articles about singletons, coupling and testing by Miško Hevery. You can start by the post called Singletons are Pathological Liars and follow up from there, it will do good to your design.
Use NSUserDefaults—they're a reliable, simple way of storing application settings, and even persist between app launches.