issue With NSTIMER iOS SDK - iphone

i wrote like:
[NSTimer scheduledTimerWithTimeInterval:900 target:self selector:#selector(CallGetCounts) userInfo:nil repeats:YES];
that means i want to repeat my timer for every 5 mins but my timer is not repeating, not able to find the reason
can any one please tell me the answer.
I wrote this in "AppDelegate" -> "- (void)applicationDidEnterBackground:(UIApplication *)application" method.

In background your code is suspended and no timer events you will receive until your application comes to the foreground again.
You should go for scheduled local notifications to get waken up from background after a given interval. However they will show a popup or a banner to the user that he has to accept first.
Here are some steps on how to do it:
// When you want to schedule:
UILocalNotification* localNotification = [[[UILocalNotification alloc] init] autorelease];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:5]; // seconds
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = #"Body text";
localNotification.alertAction = #"Button text";
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// when it's fired it will call your AppDelegate's didReceiveLocalNotification
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotification
{
// you can handle timer event here and eventually re-schedule your local notification
}

Normally when an app enters the background, it is suspended so it doesn't execute at all. In particular, NSTimers don't fire. If you want something to happen in the background, you need to configure your app to run in the background and use one of the approved methods of performing the task you want to do. running NSTimers is not one of the supported tasks.
I suggest you review the iOS Programming Guide and particularly the Background Execution and Multitasking section.

The instance of UILocalNotification fires the pop up box(and waken up your app) whenever it triggered as per the time you set, If you really chosen the UILocalNotification then Here are the good tutorial links discussed in S.O thread. Hope those will help you.

Related

Stop setKeepAliveTimeout handler from being called after application came foreground?

For VOIP application we are sending PING packet to server every 10 minutes using setKeepAliveTimeout, everything works fine, however I'm not sure how to stop the handler from being called once application came foreground.
eg: Here is how I set the timeout
[[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }];
Background handler:
- (void)backgroundHandler
{
printf("10 minute time elapsed\n");
// do some action...
}
Above function is being called even after application came foreground, I have read in Apple documentation to set the handler nil to stop it. I have tried like below in applicationWillEnterForeground
[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:nil];
Still I'm getting call every 10 mins. How to handle this, Do I need to use flag only.
Any help is really appreciated.
you can do it like this
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
[[UIApplication sharedApplication] clearKeepAliveTimeout];
}
You have to invoke clearKeepAliveTimeout to stop the timer. setKeepAliveTimeout: is designed to keep a voip connection on and that's why it's periodically called.

Whats the logic behind NSTimer when applicationDidEnterBackground [duplicate]

