How to keep nstimer run in background? - ios7

I am using the bellow code but timer kill in background. but i want to keep running my nstimer in background-
NSTimeInterval time = 5;
self.locationUpdateTimer =
[NSTimer scheduledTimerWithTimeInterval:time
target:self
selector:#selector(updateLocation1)
userInfo:nil
repeats:NO];

You can get location events while the app is in the background, and here is Apple documentation that explains how to do that. And you probably also want to use something called "the Significant-Change Location Service".
And when the change happens, you'll get a call on your CoreLocation method "location manager: didUpdateLocations:". Sample code can be seen in the "Significant-Change Location Service" section.
Doing the above will be a lot easier to do than to try to implement a timer that runs while your application is in the background (and probably fully suspended, as many apps tend to be).
And if you didn't get a location update, that means your phone didn't move. :-)

Related

What's the best way to make a continuous loop to get information from iTunes?

I'd like to make a continuous loop to get information from iTunes to get stuff like: the player position (1:37), current track being played, etc... I'm using iTunes.h and ScriptingBridge to get the iTunes Data.
I have tried using [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(getInformation) userInfo:nil repeats:YES]; but from what I've seen on the Activity Monitor this consumes a lot of the CPU and if, for example, I press a button inside the NSWindow where I have the NSTimer, the UI of my App, that supposedly was going to be updated, is not updated. If I let go of the button the UI starts updating normally.
I have also tried using a while(1){} but for some reason my App freezes.
Does any1 have any idea on how to perform what I'm looking for?
that'll burn CPU like crazy.. dont poll!
sign up for the distributed notification:
//the distributed notification sent
#define SONG_CHANGE_NOTIFICATION #"com.apple.iTunes.playerInfo"
shameless advertisment: look at source of DDBoomBox on github which does EXACTLY what you wanna do :)
https://github.com/Daij-Djan/BoomBox

Set Up a Timer That Runs for the Life of an IOS App

I'm trying to figure out a way to have a timer that begins at the time that an app is installed and continues to run even when the app is in the background. I'm basically using the timer to periodically check the battery life of an external device that is linked to the phone. I've been told that the best way to do this is to use some sort of delegate calls to a timer function, but I'm fairly new to IOS and am pretty confused on how to do that. I know how to set up the timer and get the battery life, I'm however perplexed on how to keep the timer going through the life of the app. Any help you could give would be extreeemely appreciated! Thanks a bunch!
Running an app in the background (forever) isn't possible.
But while your app is running... you can set the repeats parameter of the method scheduledTimerWithInterval:target:selector:userInfo:repeats: to YES.
Here's a link to running it in the background for a certain period of time to perform a relatively large task.
run even when the app is in the background
Not possible. You can request an extra 10 minutes, but thats it. You will not be able to write your app as is.
For the timer part of your question, you can do this:
[NSTimer scheduledTimerWithTimeInterval:60.0
target:self
selector:#selector(checkBattery:)
userInfo:nil
repeats:YES];
But you should really be subscribing to the notifications on battery change events. Here is sample code from apple that shows how to do it.
coneybeare is right. This is iOS policy, which is in place exactly to prevent what you are trying to do, i.e. exhaust the iPhone's (or iPad's) battery life.

iphone - NSTimers in background

