UIUserNotificationSettings Alert Causes App to Resign Activity - ios

I currently have an application that requires Local Notifications, so naturally I must ask the user if he or she would like to 'Allow Notifications'. Here is how I am doing this:
AppDelegate.m
// Local Notifications
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
}
At the initial loading of the app, I have a AVAudioPlayer that begins playing. I have it set up so that when the user leaves the app (the application enters the background) the music fades out and pauses.
The problem is that during the first time the app is launched, when the notification pops up asking for the user to allow notifications, it appears that the app is fooled into thinking it is about to resign activity. I can't seem to figure out how to either avoid JUST the notification alert from triggering this, or at worst "bring the app back", and becoming active once the alert is dismissed with one of the 2 notification options.
Here is what I am calling in my ViewController to notify the app when it changes state:
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(pauseAudio)
name:UIApplicationWillResignActiveNotification object:nil];
...
}
If someone could tell me how to ignore the notification alert so that it does not think it will be resigning activity, OR how to bring back the application after it does "resign". I currently have these other notification handles in attempt to bring it back, but they are not called after the alert "messes everything up":
(in the same ViewController within viewDidLoad)
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(animateLoginScreen)
name:UIApplicationWillEnterForegroundNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(resumeAudio)
name:UIApplicationDidBecomeActiveNotification object:nil];
I appreciate any help on this one. Thanks!

Whenever a "system dialog", such as the notification permission dialog, is shown your application does resign active because it is iOS, not your app, that is responsible for processing the permissions request.
Your app isn't 'fooled', it really is resigning active for the period of time that the dialog is displayed. I suspect that you should pause your audio on your application entering the background, not merely on it resigning active. UIApplicationDidBecomeActiveNotification should be posted if you are getting a willResignActive though. Do you get a call to the corresponding AppDelegate methods?

Related

How to determine app is in active state or inactive state ios?

I need to know when an App is in Foreground, it is in active state or inactive state ?
If my App is in inactive state I need to fire the Logout Protocol and destroy the current user's session,
- (void)applicationWillResignActive:(UIApplication *)application
{
NSLog(#"App is not active logout success");
}
Is there any appDelegate method which tell me that app is in inactive state, any code example will help me a lot.
If need work with "NSNotificationCenter", in which class can I add the code and who will be observer.
To test for the state you can do something like:
[[UIApplication sharedApplication] applicationState]==UIApplicationStateInactive
or
[[UIApplication sharedApplication] applicationState]==UIApplicationStateActive
If you want to be notified you can do:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(yourselector:)
name:UIApplicationDidBecomeActiveNotification object:nil];
or
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(yourselector:)
name:UIApplicationDidEnterBackgroundNotification object:nil];
You can do other notifications too (from https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplication_Class/):
UIApplicationDidBecomeActiveNotification
UIApplicationDidChangeStatusBarFrameNotification
UIApplicationDidChangeStatusBarOrientationNotification
UIApplicationDidEnterBackgroundNotification
UIApplicationDidFinishLaunchingNotification
UIApplicationDidReceiveMemoryWarningNotification
UIApplicationProtectedDataDidBecomeAvailable
UIApplicationProtectedDataWillBecomeUnavailable
UIApplicationSignificantTimeChangeNotification
UIApplicationUserDidTakeScreenshotNotification
UIApplicationWillChangeStatusBarOrientationNotification
UIApplicationWillChangeStatusBarFrameNotification
UIApplicationWillEnterForegroundNotification
UIApplicationWillResignActiveNotification
UIApplicationWillTerminateNotification
UIContentSizeCategoryDidChangeNotification
If you want to use the app delegate, you can use:
- (void)applicationDidEnterBackground:(UIApplication *)application {}
or
- (void)applicationDidBecomeActive:(UIApplication *)application {}
Please refer this Apple Doc :App Life Cycle
applicationDidBecomeActive:—Lets your app know that it is about to become the foreground app. Use this method for any last minute preparation.
applicationWillResignActive:—Lets you know that your app is transitioning away from being the foreground app. Use this method to put your app into a quiescent state.
applicationWillEnterForeground:—Lets you know that your app is moving out of the background and back into the foreground, but that it is not yet active.
applicationWillTerminate:—Lets you know that your app is being terminated. This method is not called if your app is suspended

Run Loop to set color to button ios?

