I know how to set a timer and when timer expires, it fires and a action is caught.
What I'm expecting is that after 30 seconds of every one hour of real time that that "xx:00:30" I have to check my server for updates.
I know how to communicate with server. But how can I create such a timer that fires every "xx:00:30".
I don't want to run the timer if the app is in background.
Any ideas on how to do this?
As mentioned by Marcus in his last message,
NSTimer's initWithFireDate:interval:target:selector:userInfo:repeats: or setFireDate:
works.
Related
My flutter app allows users to time how long they have been working for. I'm using the package stop_watch_timer.
Everything works fine except when the app gets killed in the background, because then I lose the timer value and it goes back to 0. As users are likely to start the timer then put their phone away and work for a while, the app getting killed is a very likely scenario and I need to make sure that this never happens. Another feature that I need in the app is for users to be able to pause and unpause the timer whenever they want.
Here are the solutions I have come up with so far and their problems:
Solution 1: Store the start DateTime on the phone using shared_preferences and calculate the current timer value when app is reopened by simply calculating the duration between start time and DateTime.now(). But then I realised that this does not work if the user had paused and unpaused the timer at some point.
Solution 2: Store the current timer value as a RestorableInt. This works if the timer is on pause when the app gets killed, but does not work if the timer is meant to be running when the app dies.
Any suggestions or ideas??
You should store something like this:
[
{"start":1664027960},
{"pause":1664027975},
{"unpause":1664027979},
{"pause":1664028061},
{"unpause":1664028065},
]
Everytime a user hits the pause button you add the time to the list and store it in the shared_prefs or in a json file. Same for unpausing.
You can then calculate the total ellapsed time.
I have implemented a Timer as detailed in the article below, so that the timer will keep running when i change tabs.
How to implement persistent stopwatch in Flutter?
I have an issue where the Timer "loses" or pauses time, only when not plugged into my computer. When i plug it into my computer, no issues, the emulator runs fine too. I test the flutter timer against a timer on my computer or phone, and after 5mins, they match. But when my phone (Galaxy S9) isn't plugged in, after 5mins of real time, the flutter timer might only be up to 2mins, when i go back into the app the timer is running but the timer wont be what it should be. It doesn't crash or reset, its counting when i get back into the app. I'm finding it hard to debug as when I plug the phone into my computer it seems to work fine! Any ideas?
I had issues with this as well. Things working correctly when running on the Simulator is fools gold. The Timer won't run in the background like you want it to unless you do specific work to keep it running. Here is the official page from Flutter on doing work in the background: https://flutter.dev/docs/development/packages-and-plugins/background-processes
I'll suggest implementing didChangeAppLifecycleState method of the WidgetsBindingObserver and detect when the app goes to the background and when it's back in the foreground. At the point where the app goes into the background, you save the current time e.g (onPauseTime) (you can use SharedPreferences here) and the Duration left on the timer (timerDurationLeft).
When the app is back in the foreground you check if the timer was running before the app entered the background state, if it was, you then check the current time e.g (onResumeTime) and calculate the time difference in seconds (onResumeTime - onPauseTime), using the time difference and the timerDurationLeft you can calculate how much time the timer has left to run and you start/resume the timer from that point or end/set the timer to 0:00 if time has already passed.
P:S Using a background service would be the way to go if you intend to perform some actions in the middle, like set notifications at some point where the timer is almost complete.
I have found the answer for this in iPhone: Detecting user inactivity/idle time since last screen touch but what happens when the device gets into inactive/sleep state? The timer stops firing right?
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nstimer_Class/Reference/NSTimer.html
A timer is not a real-time mechanism; it fires only when one of the run loop modes to which the timer has been added is running and able to check if the timer’s firing time has passed. Because of the various input sources a typical run loop manages, the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds. If a timer’s firing time occurs during a long callout or while the run loop is in a mode that is not monitoring the timer, the timer does not fire until the next time the run loop checks the timer. Therefore, the actual time at which the timer fires potentially can be a significant period of time after the scheduled firing time.
So, when your app will go to an inactive state - the timer will stop firing. And when your app will go back to an active state - the timer will resume firing again.
If I register a NSLocalNotification to a past time,wheather it will destory automaticly,or it take one schedule count in the system and never destory.
As though,we know the loacalNotification is limit to the 64 counts,when the notification register to the past time got to the 64 counts.The other lotification Whether happend or not
If you create a notification in the past time .. it will play right then.. and your app delegate's didRecieveNotification method is called.
I have created an app that uses NSTimer, which gets triggered each second.
My problem is that if the Iphone is in sleep mode i get a delay for 10 to 15
minutes before the event is triggered. I have stackoverflowed and googled this
and the reason for this seems to be that the phone stops listening for certain
events when in sleep mode.
Some people have solved this issue by playing a mute sound, not allowing the
phone to sleep.
What could be the reason for the delay?
The mute sound solution seems to be a very "dirty" one. Is there some other way to solve this?
If I use the mute sound solution will it the pass the apple review?
Code:
timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:#selector(goAction)userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
-(void)goAction {
// Here i check for some dates and then call the activateBeepAlarmView
}
Well since no one has answered my three questions I will have to answer them:
1. What could be the reason for the delay?
I will have to quote Ben S:
Once applicationWillResignActive gets called on your application you simply stop receiving events:
The delegate can implement this method to make adjustments when the application transitions from an active state to an inactive state. When an application is inactive, it is executing but is not dispatching incoming events. This occurs when an overlay window pops up or when the device is locked.
The point of sleep mode is to save energy. To do so, the device stops listening for events like the ones you're asking for. NSTimer events will still fire since they don't require expensive (battery-wise) hardware monitoring. Also, alarms are implemented using NSTimer, so they need to be able to function even when in sleep. Otherwise, people might not wake up and blame their iPhone.
2. The mute sound solution seems to be a very "dirty" one. Is there some other way to solve this?
No, currently I haven't found another solution, please feel free to correct me if I'm wrong.
Check out this blog post how to do it.
3. If I use the mute sound solution will it the pass the apple review?
Yes
When the iPhone goes to sleep, so does your app and the runloop that runs the NSTimer.
You seem to think that an NSTimer is some sort of hardware based timer. It is not. It operates completely within the software of the app that launches it. I don't know what is waking your app up but it is definitely not the NSTimer.
In short, what you want to do is impossible. You can't sleep the phone and then have an app still active and running. The mute sound technique is just a kludge to keep the phone awake and the app running.
If you need the phone to stay awake, you need to set the application's idleTimerDisabled to YES. This will prevent the phone from sleeping and the app can remain active. But once you let the phone sleep, it cannot be awaken from app code. Only the hardware can do that in response to an alarm or an incoming message.
What happens in your app when the NSTimer is triggered each second? Please provide code showing the creation of the timer as well as the code for the selector that is called when the timer completes.
Also what do you mean by a "delay for 10 to 15 minutes"? Is the delay always that long or is that how long you wait to awaken the iPhone and then the event is triggered?
Depending on what you need to do every second you can handle this situation in different ways. Please respond and we'll try to work our way through this.
Bart
#Jakob,
This is impossible with the "Official SDK". If you're developing apps for jail broken phone, then you can use IOKit framework for this. For more info please refer this.