Cancel a UILocalNotification with repeat interval - ios

I'm doing an alarm application with repeat interval. My problem is that even if the user clicks the local notification, returns to the app, and then goes back to the home screen of the phone the UILocalNotification stills fire every minute. I'm aware of [[UIApplication sharedApplication] cancelAllLocalNotifications]; and I put it in the my viewDidLoad method. Any advice how I can fix this?

Putting it in viewDidLoad is good for some circumstances just not yours. Think about when viewDidLoad is called:
Called after the controller's view is loaded into memory.
So in other words, the next time it gets called is after your little ARC friend deallocates it from memory. So, yes, eventually cancelAllLocalNotifications will get called again, just not when a user puts the app in the background and then returns it to foreground, because its still has a home in memory; it will be called next time that particular view gets loaded into the memory.
Additionally, that probably is not good logic, because that will happen for every user, even if they didn't want to cancel the repeats.
Ultimately, you will have to create additional logic to decipher which users have, say, hit 'snooze' or 'cancel' with whatever resource works for you and your project. Personally, I would guide you towards using a category based notification, that way you cancel it as needed, instead of 'just in case'. See here how to set those up.

Related

App view seems to reload back to default after some time

I've come across a strange error while programming my iPhone application. Basically when I leave my application in the background and then access it after a long time (i.e. the entire night while I'm sleeping), the viewDidLoad method seems to be called again even though I did not exit the app (I only double tapped the Home button or I tapped the Home button once) but still left the app in the background. However, if I leave the app on for a short period of time (anytime between a few minutes to a few hours), the viewDidLoad method is not called again and everything is as it should be. After doing some research, I found that it is because the viewDidUnload method is called (after the OS finds that the app is suspended for a long time), which calls viewDidLoad again when we bring the app back up. I found this out through this link: view seems to reload itself but it doesn't seem that there's a way to prevent viewDidLoad from being called when the viewDidUnload is called. Is there any way to prevent this viewDidUnload method from being called again? The thing is I want my app to be running for a long time in the background (i.e. a few days in the background) to collect data. Or, is there no way around this? Any help would be appreciated. Thanks!
EDIT: I have realized that after iOS 5, viewDidUnload is deprecated but this phenomenon still occurs. Any ideas on how to fix it? Thanks!
If you want to do stuff in the background you should look into background tasks.

Does delegate have function which is executed every time app comes from background

I have application with lot of view controllers and on every time when app comes from background I have to make some request to server and reinitialise some global variables. At the moment I am doing this by repeating code in every view controller in didViewLoad but I wonder is there way to this in delegate to avoid repeating on 10 places ? ( I check didFinishLuanchingWithOptions in delegate but it is called only first time not when app comes from background ).
I think you want to look at these two:
applicationDidBecomeActive
And
applicationWillEnterForeground
Check out the documentation for more details.

Where to update the UI of a notification widget just once

In my Notification Center Today Extension/Widget I need to update a portion of the UI every time Notification Center is activated. It never needs to update while Notification Center is in use, nor while it's in the background. In what method should I place that code?
viewDidLoad and viewWillAppear are both called every time it will be displayed, for example if you scroll up and down they will be called again, so that's too often.
widgetPerformUpdateWithCompletionHandler is not called at all before it's displayed for the first time it seems (at least with iOS 8.2 beta), and this method is automatically called whenever iOS feels like it to update the UI even when it's in the background which is not appropriate either.
loadView is only called a single time, never to be called again unless the widget is removed from memory. So if you open Notification Center and view the widget then dismiss Notification Center and reopen it later, it may not call that method again depending on whether or not it's been cleared from memory.
I'd just use viewDidLoad and not worry about the possibility of multiple calls. Unless the method takes a long time to run, there's no reason not to do it that way. [And if it does take a long time to run, your today extension is going to suck, so fix that.]
If for some reason you only want it to happen once, add a BOOL ivar to the class. Set it to YES in initWithCoder: Then in viewDidLoad, check that value. If it's YES, do your update and set the value to NO. If it's already NO, skip your update.

background methods are not stopping after viewWillDisappear/ Dealloc

First of all Check This to understand what i am doing
I did not get my answer in above question & still waiting for it.
Now new porblem is that when i click on back button using following code, methods of last ViewController are still running. It will use memory & keep processing untill it gets response(that`s what i want to do but if user press back then i want to stop all methods)
[self.navigationController popViewControllerAnimated:YES];
How do i stop it?
You need to do [getTryAgainTask cancel] (assuming getTryAgainTask is of type NSURLSessionDownloadTask) before you pop this controller. The download task is asynchronous and runs irrespective of the controller (that fired it) being deallocated. This might cause retain loops, leading the app to eventually crash. The code as of now, will go into an infinite loop. A better solution would be to keep a tab on the number of retries (say 3 times) and then prompt the user about the problem, asking if he/she would like to try again.

Termination of an app running in the background

I am currently developing an app that will need to terminate after running in the background for more than five minutes. In order to do this, I will have to have a timer running in the background after the the Home button has been pressed or in case of an interruptions such as an SMS or a telephone call, then, after five minutes the applicationWillTerminate method will be called. My first question is should I put the applicationWillTerminate in the applicationWillResignActive method or in the applicationDidEnterBackground method? My second question is since this is an app with more that one view, Should I write these things in the AppDelegate class or elsewhere? Thank you for your response.
1) You can't force your app to finish programatically.
2) You should never call these AppDelegate methods by yourself. They're meant to be called only by the system.
Reference: UIApplicationDelegate Protocol Reference.
This is pretty ghetto, but what you can do is make your app crash when you want it to exit, and it will close automatically, granted that's not closing the app, but there's no real harm in it as long as you are in control of how it crashes try to go for a bad access error, aka trying to access something that has been deallocated
as for running a timer in the background, i don't know per say if you can do that, but as an alternative you can save the time when they leave the app aka the app goes into the background and then you can have all the events return to your app of the view controller that is first responder, and each UIEvent has a time stamp, and regardless of which event it is you can compare the time stamps and see if it's greater than 5 minutes
Regardless i don't suggest any of the above, but that is the best answer i can come up with for your question
the code for receiving events out side of your app
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
will start the event tracking and the call back is:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event { }
but you have to remember to
[self becomeFirstResponder];
this tells the device which view controller to go to for the event tracking, oh and don't forget to resign first responder, and endReceivingRemotecontrolEvents

Resources