When playing around with Swift, something I’m trying hard to avoid is just implementing Objective-C patterns in my Swift code. It’s been tough, especially since the community is only just figuring out how things should be done.
I’ve spent the past few days porting an incomplete project over to Swift in the hopes of releasing my first 100% Swift app by the end of the month. I had a simple method that updated a label every second with the time elapsed. Here’s how I had implemented it in Objective-C:
- (void)updateTimerLabel
{
NSTimeInterval timeElapsed = [[NSDate date] timeIntervalSinceDate:self.startTime];
self.timerLabel.text = [self stringFromTimeInterval:timeElapsed];
}
- (NSString *)stringFromTimeInterval:(NSTimeInterval)interval {
NSInteger ti = (NSInteger)interval;
NSInteger seconds = ti % 60;
NSInteger minutes = (ti / 60) % 60;
return [NSString stringWithFormat:@"%02ld:%02ld", (long)minutes, (long)seconds];
}
In Swift, I could have written this similarly using string interpolation. That didn’t seem like the Swift way to do things however. There are a couple cases you have account for (prepending a zero to a minute or second if it was less than 10) and string interpolation alone seemed clunky. Here’s how I ended up implementing it:
func updateTimerLabel() -> Void {
let interval = NSDate().timeIntervalSinceDate(startTime)
let (min, sec) = timeElapsedInSecondsAndMinutes(interval: interval)
switch (min, sec) {
case (0..<10, 0..<10):
return contractionTimerLabel.text = "0\(min):0\(sec)"
case (_, 0..<10):
return contractionTimerLabel.text = "\(min):0\(sec)"
case (0..<10, _):
return contractionTimerLabel.text = "0\(min):\(sec)"
default:
return contractionTimerLabel.text = "\(min):\(sec)"
}
}
private func timeElapsedInSecondsAndMinutes(#interval: NSTimeInterval) -> (seconds: Int, minutes: Int){
var seconds = Int(floor(interval % 60))
var minutes = Int((interval / 60) % 60)
return (minutes, seconds)
}
There are a couple interesting things going on here that aren’t easy to do with Objective C.
(a..<b)
to check that both the minute and
second value are less than 10.(_)
in place of a variable name.This may not be the cleanest way to implement this but it certainly feels more Swifty. It’s hard rewiring your brain to do the exact same things but with new syntax. Fun stuff!