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

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.

Related

NSTimer perfomance of device

I want to run a timer that watches my game for some events that occur during the gameplay.
I would include the timer in the did load function. So the Timer is checking permanently if event1 happened or not.
[NSTimer scheduledTimerWithTimeInterval:0.001
target:self
selector:#selector(check_status_event1:)
userInfo:nil
repeats:YES];
I also try to set a pointer to the Timer to invalidate when needed.
- (IBAction)check_status_event1:(id)sender
{
//_stepper_event1_status_check.value (0 = no / 1 = yes)
if (_stepper_event1_status_check.value == 1) {
_stepper_event1_status_check.value = 0; //reset stepper again
[self event1_go:0];
}else{}
}
Question:
Is the interval of 0.001 o.k?
Is there a big influence to the device performance? Because there is permanently running an if statement (or more). Does it maybe also make the iPhone or iPad slower, when the game is sent to background via home button?
Can I use more of this timer at the same time? for example when I run 10 or 20 of them.
Is this the normal way to catch an event that occur during the game? For example a colidation of 2 objects. I also set some code with a timer after 1 sec (step1). after 2 sec (step2). after 3 sec (step3).... when I use such a timer, I can start the next step exactly at this time, when the step before has done. Maybe one step needs more then 1 sec. And I don't want to use animateWithDuration and Delay. And maybe an iPad 2 is slower in processing and reading the whole code as an iPad 4. And I don't want to start with step 2 when step 1 has not finished.
But what is about the performance of the iOS device. Is this a problem?
thank you
Philipp
Is the interval of 0.001 o.k?
Probably not. "The effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds". You may set it to 0.001 but you are unlikely to get your timer on time.
Does it maybe also make the iPhone or iPad slower, when the game is sent to background
No it won't slow down the device when in background. iOS stops timers when app is in background.
Can I use more of this timer at the same time? for example when I run 10 or 20 of them.
Yes you can, but you may find a better solution.
I don't want to use animateWithDuration and Delay.
That will make your life easier. iOS goes into extends to make your animation smooth even if the device is under load.
Is this the normal way to catch an event that occur during the game?
No, unless your game doesn't update much, e.g. a turn-base game with no animation. Delivery time of timer event is not guaranteed. It may slip significantly. You would want to update you game state smoothly on every iteration, which is normally a frame. Do you have a frame update loop in your game? That would be the place to check for collisions and count time if needs be.
You are talking about noticing an event. A better design would be to use "push" rather than "pull". When an event happens it notifies all parties interested, not vice versa.

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

Timer that works in the background

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.

iPad app freezes during NSOperationQueue

I have a problem with an app where I implemented an NSOperationQueue.
It seems that pressing the close button of the iPad makes the UI freeze. The app itself is still running in the background, the UI is updated, it's just that it won't answer to touches or rotation anymore and it doesn't get closed as it should be.
I have an update module that downloads quite a long list of xml files and saves them on the device. The operation queue has a MaxConcurentOperations value of 2.
Usually everything works fine, the app runs fine and dandy, responding to my touches and rotation UNTIL I press the device's button. After this, the UI simply freezes. The progress is still updated (an UILabel), recurrent animations are still displayed, but the app is not closed until all the operations are done.
I'm not calling waitUntilAllOperationsAreFinished on my queue so I don't know what might be causing this.. So far, I've only made tests on a first generation iPad, with iOs 5.0
If anyone can provide me with some tips, I'll really appreciate it. If necessary, I can post the NSOperationQueue and NSOperation class codes, but somehow I have the feeling this about me approaching this wrongly, and not about a faulty line of code
[edit]
I also use a timer to periodically check on the download status, but I noticed that not calling the timer doesn't eliminate the problem
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(xmlDownloaded) userInfo:nil repeats:YES];
[edit2]
After some further research, I made sure that my operations are concurrent and just to be sure, I changed the way I added my operations to the queue.
Instead of
[downloadQueue addOperation:op];
I added them to a mutable array called "operations" and in the end I used
[downloadQueue addOperations:operations waitUntilFinished:NO];
but my app still freezes when I press the close button...
Wild guess, you are locking the main thread waiting for your operation to complete / you are destroying your operation delegate on viewWillDisappear?
It seems there was another function causing this, even though I don't understand why...
I had a label animation
CABasicAnimation *fadey = [CABasicAnimation animationWithKeyPath:#"opacity"];
[fadey setToValue:[NSNumber numberWithFloat:0.35f]];
fadey.repeatCount = HUGE_VALF;
[fadey setAutoreverses:YES];
[fadey setDuration:0.6f];
This small function was causing the app to wait until all the operations were finished in order to close the app. The weird part is that the function was not even called in with the NSOperations, but before them
Again, I have no idea why... everything breaks when I press the close button, otherwise there are no problem. So if anyone else runs into a similar issue, it might help to check for some repeating animations

Show app running time in iPhone

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!