Pavan Welihinda
Pavan Welihinda

Reputation: 655

Run defined time using NSTimer as a clock

I have been struggling to get the time from NSDate to run (As in like a clock) but unfortunately it's not so easy as you think. Yes i did Google as well but i haven't been able to find a solid solution.

Here's what i'm doing. I get the current date and time from an API because i cannot rely on the local date time since it can be altered via settings. Therefore i get get the current date and time from an API and using date formatter i get the proper format and assign to a NSTimer and then to NSRunLoop for it to run like a clock and update in a label every second.

The issue is that, from the way i have implemented it, i feel that since the date I've assigned for fireDate maybe different to the local time and it becomes a mismatch in time, the loop only works according to local date time no matter what i get as an output from the API. I feel it will run as a future date so please help me out and the code written is given below. Thanks.

let timeInterval: NSTimeInterval = 1.0
var dateFormatter = NSDateFormatter()
dateFormatter.timeZone = NSTimeZone(name: "GMT")

let serverNowDate: NSDate! = dateFormatter.dateFromString(DateTime.ServerNow())!
println("2015-07-21 11:06:31 am")

var timer = NSTimer(fireDate: serverNowDate, interval: timeInterval, target: self, selector: Selector("updateTimer:"), userInfo: nil, repeats: true) 

func updateTimer(timer:NSTimer!) //this doesn't get called
{
        var dateFormatter = NSDateFormatter()
        dateFormatter.dateFormat = "hh:mm a"
        dateFormatter.timeZone = NSTimeZone(name: "GMT")
}

Upvotes: 0

Views: 370

Answers (2)

Nils Ziehn
Nils Ziehn

Reputation: 4331

The reason why your timer doesn't fire is because it's not scheduled. You need to tell the NSTimer on which runloop to run on. For convenience Apple provided a method that will return a scheduled timer:

class func scheduledTimerWithTimeInterval(_ seconds: NSTimeInterval,
                                   target target: AnyObject,
                                 selector aSelector: Selector,
                                 userInfo userInfo: AnyObject?,
                                  repeats repeats: Bool) -> NSTimer

Additionall I want to say:

This probably won't do what you intend. I think you wan't to display a clock with the 'real date', but there is no code that will actually accomplish that.

To save some time you could look into something like this: https://github.com/jbenet/ios-ntp

This will give you reliable time information and nice access to the current date & time.

Finally I want to tell you that you shouldn't instantiate Dateformatters inside your fire method, since it is a pretty heavy object to create and will impact performance very negatively. You should just create it once and keep using the same instance.

Upvotes: 1

villy393
villy393

Reputation: 3083

If you want the timer to fire straight away is there a reason you wouldn't just do this?

    let timer = NSTimer(timeInterval: timeInterval, target: self, selector: "updateTimer:", userInfo: nil, repeats: true)
    timer.fire()

Upvotes: 0

Related Questions