Bogdan Laukhin Bogdan Laukhin - 5 months ago 14
Objective-C Question

NSTimer object doesn't work (can't refresh token automatically using NSTimer)

My NSTimer object doesn't work - it starts, but doesn't fire. I try to refresh token automatically via

scheduledTimerWithTimeInterval
method.

here is the code for Token class:

//
// Token.m
// oauthdemoapp
//

#import "Token.h"
#import "ServerManager.h"

@implementation Token

+ (Token *) sharedInstance {
static Token *token = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
token = [[Token alloc] init];
});
return token;
}

- (void)setAccessToken:(NSString *)accessToken {
_accessToken = accessToken;
[self runTheTimer];
}

#pragma mark -
#pragma mark Timer

- (void)runTheTimer {
NSLog(@"timer started");
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(executeRefreshTokenRequest) userInfo:nil repeats:YES];
self.timer = timer;

}

- (void)stopTheTimer {

}

#pragma mark -
#pragma mark Requests

- (void)executeRefreshTokenRequest {
NSLog(@"timer fired");
[[ServerManager sharedInstance] postForNewTokenWithRefreshToken:self onSuccess:^(Token *updatedToken) {
NSLog(@"%@", self.accessToken);
NSLog(@"%@", updatedToken.accessToken);
} onFailure:^(NSError *error) {
NSLog(@"%@", [error localizedDescription]);
}];

}


@end


Timers starts when I'm saving the access token here while authorising user. But it doesn't fire to start countdown and run refresh token request.

My global task though, is to refresh token automatically - it comes in response with access token, time interval 60 seconds and refresh token. Maybe you can advice better solution for this.

Thank you

Answer

Solved the problem by using grand central dispatch.

I declare block method within the class:

dispatch_source_t CreateLocationTimerDispatch(double interval, dispatch_queue_t queue, dispatch_block_t block) {
    dispatch_source_t timerForLocationRefresh = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    if (timerForLocationRefresh) {
        dispatch_source_set_timer(timerForLocationRefresh, dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), interval * NSEC_PER_SEC, (1ull * NSEC_PER_SEC) / 10);
        dispatch_source_set_event_handler(timerForLocationRefresh, block);
        dispatch_resume(timerForLocationRefresh);
    }
    return timerForLocationRefresh;
}

class local variables:

dispatch_source_t _timerForLocationRefresh;
static double SECONDS_TO_FIRE = 1800.f; // time interval lengh in seconds 1800

method to start timer:

- (void)startTimer {
    // second timer
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    _timerForLocationRefresh = CreateLocationTimerDispatch(SECONDS_TO_FIRE, queue, ^{

        // do smth
    });
}

method to stop timer:

- (void)cancelTimer {
    if (_timerForLocationRefresh) {
        dispatch_source_cancel(_timerForLocationRefresh);
        _timerForLocationRefresh = nil;
    }
}
Comments