Check instance of UIAlertView when going in background - ios

I have referred the following links for this issue, but neither of the solutions worked for me:
Link 1
Link 2
I think these solutions don't work for iOS7.
So now how would I be able to find out whether there is any UIAlertView open, when my application enters in background state.
I want to dismiss the UIAlertView before going into the background.

Remove alert in applicationDidEnterBackground
Add this line in your class
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(enteredBackground:)
name:UIApplicationDidEnterBackgroundNotification
object: nil];
And implement method as well
- (void)enteredBackground:(UIApplication *)application
{
if (mainAlertView && mainAlertView.isVisible)
[mainAlertView dismissWithClickedButtonIndex:0 animated:NO];
}

You get a notification when the app is send to background, so detect that notification in the class that displays the alert view and remove it, that's all

have you checked UIAlertView property #property(nonatomic, readonly, getter=isVisible) BOOL visible Also while going in the background you get a notification in - (void )applicationDidEnterBackground: you can check there and remove all alertviews if any

Related

ChromeCast delegates are not called when the app is in the background

I am working on an application in which I will connect to the T.V using ChromeCast device, to achieve this I have used GoogleCast FrameWork in my project,
I am facing a problem when my app goes to background
Am writing piece code in this method for calling a method to mute the audio
- (void)applicationDidEnterBackground:(UIApplication *)application {
HomeViewController *lHomeViewController = [[HomeViewController alloc] init];
_mediaControlChannel = [[GCKMediaControlChannel alloc] init];
[lHomeViewController muteAudio];
}
It calls the method in the home view controller, where in which I wrote the below code
-(void) muteAudio {
[self.deviceManager setMuted:YES];
}
But the audio is not muted and it is not calling the below delegate method.
- (void)mediaControlChannelDidUpdateStatus:(GCKMediaControlChannel *)mediaControlChannel
Please suggest me
You are creating a new instance of the HomeViewController in the applicationDidEnterBackground app delegate method. You need to send the muteAudio message to the running instance of HomeViewController.
For this, the best solution would be to use NSNotificationCenter.
In your HomeViewController's viewDidLoad or viewWillAppear method, use the following line:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(muteAudio)
name: UIApplicationDidEnterBackgroundNotification
object: nil];
This will automatically call the muteAudio method when the application enters background.
Read more about NSNotificationCenter here.
Read more about the application status notifications here.

Notification or delegate called when UIAlertView is hidden/removed

