I'm having a hard time handling interruptions in my OpenGL ES 2.0 iOS app. This really pertains to OpenAL, which I think I know how to handle, but the issue is that my interrupt handler never ends up being called. I've tried registering for notifications with:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(interruptionHandler:)
name:AVAudioSessionInterruptionNotification
object:nil];
among other methods (AVAudioPlayerDelegates etc.).
On the iOS Simulator, if a user swipes down to bring up the Notification Center, or swipes up to bring up the Control Center, and then gets back into the app, the OpenAL code needs to be reset because it stops working. But, how do I capture these two interruptions?
Related
I have an audio app that plays when being launched. It has CarPlay entitlements, plays from the network and naturally plays in the background.
Now, every one in a while the phone launchs the app in the background without notice. Music simply starts to play randomly. I can't determine the cause or the situation in which this reproduces. It might be related to Bluetooth connections, phone calls, CarPlay interactions, network changes or other reasons.
I do know the following things for sure:
The app is launched from scratch as I have examined remote logs and seen the app is being launched.
Pausing the music from control center will kill the app, and it will be relaunching after 2-3 minutes again (and again)
There are not too many clues about your issue.
But I would try to find some possible causes base on my experiences.
First of all, check the notifications/listeners that you use in the app.
Something would be like bellow:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(reachabilityChanged:) name:kReachabilityChangedNotification object:nil];
for this one, once the network status changed, you would get the notification, and you might do something after that(play the music).
Second, check out if there is Timer in the app or not, it would cause problem if
the timer was set improperly and you do something by the timer.
I am currently dealing with Smartcard reader connected to a IOS device as an external accessory. When application goes to the background and remains there for a few (let's say 10-15 seconds) the reader is disconnected by iOS in order not to drain battery. This sends notification to NSNotificationCenter that the reader (EAAccessory) has been disconnected. When app comes to the foreground, it usually takes some time till the reader is connected back.
I am able to handle with these notifications using following methods:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(EAaccessoryConnect) name:EAAccessoryDidConnectNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(EAaccessoryDisConnect) name:EAAccessoryDidDisconnectNotification object:nil];
The problem is, sometimes when application is in the background for a longer time (longer than 20 minutes), more than one EAAccessoryDidDisconnectNotification is obviously posted to the notification centre as well as EAAccessoryDidConnectNotification.
When I receive EAAccessoryDidDisconnectNotification I have to adequately handle it and allow some time till the EAAccessoryDidConnectNotification is received. However when another EAAccessoryDidDisconnectNotification comes, it messes up with my settings and the user is logged out from the application.
My question therefore is - is it possible to check which notifications have been sent to the NSNotificationCenter while app was in the background just after the app comes to the foreground, and remove multiple notification of the same kind - leaving only one notification of a kind. Or is there any other solution you suggest me to implement to deal with this?
Am using NSNotificationCenter in my iPhone App to post a notification
// I add an observer in didFinishLanchingWithOptions() in the AppDelegate
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(getData:) name:kNotif_GetData object:nil];
....
....
// then in another method, I post the notification
[[NSNotificationCenter defaultCenter] postNotificationName:kNotif_GetData object:nil];
....
One user says that this functionality (which is executed by getData()) is not working. so that might mean that the notification hasn't gotten fired. Any idea why this might happen? When I test it with different devices, it works perfect. The user uses iPhone5 and iOS7. Is there any more setting or any explicit user setting which is needed or which could turn this on/off?
No, notification centre is reliable.
"Not working" is not enough information to diagnose the problem. Get more information from the user or add more logging so that you know what is actually going on.
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.
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];