My app detect the audio at particular intervel like 10:00AM(startTime) -10:30AM(endTime),etc.Now when the current time reaches start time(means current time is also 10:00 AM) how to call audio detection process and stop detection process at (endTime)10:30 AM . suppose another interval start at 10:15AM(startTime) - 10:45 AM(endTime) how to update endTime from 10:30AM to 10:45AM.how to check when current time reaches startTime and endTime.Please help me its urgent.Thanks here my code is
ViewController.h
#interface ViewController : UIViewController
{
BOOL IsListening;
}
//session array is array of dictionaries contains program start and end time.
ViewController.m
-(void)viewDidLoad
{
[super viewDidLoad];
NSTimer* listener_timer = [NSTimer scheduledTimerWithTimeInterval: 10.0 target: self
selector: #selector(listeningHandler:) userInfo: nil repeats: YES];
}
-(void)listeningHandler:(NSTimer*)time
{
if (!IsListening)
{
double currentTime=[[NSDate date] timeIntervalSince1970];
for (NSDictionary * session in SessionsArray)
{
double startTime=[[session objectForKey:#“startTime”] doubleValue];
double endTime=[[session objectForKey:#“endTime”] doubleValue];
if (currentTime > startTime && currentTime < endTime)
{
//start listening.
IsListening =YES;
/*
//detection process code
*/
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:endTime];
NSTimer *timer = [[NSTimer alloc] initWithFireDate:fireDate
interval:5
target:nil
selector:#selector(fireEndtimeAlarm)
userInfo:nil
repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
}
}
}
else
{
double currentTime=[[NSDate date] timeIntervalSince1970];
for (NSDictionary * session in SessionsArray)
{
double startTime=[[session objectForKey:#"startTime"] doubleValue];
double endTime=[[session objectForKey:#"endTime”] doubleValue];
if (currentTime > startTime && currentTime < endTime)
{
// in between session
IsListening =YES;
/*
//detection process code
*/
}
}
}
}
-(void)fireEndtimeAlarm
{
IsListening = NO;
//stop detecting process at endTime
}
Start Timer & Stop Timer in ios
start Timer
timer= [NSTimer scheduledTimerWithTimeInterval:60.0f
target: self
selector: #selector(methodFromTimer)
userInfo: nil
repeats: YES];
stop timer
[timer invalidate];
timer=nil;
You can achieve this using 2 Local notifications
First of All schedule a specific notification at a specific time when time is reached then a trigger will run and at that time Start audio and
Schedule a second notification after 30 min when that will be fired then stop audio
For local notifications you can follow these
Link1
Link2
Related
I'm working on a simple radio alarm clock app for a non-mainstream stream I'd like to wake up to. It uses the opting out of background trick to stay running when the phone is locked, similar to Rise/Sleepcycle.
Originally the alarm wouldn't fire the next day if I was to set the alarm before midnight but would always fire pretty much on the turn of the minute if set ahead of the current time but before 00:00
So I've made some adjustments so that the date is also checked. I also included conditions so that it's impossible to set a time before the current time. Now while this takes care of the next day issue, I'm finding the fire itself is temperamental. Sometimes it works perfectly, sometimes there is a huge delay (up to 10 minutes in cases) sometimes it never fires at all. I really cannot figure out for the life of me why this happens.
Below is my code. Does anyone have any ideas as to why it's not consistent?
- (void)viewDidLoad {
[super viewDidLoad];
radio = [[Radio alloc] initWithUserAgent:#"my app"];
[radio connect:STREAM_URL withDelegate:self withGain:(1.0)];
// dateTimePicker.date = [NSDate date];
dateTimePicker.date =
[[ NSDate alloc ] initWithTimeIntervalSinceNow: (NSTimeInterval) 2];
dateTimePicker.minimumDate =
[[ NSDate alloc ] initWithTimeIntervalSinceNow: (NSTimeInterval) 0 ];
}
-(void) presentMessage:(NSString *)message {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Radio Alarm" message: message delegate:nil cancelButtonTitle:#"Ok" otherButtonTitles: nil];
[alert show];
}
- (IBAction)alarmSetButtonTapped:(id)sender {
NSLog( #"Alarm Set Button Tapped");
NSDateFormatter * dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterShortStyle;
NSString * dateTimeString = [dateFormatter stringFromDate: dateTimePicker.date];
NSLog( #"Alarm Set Button Tapped : %#", dateTimeString);
[self presentMessage:[NSString stringWithFormat:#"Alarm set for %#", dateTimeString]];
NSDate *alarmFireDate = dateTimePicker.date;
NSTimeInterval differenceFromNow = [alarmFireDate timeIntervalSinceNow];
//[alarmFireDate performSelector:#selector(PlayAlarm:) withObject:nil afterDelay:differenceFromNow];
[self performSelector:#selector(PlayAlarm:)
withObject:(self)
afterDelay:(differenceFromNow)];
you can use
[NSTimer scheduledTimerWithTimeInterval:differenceFromNow
target:self
selector:#selector(PlayAlarm:)
userInfo:nil
repeats:NO];
This timer is quite accurate.
If you need to abort the timer, just save the returned NSTimer* from this in a property and call
[myTimer invalidate];
I have a timer to a date counting down in my today widget. I am gathering the date from my View Controller and then starting a timer in the extension and from there I am displaying the dates in three labels, Hours, Minutes, and Seconds. In my app... this is perfect, but not so true in the notification center. The countdown loads correctly and works great for about 20 seconds. After that it skips a second and freezes, then it starts again in about 4 seconds and then it will reset the whole widget (everything disappears) and then about 2 seconds later the whole widget resets. Is this a memory warning or something?
View Controller:
mainTextLabel.text = 436496400
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.nicmac.nextgame"];
[sharedDefaults setObject:mainTextLabel.text forKey:#"MyNumberKey"];
[sharedDefaults synchronize];
Today View Controller
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder:aDecoder]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:nil];
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.preferredContentSize = CGSizeMake(320, 300);
[self performSelector:#selector(updateNumberLabelText) withObject:nil afterDelay:1.0];
}
- (void)userDefaultsDidChange:(NSNotification *)notification {
[self performSelector:#selector(updateNumberLabelText) withObject:nil afterDelay:1.0];
}
- (void)updateNumberLabelText {
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:#"group.nicmac.nextgame"];
NSString *date = [defaults stringForKey:#"MyNumberKey"];
self.numberLabel.text = [NSString stringWithFormat:#"%#", date];
NSString *doubleString = self.numberLabel.text;
double value = [doubleString doubleValue];
destinationDate = [NSDate dateWithTimeIntervalSince1970:value];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateNumberLabelText) userInfo:nil repeats:YES];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
int units = NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *components = [calendar components:units fromDate:[NSDate date] toDate:destinationDate options:0];
[hour setText:[NSString stringWithFormat:#"%ld", (long)[components day] * 24 + (long)[components hour]]];
[minute setText:[NSString stringWithFormat:#"%ld", (long)[components minute]]];
[second setText:[NSString stringWithFormat:#"%ld", (long)[components second]]];
}
Thanks!
The problem here lies in the - (void)updateNumberLabelText method.
Specifically, here:
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateNumberLabelText) userInfo:nil repeats:YES];
This means that every time you're calling this method, it's scheduling another timer to call this method every second (every second because repeats:YES). That means, every second (with a micro offset because of any lag in the computer), x number of scheduled timers is producing x MORE number of scheduled timers, meaning that every second you have double the number of timers. This is called exponential growth, and can be modelled to 2^x.
So to find the number of timers in 20 seconds:
2^1+2^2+2^3+2^4+2^5+2^6+2^7+2^8+2^9+2^10+2^11+2^12+2^13+2^14+2^15+2^16+2^17+2^18+2^19+2^20
Ew, can we represent this better - we can! We can use sigma notation like so:
<no. of seconds>
Σ 2^i
i=1
But enough math. That averages out to around a whopping 2,000,000 timers initialised in 20 seconds. That is a lot of timers, and the widget eventually struggles to catch breath (no more memory!) and dies/crashes/restarts itself.
Here's how to fix it:
If you really want this method to loop itself, call
[self performSelector:#selector(updateNumberLabelText) withObject:nil afterDelay:1.0];
in the method instead.
You could do it the way you're currently doing it and do repeats:NO instead, but I don't think that the timer will invalidate itself after the 1.0 second, and creating that many timers is not very efficient.
Hi Friends i need count down timer for add lives every 30 minutes. So i created a count down timer but it is running on that call only. Here i need the timer run globally. If aplication in back ground or termnate any body help me.
This is my code
int hours, minutes, seconds;
NSTimer *timer;
- (void)updateCounter:(NSTimer *)theTimer {
if(secondsLeft > 0 ){
secondsLeft -- ;
// hours = secondsLeft / 3600;
minutes = (secondsLeft % 3600) / 60;
seconds = (secondsLeft %3600) % 60;
// myCounterLabel.text = [NSString stringWithFormat:#"%02d:%02d:%02d", hours, minutes, seconds];
[self removeChild:Liveslable];
Liveslable=[CCLabelTTF labelWithString:[NSString stringWithFormat:#"lives left in %02d:%02d minuts",minutes, seconds] fontName:#"ArialMT" fontSize:25];
Liveslable.position=ccp(winSize.width/2, winSize.height/2-140);
[self addChild:Liveslable];
}
else{
secondsLeft = 1800;
}
}
-(void)countdownTimer{
secondsLeft = hours = minutes = seconds = 0;
if([timer isValid])
{
[timer release];
}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:#selector(updateCounter:) userInfo:nil repeats:YES];
[pool release];
}
It is not appropriate to use the NSTimer in this case. You cannot execute code in the background, with good reason (imagine if the user quits the process, or turns the device off). Instead you should look into storing the timestamp at which a life has been given and then calculate the timestamp for when the next life should be given.
You can save the time to NSUserDefaults like this:
float timeStamp = [[NSDate date] timeIntervalSince1970] * 1000; // Milliseconds
[[NSUserDefaults standardUserDefaults] setFloat:timeStamp forKey:#"lastTimeStamp"];
And retrieve the previous timestamp like this:
float lastTime = [[NSUserDefaults standardUserDefaults] floatForKey:#"lastTimeStamp"];
Whenever the user opens the application you should perform your calculations and give lives accordingly. This can be done in applicationWillEnterForeground: in the AppDelegate.m
You can use your NSTimer to check if the next timestamp matches the NSDate-time while the app is running.
How do I have an NSTimer with a UIButton that changes its text from Start to Stop, Also another UIButton will be added to pause the timer. So, You press start and then the timer will show in a label in hours, minutes and seconds. While the timer is running, is there a way to pause the timer ( I heard you have to use NSUserDefaults). Also is there a way to save the time at which the start button was pressed and then to save the time that the button was pressed again to stop? Also when the pause button is pressed to pause the timer and when pause is pressed again it will resume the timer?
If you need a timer that doesn't support pausing, you only need to know the NSDate at which the timer started so that you can calculate the time elapsed. Create an instance variable:
#property (strong, nonatomic) NSDate *timerStartDate;
When the button is tapped:
- (void)startTimer
{
self.timerStartDate = [NSDate date];
}
Your NSTimer is not to keep track of the time, but to periodically update the label. Create an instance variable:
#property (strong, nonatomic) NSTimer *labelUpdateTimer;
and update the -startTimer method:
- (void)startTimer
{
self.timerStartDate = [NSDate date];
// start timer to update label
if (!self.labelUpdateTimer) {
self.labelUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(updateLabel)
userInfo:nil
repeats:YES];
}
}
- (void)updateLabel
{
NSTimeInterval secondsElapsedSinceTimerStart = 0;
if (self.timerStartDate) {
secondsElapsedSinceTimerStart = [[NSDate date] timeIntervalSinceDate:self.timerStartDate];
}
NSString *formattedTime = <format time elapsed the way you like>;
self.label.text = formattedTime;
}
- (void)dealloc
{
// make sure timer is not firing anymore!
if (_labelUpdateTimer) {
[_labelUpdateTimer invalidate];
_labelUpdateTimer = nil;
}
}
However, if you want to be able to pause the timer, besides calculating the time elapsed since the timer last started, you'll need to store the time previously elapsed (if you started/paused the timer before). Create an instance variable:
#property (nonatomic) NSTimeInterval previouslyElapsedSeconds;
And when you pause the timer:
- (void)pauseTimer
{
// update elapsedSeconds
if (self.timerStartDate) {
self.previouslyElapsedSeconds += [[NSDate date] timeIntervalSinceDate:self.timerStartDate];
self.timerStartDate = nil;
}
[self.labelUpdateTimer invalidate];
self.labelUpdateTimer = nil;
}
Update -updateLabel:
- (void)updateLabel
{
NSTimeInterval secondsElapsedSinceTimerStart = 0;
if (self.timerStartDate) {
secondsElapsedSinceTimerStart = [[NSDate date] timeIntervalSinceDate:self.timerStartDate];
}
// account for previously elapsed time
NSTimeInterval totalSecondsElapsed = self.previouslyElapsedSeconds + secondsElapsedSinceTimerStart;
NSString *formattedTime = <format time elapsed the way you like>;
self.label.text = formattedTime;
}
NSUserDefaults will be required only if you want to keep timing even if the app is shut down (not just backgrounded). In that case store previouslyElapsedSeconds and timerStartDate in NSUserDefaults instead of as instance variables.
assuming you have NSDate objects startTime and stopTime
[[NSUserDefaults standardUserDefaults] setObject:startTime forKey:#"startTime"];
[[NSUserDefaults standardUserDefaults] setObject:stopTime forKey:#"stopTime"];
Or you can use floats startTimef and stopTimef
[[NSUserDefaults standardUserDefaults] setFloat:startTimef forKey:#"startTime"];
[[NSUserDefaults standardUserDefaults] setFloat:stopTimef forKey:#"stopTime"];
Check out the NSUserDefaults docs.
Here's a great set of tutorials.
I have this code for a repeated timer in my app:
(inside viewDidAppear)
NSDate *date = [NSDate dateWithTimeIntervalSinceNow: 3];
NSTimer *restrictionTimer = [[NSTimer alloc] initWithFireDate: date
interval: 3
target: self
selector:#selector(changeRestriction)
userInfo:nil repeats:YES];
and
- (void) changeRestriction
{
NSLog(#"inside !!");
}
However, I dont see any output, any help ?
If you're using -initWithFireDate:.. you have to manually add the timer to the NSRunLoop. However you could just use +scheduledTimerWithTimeInterval:.. and it will automatically trigger.