I am trying to find what delegate/protocol or even notification is called when an alert view is hidden or shown. Do these events trigger a notification or callback that I can listen for?
I know the UIAlertView protocol, but that's not what I am looking for, I am looking for the actual display and hide events to perform actions after they are completed.
Does this exist?
If you want to know about AlertViews you've presented yourself, you're looking for UIAlertViewDelegate protocol
didPresentAlertView: and alertView:didDismissWithButtonIndex:
If you want to know when an AlertView has been shown by the OS, you can try UIWindowDidBecomeVisibleNotification and UIWindowDidBecomeHiddenNotification in the UIWindow class reference, then check if the windowLevel property is equal to UIWindowLevelAlert
An easy way to check NSNotifications is adding that code to your AppDelegate.m:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(notification:) name :nil object:nil];
return YES;
}
-(void)notification:(NSNotification*)notification
{
NSLog(#"Notification name is %#, \n sent by %#\n\n",[notification name], [[notification object] description] );
}
I tested this code triggering UIAlertViews and I never receive an NSNotification related to.
So probably there aren't NSNotificationrelated to UIAlertViews.

Send NSNotification from AppDelegate

I want to send an NSNotification from this method (when the UIButton is clicked) in my AppDelegate.m:
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0){
//cancel clicked ...do your action
// HERE
}
}
..and receive it in one of my UIViewControllers. How can I do that?
EDIT WITH MORE INFO: I am making an alarm app, and when the user presses the UIButton, I want to stop the alarm. I figured that NSNotifications is the only way to get information from my AppDelegate.m file to a ViewController.m file?
You should to register your receiver object to accept some messages sent from Notification Center.
Suppose you have Obj A which controls your alarm, and value "stopAlarm" is the message which can stop alarm. You should create an observer for a "stopAlarm" message.
You can do, with:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(controller:)
name:#"stopAlarm"
object:nil];
Now, you should create a method controller that manages this messages:
- (void)controller:(NSNotification *) notification {
if ([[notification name] isEqualToString:#"stopAlarm"]){
//Perform stop alarm with A object
}
}
Finally, you can send the message "stopAlarm" when you want in the code with:
[[NSNotificationCenter defaultCenter]
postNotificationName:#"stopAlarm"
object:nil];
I Hope this may help.
EDIT:
When your UIViewController are unloaded or when app terminate, you should call:
[[NSNotificationCenter defaultCenter] removeObserver:self];
for stop observing.
That's all.
Thanks to Hot licks for correction.
You may want to create a class–maybe even a singleton if there is only one alarm–that manages the timer. That way you can manage from any place in your application rather than in the view controller. Take a look at:
http://dadabeatnik.wordpress.com/2013/07/28/objective-c-singletons-an-alternative-pattern/
and:
https://developer.apple.com/library/mac/documentation/cocoa/conceptual/Notifications/Articles/NotificationCenters.html
As Hot Licks mentioned, you really do not want to jump into this without knowing what is going on. Hopefully these links will help get you going in the right direction.

Why is my NSNotification its observer called multiple times?

Within an App I make use of several viewcontrollers. On one viewcontroller an observer is initialized as follows:
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"MyNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMethod:) name:#"MyNotification" object:nil];
Even when removing the NSNotification before initializing the number of executions of myMethod: is being summed up by the amount of repeated views on the respective viewcontroller.
Why does this happen and how can I avoid myMethod: being called more then once.
Note: I made sure by using breakpoints that I did not made mistakes on calling postNotification multiple times.
Edit: This is how my postNotification looks like
NSArray * objects = [NSArray arrayWithObjects:[NSNumber numberWithInt:number],someText, nil];
NSArray * keys = [NSArray arrayWithObjects:#"Number",#"Text", nil];
NSDictionary * userInfo = [NSDictionary dictionaryWithObjects:objects forKeys:keys];
[[NSNotificationCenter defaultCenter] postNotificationName:#"myNotification" object:self userInfo:userInfo];
edit: even after moving my subscribing to viewwillappear: I get the same result. myMethod: is called multiple times. (number of times i reload the viewcontroller).
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"MyNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMethod:) name:#"MyNotification" object:nil];
}
edit: something seems wrong with my lifecycle. ViewDidUnload and dealloc are not getting called, however viewdiddisappear is getting called.
The way I push my Viewcontroller to the stack is as follows where parent is a tableview subclass (on clicking the row this viewcontroller is initiated:
detailScreen * screen = [[detailScreen alloc] initWithContentID:ID andFullContentArray:fullContentIndex andParent:parent];
[self.navigationController pushViewController:screen animated:YES];
Solution:
Moving removal of nsnotification to viewdiddisappear did the trick. Thanks for guidance!
Based on this description, a likely cause is that your viewcontrollers are over-retained and not released when you think they are. This is quite common even with ARC if things are over-retained. So, you think that you have only one instance of a given viewcontroller active, whereas you actually have several live instances, and they all listen to the notifications.
If I was in this situation, I would put a breakpoint in the viewcontroller’s dealloc method and make sure it is deallocated correctly, if that’s the intended design of your app.
In which methods did you register the observers?
Apple recommends that observers should be registered in viewWillAppear: and unregistered in viewWillDissapear:
Are you sure that you don't register the observer twice?
Ran into this issue in an application running swift. The application got the notification once when first launched. the notification increases the number of times you go into the background and come back. i.e
app launches one - add observer gets gets called once in view will appear or view did load - notification is called once
app goes into background and comes back, add observer gets called again in view will appear or view did load. notification gets called twice.
the number increases the number of times you go into background and come back.
code in view will disappear will make no difference as the view is still in the window stack and has not been removed from it.
solution:
observe application will resign active in your view controller:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "applicationWillResign:", name: UIApplicationWillResignActiveNotification, object: nil)
func applicationWillResign(notification : NSNotification) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
this will make sure that your view controller will remove the observer for the notification when the view goes into background.
it is quite possible you are subscribing to the notifications
[[NSNotificationCenter defaultCenter] postNotificationName:#"myNotification" object:self userInfo:userInfo];
before self gets initialized. And trying to unsubscribe 'self' which isn't really subscribed to, and you will get all global myNotification notifications.
If your view was hooked up in IB, use -awakeFromNib: as the starting point to register for notifications
It is possible that the class with the observer is, quite appropriately, instantiated multiple times. When you are debugging it will kinda look like the notification is being posted multiple times. But if you inspect self you might see that each time is for a different instance.
This could easily be the case if your app uses a tab bar and the observer is in a base class of which your view controllers are subclasses.

XCode ARC Multiple instances of the same view

I am new to iOS development and I am writing a 3-View Location Application.
The first view is the main view of the application, the second view is a table view with several locations and the third view is a detail view, where the user is able to edit or add new Locations to the table view.
I'm using the CLLocationManager in the first and in the third view but every view of both has got his own CLLocationManager instances, because for the detail view I need the best accuracy whereas in the MainView I dont need the best accuracy.
So here is the problem:
In my AppDelegate.m I have got a notification, which fires when the Applications enters foreground:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[NSNotificationCenter defaultCenter] postNotificationName: #"didEnterForeground" object: nil userInfo: nil];
}
In my third view, the DetailViewController.m, I register in the viewDidLoad for this notification:
- (void) viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(enteredBackground:) name: #"didEnterBackground" object: nil];
[[NSNotificationCenter defaultCenter] addObserver: self selector: #selector(enteredForeground:) name: #"didEnterForeground" object: nil];
}
The enteredForeground Method in DetailViewController.m just needs to start the Location Manager again (the didEnterBackground Method stopped him)
- (void) enteredForeground: (NSNotification*) notification {
[self.locationManager startUpdatingLocation];
}
I am using XCode 4.2 with ARC.
The problem is, that if I visited the DetailView for about 10 times, go to background (f.e. from the MainView), then I enter foreground again then 10 LocationManagers will be started immediately (this is what my NSLog says).
It seems that for the DetailView (and for the other Views) the same number of instances like the number of visits for these views exist.
Maybe the views dont get released properly if they disappeared, perhaps because of the NSNotification?!
I would appreciate if someone could help me with this matter, cause so many LocationManagers will stress the battery pretty hard.
Thanks in advance!
I believe you need to stopUpdatingLocation when it goes to the background. Otherwise, it will spawn multiple instances.

Resources