App in foreground and background - iphone

I have a button ON/OFF in my viewcontroller that plays some music when it is turned on by the user. Now if the user clicks the iPhone home button and re-launches my app again, the button is shown as "ON" but there is no music playing. So the user has to hit ON-OFF-ON again for music to start playing again.
Anyone know how can I call my ON/OFF view controller button so that I can set it to OFF when app enters background and set it to ON and play the music when it enters forground in these app delegates?
I know I need to write to a plist file the button & music state on applicationDidEnterBackground. I don't know how can I get to those action from appdelegate since they are defined in my viewcontroller.
Similary, when the app enters the foreground I will read the saved plist file and then set the state of music and button again. Again, I don’t know how to call my controller methods from delegate.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"Inside applicationDidEnterBackground");
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(#"Inside applicationWillEnterForeground");
}

One possible methodology is to send a message from the app delegate to the view controllers to save or restore state. Then the view controller, which have access to their internal state, can implement any needed save and restore methods.
If the app delegate does not directly contain a reference to the active view controller, it can send the message down the chain, to root view controller, which can then send a message to the next view controller, and etc., each controller saving anything it considers important on the way down.

All you need to do is subscribe to the UIApplicationDidEnterBackgroundNotification notification in your view controller
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(handleEnteredBackground:)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
Theres also a notification for DidEnterForeground too.

Related

iOS UILocalNotification - No delegate methods triggered when app is running in background and the icon is clicked upon notification

iPhone version - 5.1 (9B176)
Below is the series of events during Local Notification where in which didFinishLaunchingWithOptions method is not invoked.
App is running in background.
Got local notification - simple notification no dialog.
Click on the app icon which shows the badge number.
Expected as per Apple documentation:
As a result of the presented notification, the user taps the action button of the alert or taps (or clicks) the application icon.
If the action button is tapped (on a device running iOS), the system launches the application and the application calls its delegate’s didFinishLaunchingWithOptions method (if implemented); it passes in the notification payload (for remote notifications) or the local-notification object (for local notifications).
If the application icon is tapped on a device running iOS, the application calls the same method, but furnishes no information about the notification
Actual :
didFinishLaunchingWithOptions NOT invoked. But applicationWillEnterForeground and applicationDidBecomeActive were invoked.
You are correct. The behavior is inconsistent with the documentation. Putting the documentation aside and focusing on actual behavior; The crux of the matter seems to be this: If your app becomes active by the user interacting with the notification you will receive a pointer to the notification, if the user taps your application icon directly you will not.
To illustrate. If you present an alert style notification and the user taps the action button, or if, as in your case, you present a banner notification and the user taps on that you will receive a pointer to the notification in one of two ways:
If your application was in the Not-Running state:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
UILocalNotification *launchNote = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (launchNote){
// I recieved a notification while not running
}
}
If your application is running in any state:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
// I recieved a notification
}
In the case where a user elects to cancel an alert style notification, that notification is gone.
The truly annoying an inconsistent part is that if you present a banner notification and the user taps your icon you seem to have no way of retrieving a reference to the presented notifications in the notification center. i.e. they do not appear in the [[UIApplication sharedApplication] scheduledLocalNotifications] array, presumably because they are no longer scheduled but are now presented.
So in short; The documentation is wrong. And there are other annoying inconsistencies. If this behavior is a problem for you you should file a bug with Apple.

Remove Modal View Controller when Application becomes active

In my app I have a button, when the user clicks it, it brings up a modal view controller which gets the user's location (with a UIActivityIndicator and image on). When it has there location it will send them off to another application.
This works well on older devices (without multi-tasking) because the app simply re-launches back to it's previous state after I go back to it.
However on devices that have multi-tasking, when I resume the app, the view that tells the user it's getting their location is still there - which is not at all desired.
My first idea was to set a BOOL when it was about to fire them off to the other app, and then in the viewDidAppear, if the BOOL is true, dismiss the modal view.
That would work, if viewDidAppear got called when an app resumes active. As I have just learnt, it doesn't.
Is there a method that view controllers can respond to when the app resumes active to that view? Or, will I have to set up delegation etc with the app delegate? If so, can you explain how I would do that?
You can send a notification when the app becomes active and listen to it into your modalviewcontroller. I think this is the easiest way.
// Into the app delegate
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName:#"ApplicationDidBecomeActive" object:nil];
}
// Into your modal view controller register it for the given notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidBecomeActive:) name:#"ApplicationDidBecomeActive" object:nil];
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
//...
}
Otherwise you can disable the background mode of your application by setting the "UIApplicationExitsOnSuspend" key to YES in the info.plist file.

How apply Setting changes at restart?

I work on a project on iPhone iOS 4 with Xcode 4.
I have a view with a UIButton. The title of the UIButton is set in viewDidLoad. So when app starts, the Button has a title.
However, my app has a Settings bundle and the button title can be also changed in Settings app. So I clic on the home button, my app quits, I go to the Settings app, and set a new button title.
When I quit Settings and restart my app, the button title is not refreshed, it is the old button title. Everything is as I had left.
Only if I turn off the iPhone, then turn on and relaunch my app (i.e. at full restart) the button has at the new title.
How to make sure that the button title changes when the app is (not full) restarted?
Thank you.
You want to update the settings in applicationDidEnterForeground. That gets called when it resumes.
Edit: Had a typo, it should be
- (void)applicationWillEnterForeground:(UIApplication *)application
see docs: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html
I was mistaken in thinking that the viewWillAppear message would be sent to the ViewController when the app became active again after switching back from the Settings app. There is a notification posted when the app becomes active, however, so you should be able to accomplish what you want by registering your ViewController to receive UIApplicationDidBecomeActiveNotification notifications:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(refreshButtonTitle:) name:UIApplicationDidBecomeActiveNotification object:nil];
and then create the appropriate method in your ViewController to be called when the notification is fired:
- (void)refreshButtonTitle:(NSNotification *)notification {
// update the title of your button here
}
You can register to receive NSUserDefaultsDidChangeNotifications and then act accordingly to update your UI.

How to save video capture in progress if user taps home button to terminate app

I am using UIImagePickerController to capture video.
I have set the delegate to save the captured video when video capture is stopped.
The delegate does get called when stopVideoCapture is called by the program based on user action.
I would like the same actions to also happen if while video capture is in progress the user presses the home button to terminate the app.
I tried adding call stopVideoCapture in applicationWillTerminate but for some reason the delegate action to save the video is not being called. The imagePickerController delegate is a separate view controller and not the UIApplicationDelegate.
As of iOS 4.0, applicationWillTerminate will not be called when the user presses the home button. Instead, see applicationDidEnterBackground: (or have your view controller listen to the UIApplicationDidEnterBackgroundNotification notification). Try setting up a background task with beginBackgroundTaskWithExpirationHandler:.
You should check iOS 4.0 support for short-time background tasks before exit, check beginBackgroundTaskWithExpirationHandler.
Here's link to Apple documentation.

How to reload view when application becomes active after suspended?

When the user changes NsuserDefaults in settings on the iPhone and activates my app after it being suspended, i want to reload the active view.
How can i do this?
You could implement the applicationDidBecomeActive: method in your application delegate, or register for the UIApplicationDidBecomeActiveNotification notification in any other object.
- (void)applicationWillEnterForeground:(UIApplication*)application on the App Delegate is invoked when coming out of suspend.
Implement this method, in it check if the setting you are about has changed, find your topmost view controller and reload it's view then.