I don't understand it at all but NSTimer in my app definitely is running in background. I have a NSLog in method run by the timer and it is logging while it's in background. It's on iPhone 4 with iOS 4.2.1. I have declared location background support in Info.plist.
I read the docs and many discussions here and elsewhere and it shouldn't be possible. Is it an iOS bug? Or undocumented feature? I don't want to use it and find out in near future, for example with coming of iOS 4.3 that Apple silently "fixed" it and the app won't be working.
Does anybody know more about it?
NSTimer is going to fire whenever the main runloop is running. Apple makes no promises that I know of to unschedule timers or to prevent the main runloop from running. It's your responsibility to unschedule your timers and release resources when you move to the background. Apple isn't going to do it for you. They may, however, kill you for running when you are not supposed to or using too many seconds.
There are many holes in the system that will allow an app to run when it isn't authorized to. It would be very expensive for the OS to prevent this. But you cannot rely on it.
You can have a timer fire while in background execution mode. There are a couple of tricks:
You need to opt into background execution with beginBackgroundTaskWithExpirationHandler.
If you create the NSTimer on a background thread, you need to add it to the mainRunLoop manually.
- (void)viewDidLoad
{
// Avoid a retain cycle
__weak ViewController * weakSelf = self;
// Declare the start of a background task
// If you do not do this then the mainRunLoop will stop
// firing when the application enters the background
self.backgroundTaskIdentifier =
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundIdentifier];
}];
// Make sure you end the background task when you no longer need background execution:
// [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskIdentifier];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Since we are not on the main run loop this will NOT work:
[NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(timerDidFire:)
userInfo:nil
repeats:YES];
// This is because the |scheduledTimerWithTimeInterval| uses
// [NSRunLoop currentRunLoop] which will return a new background run loop
// which will not be currently running.
// Instead do this:
NSTimer * timer =
[NSTimer timerWithTimeInterval:0.5
target:weakSelf
selector:#selector(timerDidFire:)
userInfo:nil
repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:timer
forMode:NSDefaultRunLoopMode];
// or use |NSRunLoopCommonModes| if you want the timer to fire while scrolling
});
}
- (void) timerDidFire:(NSTimer *)timer
{
// This method might be called when the application is in the background.
// Ensure you do not do anything that will trigger the GPU (e.g. animations)
// See: http://developer.apple.com/library/ios/DOCUMENTATION/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW47
NSLog(#"Timer did fire");
}
Notes
Apps only get ~ 10 mins of background execution - after this the timer will stop firing.
As of iOS 7 when the device is locked it will suspend the foreground app almost instantly. The timer will not fire after an iOS 7 app is locked.

How to disable UILocalNotification in iPhone for some time?

I have implemented one reminder iphone applicaion in which I have used local notification for reminder.
In this application their one functionality alert on/off.
So when user set on then user get notification and if its off then user can get notification.
I have done googling but not got sucess.
Can you give me idea for that is it possible or not.
Thanks in advance
Do you have other notifications in your appln.
If you don't have other notification in your app than,
Do one thing,
When you set OFF
- cancel all the notification
- calculate the time difference of current time & your notification firing time. set this in to some variable.
when you set it ON
- reschedule your Notification based on the time which you have saved earlier.
I am considering that you know how UISwitch works, according to switch position
UILocalNotification *localNotif;
//if switch is on
localNotif = [[UILocalNotification alloc] init];
//else if localNotif is not equal to null then
localNotif = nil;
You can start a timer which continuously check switch position and do the above stuff that depends on your coding.

Objective-c Don't pause while entering in background

is it possible not to pause the application while in background mode (when you press the home button and the app minimizes)? I have some timers and variables that i don't want to get paused.
EDIT:
I have followed this example http://evilrockhopper.com/2010/01/iphone-development-keeping-the-ui-responsive-and-a-background-thread-pattern/
I have called a timer inside however it's not getting called when i enter background mode:
- (void)applicationDidEnterBackground:(UIApplication *)application {
if(self.viewController.timerquest != NULL)
{
if(self.viewController.timerquest.timerRunning){
// Save varibales
[self performSelectorInBackground:#selector(performLongTaskInBackground) withObject:nil];
}
}
}
- (void) performLongTaskInBackground
{
// Set up a pool for the background task.
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// perform some long task here, say fetching some data over the web.
//...
timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(updateTimer) userInfo:nil repeats:YES];
// Always update the components back on the main UI thread.
[self performSelectorOnMainThread:#selector(completeLongRunningTask) withObject:nil waitUntilDone:YES];
[pool release];
}
-(void) updateTimer{
// Update my timer. This method is not being called in background mode
}
What should I do?
Thanks.
use Long Running Background tasks according to manual: http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/BackgroundExecution/BackgroundExecution.html
Have a read here at the Apple non-technical documentation or at the technical reference.
Could you replace the timer with delayed background notifications?
Depending on what happens when your timers fire, you want to set up a local notification that fires at the same time the timer would have; this is useful when the timer would present something for the user to act on. As far as saving variables, you'll want to use -applicationDidEnterBackground: to save whatever state you need to, so that the correct variables can be loaded/generated when the app relaunches (which may not happen until the app has been exited and completely restarted again).
The types of tasks that are allowed to perform long running background tasks are pretty limited, specifically for things like GPS and playing audio. Everything else needs to decide on a task-by-task basis whether to simulate continued running (such as turning a timer to a local notification), pausing and saving necessary state to continue the next time the app is run, simply cancelling the task and gracefully restarting/notifying the user upon resuming the app, or asking for a finite length of time to finish a task (for things like finishing a download).

How to show a UILocalNotification when ASINetworkQueue finishes all requests?

I'm using ASIHTTPRequest to download multiple files while the iPhone app is running in the background. I want to present a UILocalNotification when the queue finishes.
The following delegate method isn't called until the app is resumed:
- (void)queueFinished:(ASINetworkQueue *)aQueue
{
NSLog(#"Queue finished");
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground) {
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = NSLocalizedString(#"All downloads completed");
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
[localNotification release];
}
}
So, how can I make this notification appear?
The reason your delegate isn't getting called is likely because your app is suspended in the background. If you are doing some sort of lengthy network process that continues after the user closes the app, you can use -[UIApplication beginBackgroundTaskWithExpirationHandler:] when you start the network tasks so that your application continues running in the background until you're done with the network tasks. However, it can still expire so you're not guaranteed to get enough time to finish.
From previous SO question notification when program is in background iOS 4
You do realize that when your app is in a suspended state, you won't receive any notifications -- and this is right in the documentation. There are only 3 classes of applications that can receive notifications: Audio applications (like iPod and analogues), location based applications, and voip apps. Your plist has to be set up correctly if your app is one of those applications.
Use this:
UILocalNotification *localNot = [[UILocalNotification alloc] init];
localNot.alertBody = #"Your Text";
localNot.alertAction = #"Name on the button";
localNot.fireDate = [NSDate date];
localNot.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNot];
What you're doing:
Create the LocalNotification
Add the body of your LN
Add the name of the button which appears on the "alert"
Set the fireDate to the actual date and time (maybe you need to increase the actual date with 1 or 2 seconds - for this use: dateByAddingTimeInterval:)
Set the soundName (you could also use a custom sound...)
Schedule / Create the LN
Do you have your queue maxConcurrentOperationCount set to 1?
The method setShouldContinueWhenAppEntersBackground:YES is set on a per request basis, and since you have a bunch of ASIHTTPRequest's inside a queue, only one of them may be executing at a time. This means that the other items in your queue haven't even started when you suspend the app, so the OS doesn't know yet to keep that network request alive.
I'm not sure of a solution, but I think this is the reason for what you're seeing.