how to inform other class that default settings has been changed - iphone

I am doing and setting for my application. I am able to be notified that my setting defaults have been changed ( by changing them in the Setting application ). However, how can I let other classes knowing that the default settings has been changed

if you have several class to notify then you can use NSNotificationCenter for notifying then.
In this thread you can get an idea for using Notification center

There are several ways you can achieve that:
First - have the other classes check the values every time when needed, by coding the Settings Container as an always available singleton pattern object.
Second - have all relevant classes be notified via NSNotification when required.
And probably many more...

The link that you provided shows everything you need to do.
This code:
[[NSNotificationCenter defaultCenter] addObserver:yourClassThatNeedsToBeNotified selector:#selector(selectorNameOfYourClass:)
name:UIApplicationDidFinishLaunchingNotification object:nil];
is dedicated to add notification about any change of NSUserDefaults.
So if you have several classes that have to get this notification just add this code to each class init method, and don't forget to remove this notification in dealloc.

Related

performSelectorOnMainThread over Notifications

I have some basic doubt's, guess someone will help me out.
Please refer this Question : Update ULabel immediately while downloading files
I have tried using performSelectorOnMainThread , which is calling the updateProgress method in another class and but the label is not updating.
But now I have used the notification like
[[NSNotificationCenter defaultCenter] postNotificationName:#"updateProgress" object:nil userInfo:nil];
which seems to be calling the method and also updating the UILabel. Eventhough my problem is resolved, I want to know why the above performSelectorOnMainThread didn't worked out for me? Any specific reasons ?
The class where you make the performSelectorOnMainThread call and the updateProgress method needed to be in the same class. If not, (in your case), create a method in the class where performSelectorOnMainThread was called and redirect it to the updateProgress on the other class.
The performSelectorOnMainThread can be used to run some codes in your main Thread. It not seems to be a method to call a method on another class (Even though you can call the method on another class using this if you have the working instance of the class). If you are using API calls in one of your class, you may have to use seperate threads for performing the API calls as it blocks the main thread (Its not kind to users who use your app). So in the ios you must call the UIKit from main thread only.
The NSNotification is used to get a event call. I mean it notifies the observer when occurs a specific event that the observer registerd to be get notified.
Hope this helps you.

Notice a view is loaded from outside of a viewController

Any help would be appreciated.
I am looking for a way to programatically notified that a view is loaded from outside of that viewController.
Lets say my main view has 5 buttons, after the view is loaded and the buttons appeared I want to be notified in another file (outside of that viewContrller) that it is loaded. How/Where can I check this and be notified?
Do I need to do some Aspect Oriented Programming?
Use NSNotificationCenter. You can communicate between classes.
NSNotificationCenter or a delegate method is the most appropriate way to accomplish this.
Listen for a custom NSNotification inside your other object. Have your view controller post that notification during whichever part of its life cycle makes most sense (viewDidLoad, viewDidAppear ...).
If you can't post a notification, then observing a keyPath might be the way to go. For example, you can put something like this in your control object and then implement observeValueForKeyPath::
[viewController addObserver:self
forKeyPath:#"view"
options:NSKeyValueObservingOptionNew
context:NULL];
While you can do this with notifications as others have suggested or KVO, this strongly suggests a design problem. You should never be accessing a view controller's internal views directly. So the deeper question is: why do you want to know?
The most likely cause in my experience is that you're letting some other object set the titles or modify enabled. This breaks MVC and leads to the kind of problems you're probably trying to fix. The correct way to handle this is to put the data into a model object that is shared between the various view controllers. The current view controller can then observe changes on the model and update its UI elements appropriately.

iPhone Delegates And Making 2 Instantiated Objects Talk To One Another

I have had about 6 hours trying to work out custom application delegates. even following tutorials i end up with errors!
I need a simple way of allowing one object to talk to another.
I have a root view. then another view which then pushes onto the stack with a list of options. then another view showing the relevant options based on the previous selection.
So basically 3 views, and i need view 3 to pass data back to view 1 when i popBackToRootViewController.... This is becoming a huge headache, for something that in theory should be so simple. I have previously just thrown data into nsuserdefaults but using protocols in the way apple suggest to do it.
Please can someone help me understand :)
There a different ways to solve that problem. First of all, you could pass the first View over and over to the View you are making changes on and then call a method of view 1. I won't recommend that.
Another, much easier way is to use Notifications. Just register your first View in the notification center [[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(somethingChanged) name:#"aStringWichIsUniqeForCallingSomethingChanged" object:nil];. You have to provide and implement a callback method (somethingChanged in my case). In your subwiew where the things happen, you have to post a notification by doing [[NSNotificationCenter defaultCenter] postNotificationName:#"aStringWichIsUniqeForCallingSomethingChanged" object:nil];. And don't forget to remove the view from the notificationcenter if they are not needed anymore!
[[NSNotificationCenter defaultCenter] removeObserver:self];
A third possibility is to use a singelton (like the app delegate) which contains all views that should communicate. Simple make all views as ivars & properties for them in this singleton and implement in each of them methods which should be called if something changes. Then call [[singelton sharedInstance] view1] somethingChanged].
If i say View, i mean viewController, but i'm to lazy to write that. ;)
Hope, that helps!
Protocols and delegation formalize a concept which works even if you don't follow the formal rules: It's about declaring a way for objects to talk to each other about the same thing, especially in those cases where you either don't have or don't want control about one of the objects, or in cases where things get complex and you want everything nice and tidy so it's easier to reuse the code.
In those cases however where a rather small, well known set of information is to be passed back and forth between two (or more) well known objects which are unlikely to be reused, informality is quite ok.
This means you could:
provide the sending object with a property of the type of the receiving object
implement a method in the receiving object which will take the information to be sent as an argument
at some point, for example in your case when the root controller pushes the child which becomes the sending object, the receiving object will set itself as the value of the sending object
if the sending object has information to send, it uses the reference to the receiving object to send it a message calling the earlier mentioned method, passing the information as an argument
As I mentioned before, this makes sense for glue code. You shouldn't be doing it this way though, if:
you're working in a team and you're working on one object and a teammate is working on the other
it's obvious you may be able to use the same functionality in a future project. In this case, think about having an intermediate subclass between your original superclass and your app-specific subclass, one that encapsulates the core functionality and offers a formal protocol to interface with it
the exchange of information involves objects of different classes within the same app
the exchange of information itself is rather complex and one (or two) glue methods wouldn't cover it

applicationWillTerminate, delegate or view?

I am looking to save some settings when my application exits and I am a little confused about the 2 different versions below. My feeling is that to better fit the MVC pattern I should be using the version in the viewController. I am just curious as most folks don't seem to do much in the appDelegate when that call would be used?
AppDelegate
-(void)applicationWillTerminate:(UIApplication *)application {
NSLog(#"_deli: applicationWillTerminate");
}
ViewController
-(void)applicationWillTerminate:(NSNotification *)notification {
NSLog(#"_view: applicationWillTerminate");
}
many thanks
EDIT_001:
Sorry, I should claifiy, you would also need to add (see below) to the ViewController to make the above work.
UIApplication *app = [UIApplication sharedApplication];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillTerminate:)
name:UIApplicationWillTerminateNotification
object:app];
gary
Use whichever one has access to the data you want to save. So if the ViewController can see the data but the AppDelegate can't, use that.
Well, to flog my personal hobby horse, I would say that settings are a form of preferences that should be saved in a dedicated data model. NSUserDefaults, for example, is a data model built on the singleton pattern. You could, of course roll your own. There is no problem with having multiple data models in the same app if they manage unrelated information.
The key is to save defaults/preference/state as they are made. Then when the application quits the defaults are already automatically saved. Remember that on the iPhone you never know when the app will be interrupted or quit. Save as you go is really the only option.
Also, in the code examples you provided, how will the view controller know when the application quits? IIRC, UIViewController does not have a applicationWillTerminate: method and does not automatically receive a specific app will quit message. (Edit: In the comments, KennyTM points out that the view controller can register and listen for UIApplicationWillTerminateNotification) You would have to put this functionality in -viewWillUnload. Otherwise, you would have to track your view controllers from the app delegate have the delegate send the active view controller a message when the app quit.

Looking for concept for managing game level views, level selection views, preferences view, storing levels, environment variables

I'm developing a puzzle game application - watch on youtube - for iPhone, and the actual "in-game" part is almost done. It is a separate Class (subclass of UIView) what initializes with a puzzle clue, puzzle pieces, and is ready to send a message for somebody if the puzzle has solved ("completeness" check invoked on every touchesEnded).
Now I'm troubled how to design the whole application pattern programatically.
The game needs a main menu view, a puzzle selector view, fromwhich I can "create" puzzleLevel instances, I have to store the actual puzzle data in a separate class (I suppose), maybe in archive files, and need a preferences view, inwhich I can change the "global" variables that every puzzleLevel instance should use (angular snap values, skins, etc.).
I can feel that I have to do something with the main viewController what controls all the views I've mentioned above, but I don't know how to do it exactly. Where should I store global variables? Where should I store puzzle data? How should I report the "puzzle completeness", and who for should I report? How should I design the view hierarchy?
I'm wondering if somebody could show me some concept, or just a link where I can get along. I'm interestend in concepts mainly, the actual coding part can be "googled" after.
Typically my games have an App object at the top, which owns one of several AppStates (menu, selector, preferences, etc) and switches between them as required, in a pretty typical usage of the State pattern. These states handle their own rendering and input and store whatever resources they need. The App object also owns any global application-wide settings and objects that are shared across the states (eg. rendering, sound). These may be passed in to the states individually, or the states could request the relevant interfaces back from the App at some point.
One of the AppStates will be the game playing state, and that will contain the definition of the current puzzle, plus the current state of this play session (eg. how completed it is). I would tend to still have a separate Game class that is owned by the relevant GamePlayingState, since the former would contain only game logic information and the latter handles input/output.
I think I should use the NSNotification class. It is simply set up a "listener" in the object (viewController) that contains the subviews, then subviews can send notifications to the controller. Then the notification handler can invoke any methods.
viewController part:
-(void) viewDidLoad
{
//Set up a listener.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notificationHandler:) name:#"finishedCurrentLevel" object:nil];
...
}
-(void) notificationHandler: (NSNotification*) notification
{
//Notification handling.
if ([notification name] == #"finishedCurrentLevel") [self finishedCurrentLevel];
}
-(void) finishedCurrentLevel
{
//View managing code here...
}
The notification, the listening and the "responds" for the notifications set up this was. The actual notifying goes like this (can be executed from any subviews):
[[NSNotificationCenter defaultCenter] postNotificationName:#"finishedCurrentLevel" object:nil];
It solves my "communication" problem, I think.
About globals I simply created a separate globals.m file with the coressponding globals.h without defining any class. They just "attach" some extern variables, so I can reach them from any file having globals.h imported.