I've got sort of a problem with my ios application. It handles the Apple Push Notification (APN) and everything BUT, my app handle it in it appDelegate.m
The problem is I want to make a button to change color if the user have a notification, so I search a way to do it and I found "Run Loop", is this possible to have a Run Loop in a secondary thread to check infinitely if there is a new notification? (with a wait of 5/10 seconds between each verification) I don't really know how to declare it neither to make it works alone. (I'm pretty new with xCode and used the AFNetworking asynchronous methods for the rest of the app so I'm not really good with threading and co.)
It could be really great if someone is able to give me a way to implement a simple run loop in my app.
Thank you!
EDIT : I have a white button for User profile, and I want it to change to Red when the user have a notification, the button is already declared and works in a viewController, but I don't manage to link it to the appDelegate, that's why I'm asking to do a RunLoop who could handle a BOOL sent by the appDelegate, that my view do only in the viewDidLoad (that don't really work when app is in background etc...)
I don't really see why you need a Run loop?
You could use NSNotificationCenter. https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html
AppDelegate.m
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive) {
[[NSNotificationCenter defaultCenter] postNotificationName:#"didRecieveNotification" object:nil userInfo:userInfo];
}
}
And add your ViewController where the button lives as a observer:
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleNotification:) name:#"didRecieveNotification" object:nil];
}
-(void)handleNotification:(NSNotification *)notification
{
YourButton.backgroundColor = [UIColor redColor];
}

Spurious UIApplicationDidBecomeActiveNotification notification

I am able to register for UIApplicationDidBecomeActiveNotification and properly receive events. But sometimes I receive these notifications WHILE the app is still running. I suspected memory problems to trigger an app resign/resume but could not confirm this was the case (I saw once a memory warning at the same time). Any reason why these methods would be called while the app is running (no call, no lock, etc.)?
I am registering for these notifications:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appDidBecomeActiveNotif:) name:UIApplicationDidBecomeActiveNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appWillResignActiveNotif:) name:UIApplicationWillResignActiveNotification object:nil];
(This is done once in a singleton constructor using dispatch_once)
The corresponding functions:
-(void)appDidBecomeActiveNotif:(NSNotification*)notif
{
NSLog(#"appDidBecomeActiveNotif called");
}
-(void)appWillResignActiveNotif:(NSNotification*)notif
{
NSLog(#"appWillResignActiveNotif called");
}
Here are some logs:
2013-04-11 09:28:11.401 App[1499:907] appWillResignActiveNotif
2013-04-11 09:28:13.505 App[1499:907] appDidBecomeActiveNotif
This is what the docs says about those notifications:
UIApplicationDidBecomeActiveNotification
Posted when the application becomes active.
An application is active when it is receiving events. An active application can be said to have focus. It gains focus after being launched, loses focus when an overlay window pops up or when the device is locked, and gains focus when the device is unlocked.
UIApplicationWillResignActiveNotification
Posted when the application is no longer active and loses focus.
An application is active when it is receiving events. An active application can be said to have focus. It gains focus after being launched, loses focus when an overlay window pops up or when the device is locked, and gains focus when the device is unlocked.
So, are there any overlay window pop ups or are you locking the device or anything like that?
Also, why not use the methods in the AppDelegate to listen to those events?
EDIT
The problem, it seems, is MapKit's pop up asking the user to use it's location.

notification launch custom method/class

just want to make sure i'm on the right path.
I'm creating a local notification as an alarm clock. when the user hits button... I want it to DO STUFF.
I'm thinking I have to call my method in
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
.. .for when the application is closed
(void)applicationWillEnterForeground:(UIApplication *)application
... for when the application is in the background... when user hits okay
Is there a better way to do what I'm trying to accomplish... DO STUFF when user hits okay on notification?
thanks in advance
According to the documentation of local and push notifications, you should call application:didFinishLaunchingWithOptions: in both cases :
Handling Local and Remote Notifications
Let’s review the possible scenarios when the operating delivers a
local notification or a remote notification for an application.
The notification is delivered when the application isn’t running in the foreground.
In this case, the system presents the notification, displaying an alert, badging an icon, perhaps playing a sound.
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 application: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 .
They can not be forced to call. only Monitoring.
UIApplicationDelegate Protocol
These methods provide you with information about key events in an
application’s execution such as when it finished launching, when it is
about to be terminated, when memory is low, and when important changes
occur. Implementing these methods gives you a chance to respond to
these system events and respond appropriately.
If you want you're ViewController get Notification there method. try this
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidFinishLaunching:) UIApplicationDidFinishLaunchingNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationEnterForeground:) name:UIApplicationWillEnterForegroundNotification object:nil];
- (void)applicationDidFinishLaunching:(NSNotification *)noti
{
//do stuff
}
- (void)applicationEnterForeground:(NSNotification *)noti
{
//do sutff
}

Application does not run in background simply does not work

I have read over many stack overflow questions where people ask to terminate their app oppose to let it run in the background.
The main answer I found was to set the application does not run in background BOOL to YES in my info.plist
I have done this and cleaned my project but still my application runs in the background when the user presses the home button. This solution simply does not work.
What can I do to make my application quit when a user presses the home button.
My app is currently running on iOS 6.
Any help is appreciated :)
This answer is for your first comment, not the original question. Have your iPod view controller register for the UIApplicationDidEnterBackgroundNotification notification. The implementation should stop the music. This is a much better user experience than choosing to have your app terminate on suspend.
// Put this in a good place like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(backgrounding) name:UIApplicationDidEnterBackgroundNotification object:nil];
// Handle the notification
- (void)backgrounding {
// app is leaving the foreground, stop the music
}
// In your dealloc method add:
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];

Resources