What's the code to subscribe to an event like applicationWillResignActive in any place in your iphone application?
[UPDATE]
Let me rephrase my question. I don't want to respond to this in my application delegate, but rather listen to this event from another class. Is that possible or I need to pass the event from the application delegate to the concerning class?
Looks like you are looking for this code.
- (void) applicationWillResign {
NSLog(#"About to lose focus");
}
- (void) myMethod {
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(applicationWillResign)
name:UIApplicationWillResignActiveNotification
object:NULL];
}
Take a look at the documentation for the method you're talking about:
applicationWillResignActive:
Tells the delegate that the application will become inactive. This method is optional.
- (void)applicationWillResignActive:(UIApplication *)application
[...]
Discussion
[...]
Just before it becomes inactive, the application also posts a UIApplicationWillResignActiveNotification.
Implement the method below in your application delegate:
-(void)applicationWillResignActive:(UIApplication *)application
This allows you to react when the application becomes inactive - when this is the case, it is executing but not dispatching incoming events. This happens, for example, when an overlay window pops up or when the device is locked.
Just before it becomes inactive, the application also posts a UIApplicationWillResignActiveNotification.
Your topic and question are asking slightly different things.
Your application will receive applicationWillResignActive, along with applicationWillTerminate, automatically. No subscription is necessary, just implement the function in your app.
As to how to respond, this is down to the application. While you can choose to do nothing the recommended behavior is that you cease or slow any non-critical functionality. E.g. if you were a game you would stop updating the display and/or pause the game.
Related
Flurry docs recommend placing the startSession call in applicationDidFinishLaunching:.
Two problems with this...
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
[FlurryAnalytics startSession:#"AWESOMEAPIKEY"];
// ...
}
1) Isn't application:didFinishLaunchingWithOptions: the new approved launch point?
2) This is only called once on launch, but don't we want session info every time a user opens or switches back to the app? Or does Flurry handle all that on their own by listening to some event or NSNotification?
Wouldn't a better place to put the startSession call be in applicationDidBecomeActive: or applicationWillEnterForeground:, like so?
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// ... Flurry AppCircle setup
[FlurryAnalytics startSession:#"AWESOMEAPIKEY"];
// ... your setup
}
for your case 1)
correct place to put [FlurryAnalytics startSession:#"SOMESESSIONKEY"]; is
application:didFinishLaunchingWithOptions:
you can place it there without worries. I have done this by myself and the app is working awesome at appstore and providing the stats perfectly.
for case 2), your secession will be automatically resumed when app returns to foreground so you dont have to do any special handling here.
I was real curious about this too. I looked at my inherited code for my app and didn't see any flurry activity in didbecomeactive, foreground, etc. I only saw the startsession in didfinishlaunchingwithoptions. I saw the below on the flurry site re: startsession, but i still don't get how it works, just behind the scenes stuff the flurry library does? #samfisher, can you elaborate?
"This method serves as the entry point to Flurry Analytics collection. It must be called in the scope of applicationDidFinishLaunching. The session will continue for the period the app is in the foreground until your app is backgrounded for the time specified in setSessionContinueSeconds:. If the app is resumed in that period the session will continue, otherwise a new session will begin."
FlurryApi.h shows the default as 10 for setSessionContinueSeconds so I guess Flurry handles it, I'm just looking for more confirmation.
http://support.flurry.com/sdkdocs/iOS/interface_flurry_analytics.html#a78b0b92085b38875d51f1ca0d699849a
I want to trigger an event when pressing the home button. Is there any particular api for using that?
Thanks
Shawn
Use applicationWillResignActive and/or applicationWillTerminate. You have a limited amount of time to do stuff in these functions, so be quick.
Make your viewController a NSApplication delegate and the implement
- (void) applicationDidEnterBackground:(UIApplication *)application
When the iPhone application is running in background and it receive a remote notification. So it will execute the didReceiveRemoteNotification call back. In that I am going to push to a new UIViewController. But before that its noticed that its calling the applicationWillEnterForeground callback.
In that I am also doing some location update using a modal dialog. So when this notification arrives this both scenarios happens and the app is getting crashed. So is there any way to block the applictiaonWillEnterBackground processing on remote notification. As the moment is little bit hard cos this processing is done after applicationWillEnterBackground controller.
Thank you.
The callback application:didReceiveRemoteNotification: should only be invoked when the application is running in the foreground. When running in the background you should instead get a call to application:didFinishLaunchingWithOptions:.
Since you are asking the question and also using core location it might be that application:didReceiveRemoteNotification: is called when the application is in the background but I would think that would be a bug. At least according to Apple's documentation.
Anyway, NO, you can't block applicationWillEnterForeground:. Without knowing exactly what you are doing in the different callbacks I would recommend that you set a flag in applicationWillEnterForeground: if you are doing something there and then check that flag in application:didReceiveRemoteNotification:
- (void)applicationWillEnterForeground:(UIApplication *)application {
if (somehingHappend) {
somethingHappended = YES;
}
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (!somethingHappened) {
// push your view controllers or whatever
}
}
Where somethingHappened is a BOOL defined in the same class as an ivar.
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.
I want to implement this function on my apps but i cant seem to figure out how to use this line of codes.
- (void)applicationWillResignActive:(UIApplication *)application {
//our app is going to loose focus since there is an incoming call
[self pauseGame];
}
- (void)applicationDidBecomeActive:(UIApplication *)application{
//the user declined the call and is returning to our app
[self resumeGame];
}
I've read that this must be placed in appdelegates but i cant seem to figure out how could i call my pause action when the game is currently in the viewcontroller.
Thank you.
Instead of sending the messages to self (which is the app delegate), you would send them to your view controller.
For example, if your app delegate had a property for your main game view controller named "gameViewController" (where the methods to pause and resume were implemented):
- (void)applicationWillResignActive:(UIApplication *)application {
// our app is going to loose focus since there is an incoming call
[self.gameViewController pauseGame];
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// the user declined the call and is returning to our app
[self.gameViewController resumeGame];
}
I know that this was answered a long time ago. But I wanted to add that another (more scalable) solution is to have interested parties (e.g., UIViewControllers) register an interest in UIApplicationDidEnterBackgroundNotification and UIApplicationWillEnterForegroundNotification.
This approach has the advantage that the Application Delegate doesn't need to have direct knowledge of the objects that might need to respond to entering background/foreground.