Im developing an app that has to run in the background. It's a location based app, so it runs all the time, the OS doesn't kill it.
It should send some info every 10 secs(just for debugging), I set a timer once its in the background. I set a breakpoint in the function that should be executed every 10 secs, which is never called, but if I pause the app and then continue the timer is called, and then the timer is executed every 10 secs without problems, weird right?
I thought that the timer would be executing anyway when I wasn't debugging, but it isn't, same thing as if I didn't pause the debugging.
My question is WHY?? The timer is set correctly(I assume) since it works after pausing, but it's not.
Any ideas?
The way I set the timer is:
self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(doStuff) userInfo:nil repeats:YES];
And in the function I connect to a webservice.
Thanks.
I have a similar app design and was stuck on the same thing. What I found somewhere on the internet is adding this type of statement applicationDidEnterBackground:
UIBackgroundTaskIdentifier locationUpdater =[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:locationUpdater];
locationUpdater=UIBackgroundTaskInvalid;
} ];
This tells the os that you still have things going and not to stop it.
I have my timer attached to this function
//this is a wrapper method to fit the required selector signature
- (void)timeIntervalEnded:(NSTimer*)timer {
[self writeToLog:[NSString stringWithFormat:#"Timer Ended On %#",[NSDate date]]];
[self startReadingLocation];
[timer invalidate];
timer=nil;
}
I set the timer in my my location manager delegate methods.
I feel your pain. I found that these things were super finicky. This is what worked for me. I hope it helps. I have found that there isn't any really restrictions in what you can do in the background.
There might be restrictions on what you can do in the background. Try adding the timer to the run loop before going into the background. Even that might not work; it may be that the only code of yours that can run in the background is the code called by the Core Location methods you've signed up for (e.g. locationManager:didUpdate...). But my impression is that timers already running before you start to go into the background will continue to run.

NSRunLoop freezes with NSTimer and any input

For some reason when I push down (click and hold) on any control, the NSTimer in my App freezes and does not fire until I release the mouse button. It simply does not fire while I have the mouse pressed. This is fine for short periods, but it also freezes if I have a popup menu open, or a combobox dropped down.
I'm not sure if there is something I missed, but it seems like this is incorrect behavior.
I want to be able to click the down arrow of an NSPopUpButtonCell (or even click and hold an NSTableView) without the entire NSTimer freezing (which redraws an NSView).
Any comments / suggestions would be appreciated.
The NSTimer is added to the currentRunLoop with mode NSDefaultRunLoopMode.
While the mouse is down, the run loop is in the NSEventTrackingRunLoopMode. Therefore, any event that's not received onto the EventTracking event queue won't be serviced until the runloop returns to the appropriate mode.
The way around this is to add the timer to the runloop for both modes (default and event tracking).
Instead of adding two or more timers to different runloops or using multithreading (as you won't then be able to update the UI from another thread) simply add the timer to the NSRunLoopCommonModes:
NSTimer *myTimer = [NSTimer timerWithTimeInterval:RefreshInterval target:self selector:#selector(doWork) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSRunLoopCommonModes];
Assuming you're just dealing with one thread in your application, what you described is perfectly expected. By default, NSTimer's are added to the current NSRunLoop which, in your case, is also responsible for dealing with UI interaction. When it gets tied up with handling UI interaction, it can't check your timer and "fire" it.
A solution is to use multi-threading so as to avoid this tie-up. Here's a nice blog post on this very subject: http://blog.narent.com/?p=21
EDIT: See Dave's post for an alternative (and more elegant IMO) solution
Also see:
NSTimer doc
NSRunLoop doc
Threading programming guide

NSTimer: Getting firing to NOT act retroactively

I'm currently using the snippet of code presented below to fire some methods every second. My app is running in the background. The problem is that if the computer wakes up after a sleep period the timer wants to retroactively fire all the methods it has missed. Similar issues come up if the user were to change the System Clock time.
Basically I want to implement the proper timer method that will have my methods called only every current second. If a second (or minute or hour or day) has passed and for whatever reason the methods weren't called I want my app to just continue from the current moment in time.
Also, can we keep this while using NSTimer?
Thanks!
-(void)start
{
NSTimer * timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:#selector(tasks:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode: NSDefaultRunLoopMode];
}
To handle the big time changes you can use the link UIApplicationSignificantTimeChangeNotification and unregister/reregister your timer.
To deal with the sleep issue, you can unregister and then reregister your timer whenever the machine goes to sleep and wakes up. See this technical note for information on how to do that. This solution won't work for changing the system time, though.