Lauren G Lauren G - 4 years ago 264
Swift Question

Measuring Time Accurately in Swift for Comparison Across Devices

I need to be able to record reaction time, from when the screen loads or the question label refreshes until the user taps a number button. I'm not finding documentation from Apple on this to be very helpful.

NSDate
is not accurate enough, I need to measure to milliseconds at least.
mach_absolute_time
seems to be favored by game designers because it is internally consistent, but it won't work for this application because I need to compare data across devices, and
mach_absolute_time
is CPU dependent time. This Apple Dev Q&A suggests using
NanosecondsToAbsolute
and
DurationToAbsolute
but it's in obj-c and I can't find a swift equivalent documentation.

Is there a swift version of
NanosecondsToAbsolute
and
DurationToAbsolute
that I'm just not finding? Some other way to do this consistently?

Here's the code I'm trying to add the times to:

class EmotionQuestionsViewController: UIViewController{

override func viewDidLoad() {
super.viewDidLoad()

//mark "startTime" when view loads
}

@IBOutlet var questionLabel: UILabel!
var timeResultsStack = [String]()

var questionsStack = ["HAPPY", "ANXIOUS"]
var questionResultsStack = [String]()
var questionStackArrayIndex = 1

@IBAction func RecordValueFromNumericalScaleOneToSeven(sender: UIButton) {

//mark durration time as currentTime - startTime, append to timeResultsStack

let value = sender.currentTitle!
questionResultsStack.append(value)

if questionResultsStack.count < questionsStack.count{
self.questionLabel.text = "how \(questionsStack[questionStackArrayIndex]) are you right now?"

//mark startTime when label is changed

self.questionStackArrayIndex++

}
else{
self.performSegueWithIdentifier("showResults", sender: nil)

}
}

Answer Source

You can use NSTimeInterval to measure time (much better than a timer). You just need to store two dates (two points in time) and subtract endTime - StartTime as follow:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var salesPriceSlider: UISlider!

    var startTime: NSTimeInterval = 0
    var endTime: NSTimeInterval = 0

    override func viewDidLoad() {
        super.viewDidLoad()
        startTime = NSDate().timeIntervalSinceReferenceDate
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
    @IBAction func stopTimeAction(sender: AnyObject) {
        endTime = NSDate().timeIntervalSinceReferenceDate
        println((endTime-startTime).time)
    }

}

extension NSTimeInterval {
    var time:String {
        return String(format:"%02d:%02d:%02d.%03d", Int((self/3600.0)%60),Int((self/60.0)%60), Int((self) % 60 ), Int(self*1000 % 1000 ) )
    }
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download