IOS - Creating & Using Interval Specific Timers - ios

I am a newbie IOS developer, but I have a good amount of experience in Android development. My question is regarding the creating and use of interval specific timers.
In android I could easily make a timer like this:
timedTimer = new Timer();
timedTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
TimedMethod();
}
}, 0, 1000);
Where the interval is 1000 MS and the method TimedMethod() is called on every tick. How would I go about implementing a similar function in IOS?
Thanks so much for reading! Any help at all would be great! :-)

You can use a repeating NSTimer like so:
- (void) startTimer {
[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:#selector(tick:)
userInfo:nil
repeats:YES];
}
- (void) tick:(NSTimer *) timer {
//do something here..
}

Use
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(timerCallback) userInfo:nil repeats:YES];
In the same class as you called the above method, create a method called timerCallback. This will be called every time your timer fires; every 1000 milliseconds.

Use below method present in NSTimer.h file of Foundation Framework
Syntax :
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;
Usage :
#define kSyncTimerLength 4 //Declare globally
-(void) timerActivityFunction; //Declare in interface
[NSTimer scheduledTimerWithTimeInterval:kSyncTimerLength target:self
selector:#selector(timerActivityFunction) userInfo:nil repeats:NO];
-(void) timerActivityFunction {
// perform timer task over-here
}

For Swift:
Create a timer object using below line which will call upload method every 10 second. If you get does not implement methodSignatureForSelector extend your class with NSObject. Read this for more information Object X of class Y does not implement methodSignatureForSelector in Swift
timer = NSTimer.scheduledTimerWithTimeInterval(10.0, target: self, selector: "upload", userInfo: nil, repeats: true)
func upload() {
print("hi")
}

Related

Is this correct for a NSTimer to get run on the main thread?

Hello I wanted to run a NSTimer on the main thread im not sure if they are run on the main thread by default or I have to do a special implementation ? thanks to anyone who could help
#interface RootViewController : UIViewController {
NSTimer *minutePassed;
}
- (void)adViewDidLoad
{
minutePassed = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:#selector(callMinutedPassed) userInfo:nil repeats:NO];
}
-(void)callMinutePassed
{
NSLog("Minute Passed");
}
Documentation for scheduledTimer(timeInterval:target:selector:userInfo:repeats) states Creates a timer and schedules it on the current run loop in the default mode.. That means in your instance, that it is running on the main thread. I'm assuming when you say -(void)adViewDidLoad you mean -(void)viewDidLoad().

Why isn't my NSTimer calling my method upon expiration?

