For the sake of learning i'm making a timer. Used an NSTimer but it appears this stops
when going to the background.
Thought of using NSDate instead. Does this work in the background?
Do i compare current time to a set time to get the timer running properly?
Some thoughts would be greatly appreciated!
If you are looking for something to handle time based events in the background, have a look at UILocalNotification. With a local notification, the OS will alert the user at the appointed time whether the app that scheduled the notification is running or not.
If you are looking for something to happen when the app starts, you can use NSUserDefaults and store a value containing the current timestamp. Fire this off when in the AppDelegate inside applicationWillResignActive method. You can then check this value in the applicationDidBecomeActive.
Related
How would you go about implementing a "dayDidChange" method?
I have a dateLabel, that needs updating, when the day changes.
I already had 2 solutions implemented. But gave up on them.
1st, on viewWillAppear, I would set my label. Chances for date changing when the user is viewing the VC are VERY small ... and it wouldn't really introduce any "errors" to execution But still, it's not perfect.
2nd, I also implemented an NSTimer with intervals of 1 second. Works great. But I'm not too found of the idea of having a method being called if there is a chance that I don't need to do it.
Are there any other options? I need to update that label, when the day changes. Also, is it possible to use NSNotificationCenter with this?
In your appliciation delegate, implement the following method: -(void)applicationSignificantTimeChange:(UIApplication *)application
This method is called when the day changes, or if the device's time has been changed in the background for whatever reason (such as changes to time zone).
hope it helps. happy coding :)
You can calculate the time left on the day and set a timer to it. You can also listen to UIApplicationSignificantTimeChangeNotification. Note that this notification will be fired not only when the date changes, but for timezone adjustments and other changes. Keep in mind also that the firing of the notification will be triggered only if your app is not in an inactive state.
There are many ways to do so, and I can elaborate more on them if needed.
But here is a nice quick trick
use this code in your app delegate
it will listen to time changes (when the date or time changes dramatically) and when that happens - run a test and update the label if needed.
read me about this here: https://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIApplication_Class/Reference/Reference.html
It's just a quick simple way of doing it without timers.
- (void)applicationSignificantTimeChange:(UIApplication *)application {
NSLog(#"Time has changed, do a test and update the label if needed");
// [yourViewController runTimeTestAndUpdateFunction];
}
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.
I am wanting to create a timer or something of sorts to auto logout the user after x minutes of inactivity. I would like to do it the same way the Bank of America application does it. The way the BofA app does it is even when the application is put into the background it still keeps track of the time. When the time limit is reached a notification will popup stating you are being logged out.
How can this be done without the timer being suspended when the application goes into the background?
I think maybe the simplest thing you can do is register your AppDelegate with the NSNotificationCenter to listen for all events from all (or maybe specific) senders.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(resetTimer) name:nil object:nil];
You need to take care with passing nil to the name and object parameters as you will get a ton of notifications (even some not originating from the application, i.e., memory warnings). If you know of or have the list of specific event names and/or objects I would observe on those instead.
In your resetTimer method, you will simply invalidate the previous timer and create a new one that will call some logout method AND set an iVar to the current date/time (i.e., timerStart = [NSDate now];)
The above steps will take care of your app while it is in the foreground.
When the app is backgrounded, the timers will quit working. However, when the app returns to the foreground, you can calculate the delta between [NSDate now] and your timerStart iVar. If the delta is greater than some interval, you invoke your logout method. If not, you can just call resetTimer to start your timers again.
EDIT
If you want the backgrounded app to alert that the user is about to be logged out, you can use a UILocalNotification. You can schedule one to alert when the application enters the background. When the application enters the foreground, you can cancel that notification (and perform the steps I mention above).
I want a method to work in background until a duration specified by the user (let's say 20 minutes) elapses. I know it's not possible, because Apple allows the app to work for a maximum of 10 minutes in the background. Unfortunately FireDate works with UILocalNotifications only. I also read about performSelector:Selector:WithObject:afterDelay: method but I'm not sure if that will work in the background or not. Kindly give me suggesstions and code snippets (if any).
two methods that will be of use:
NSObject -(void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
UIApplication
- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void(^)(void))handler
local notifications can be used if you want the user to re-launch, but if they don't click through to the app, then your app never knows about it
I would like to write a counter that shows how many seconds an app has be running for. (textView) and the counter should be cumulative and starts from where it left off. Im new to iphone sdk.
you are going to have to do these things:
get the time when the app starts in applicationDidFinishLaunching: in your application delegate
check if you have an old time using NSUserDefaults
have a thread that updates the ui (your textView display, may i suggest using a label instead) with the ever increasing time using NSThread or NSTimer - i recommend NSThread. you will also need to perform your updates on your ui thread as updating your ui from a background thread can just get lost in the post.
store the end time in applicationWillTerminate: in your application delegate using NSUserDefaults
lots of googling ahead of you, have fun!