I am using an NSTimer to call a method which is titled Lose. I had a timer which when it ran out, it called Lose, but I lost everything due to a hard drive error. After trying to code it all again, I can't seem to get the method to be called.
Timer = [NSTimer timerWithTimeInterval:timeMax target:self selector:#selector(Lose) userInfo:nil repeats:NO];
Lose is declared in my .h file, like this:
-(void)Lose;
Also, my method looks like this:
-(void)Lose{
Text.hidden = NO;
scoreLabel.hidden = NO;
Target.hidden = YES;
Targetx.hidden = YES;
if (Score > highScoreNumber) {
highScoreAchieved.hidden = NO;
highScoreNumber = Score;
}
}
The variable timeMax is an int declared in my .h file, like last time.
whenever a target is tapped in my game, timeMax becomes .03 seconds shorter. I do it like this:
timeMax = 5 - (Score * 0.03);
I don't remember it looking different before the massive hardware failure, but why isnt it working?
You have to schedule the timer on a run loop or just use this line instead which schedules it for you:
Timer = [NSTimer scheduledTimerWithTimeInterval:timeMax
target:self
selector:#selector(Lose)
userInfo:nil
repeats:NO];
It's also a good idea to always back up your code...which reminds me.

Issue while using 2 NSTimers

I am working on an iOS app which provides/makes calls from app. We can make two calls one after another. First time we are making 1st call. Once call get established, the NSTimer should be fired and it would show the duration of the call.
For this I am doing following for timer
self.switchTimer1 = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(setTimerLabel1:)
userInfo:nil
repeats:YES];
[self.switchTimer1 fire];
after establishing this first call, user can make second call.
Once second call gets established, it would fire second timer.
if (hasSecondCall)
{
self.switchTimer2 = [NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(setTimerLabel2:)
userInfo:nil
repeats:YES];
timeSec=0;
timeMin=0;
[self.switchTimer2 fire];
}
It's working fine while making first time of both calls.
Suppose if I ended 2nd call and again I made call, that time 2nd timer before establishing the call the timer automatically calling and once call established, the timer incrementing value very fast like double values showing. Like, 2,4, 6, etc.
For secondtimer after firing method following
- (void)setTimerLabel2:(NSTimer *)timer {
timeSec=timeSec+1;
NSLog(#"timeSec+1 %d",timeSec+1);
if (timeSec == 60)
{
timeSec = 0;
timeMin=timeMin+1;
}
NSString* timeNow = [NSString stringWithFormat:#"%02d:%02d", timeMin, timeSec];
[_switchCallLCD setStatus:timeNow labelNumber:2];
}
While disconnecting call we calling following
- (void)endingCallWithId:(UInt32)call_id {
if (hasSecondCall&& call_id==_current_call) {
if (self.switchTimer2) {
//NSLog(#"self.predictNumber %#",self.predictNumber);
self.predictNumber=self.predictNumber2;
[_lcd setText:self.predictNumber];
[self.switchTimer2 invalidate];
self.switchTimer2 = nil;
[self.switchTimer2 release];
[_switchCallLCD setStatus:NSLocalizedString(#"call ended",nil) labelNumber:2];
timeSec = 0;
timeMin = 0;
}
I have searched so many forums regarding this issue, but I couldn't figure out solution. I heard, if we use multiple timers there is some issue like this.
You likely still have the previous instance of the timer(s) running. When you make a second set of calls you then have 2 instances of switchTimer1 running and 2 instances of switchTimer2 running.
As soon as you end a call, you need to invalidate the timer:
[self.switchTimer1 invalidate];
and then set it to nil for good measure:
self.switchTimer1 = nil;

Call an action at specific intervals in iOS

I am trying to invoke a function that contains ccactioninterval in Cocos3d. I want to call that function at specific time intervals.When I tried NSTimer , i found that it works sometimes and sometimes not.
NSTimer makeTarget=[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(createTargets) userInfo:nil repeats:YES];
Here createTargets is the function that contains action events. when i run the function straightit works fine for single time. Problem comes when i try to schedule it. I ve tried different methods already explained for related questions . But nothing worked for me. . . .
Here is the code
-(void) addTargets {
NSTimer *makeTarget = [NSTimer scheduledTimerWithTimeInterval:2.0
target:self selector:#selector(createTargets) userInfo:nil repeats:YES];
}
-(void)createTargets {
CC3MeshNode *target = (CC3MeshNode*)[self getNodeNamed: #"obj1"];
int minVal=-5;
int maxVal=5;
float avgVal;
avgVal = maxVal- minVal;
float Value = ((float)arc4random()/ARC4RANDOM_MAX)*avgVal+minVal ;
[target setLocation:cc3v(Value, 5.0, 0.0)];
CCActionInterval *moveTarget = [CC3MoveBy actionWithDuration:7.0 moveBy:cc3v(0.0, -10.0, 0.0)];
CCActionInterval *removeTarget = [CCCallFuncN actionWithTarget:self selector:#selector(removeTarget:)];
[target runAction:[CCSequence actionOne:moveTarget two:removeTarget]];
}
-(void)removeTarget:(CC3MeshNode*)targ {
[self removeChild:targ];
targ=nil;
}
Without much code its hard to tell what you issues is, but here are some things to try apologies if any of this is obvious.
Are you holding onto a reference to the timer?
This might be useful for debugging. If you have a property called makeTargetTimer, then you could do this:
NSTimer * makeTargetTimer = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(createTargets) userInfo:nil repeats:YES];
self.makeTargetTimer = makeTargetTimer // Save to a property for later use (or just use an iVar)
The only way to stop a re-occurring timer is to invalidate it. Therefore you could check to see if its been invalidated.
BOOL isInvalidated = [self.makeTargetTimer isValid];
Also you might want to do this in your dealloc method anyway:
- (void) dealloc {
[_makeTargetTimer invalidate]; // Stops the timer from firing (Assumes ARC)
}
Are you scrolling when the even should be received?
If you want the timer to be fired while scrolling then you need to use NSRunLoopCommonModes. There is a excellent expiation in this question.
[[NSRunLoop currentRunLoop] addTimer:makeTargetTimer forMode:NSRunLoopCommonModes];
What is your implementation of createTargets like?
Have you put NSLog statements on the body of this method. Are you certain its not being called?

iOS : code creates two NSTimers

When I create a new timer with an IBAction and I double click the button, it creates two timers.
How can I write the code so there's only 1 timer and if I push the button it doesn't create a new timer?
Sorry for my bad English I'm 13 and from Germany.
Here is the code I use to create the timer:
- (IBAction)start:(id)sender;
{
progressBarUpdate = [NSTimer scheduledTimerWithTimeInterval:0.003 target:self selector:#selector(progressbarupdate) userInfo:nil repeats:YES];
//startet den timer
}
safe the timer as a member variable and check if already exists
#implementation MyViewController {
NSTimer *_timer;
}
...
- IBAction)start:(id)sender {
if(!_timer) {
_timer = [[NSTimer timerWith...] retain];//with arc, forget the retain
}
}
...
#end
Check progressBarUpdate.isValid before recreating the timer is an easy way to do this

Resources