In this Apple Watch developer tutorial series we are building a watchOS 2 app with a companion iPhone app. Since Intertech’s 3-month paid sabbatical program is so popular with employees (and something they literally count down the days to until it arrives) I thought it would be fun to build everyone an Apple Watch countdown app that shows them how long they have until they can experience three months of being paid to do whatever they want. Along the way in this Apple Watch development tutorial we’ll learn about WatchKit, ClockKit, NSDate formatting and complications. If you run into trouble be sure to check out my article on Apple Watch Developer Tips and Tricks.
Setup project
To begin launch Xcode and fire up a new project by selecting File >> New Project.
Under WatchOS Application, select iOS App with WatchOS app:
Fill in Project Name, Organization Name etc. and select Swift for your Language and iPhone under Devices. Make sure to select “Include Complication” for use in the third part of this tutorial series and de-select all other checkboxes.
Save your project.
Once you have saved your project, set the Active Scheme to your WatchKit app >> iPhone 6S Plus + Apple Watch 42mm. The actual device types don’t matter as much as having both a phone simulator and an Apple Watch simulator in your active scheme.
Run your project with this new Active Scheme. You should see two simulators appear, one simulating the phone and one simulating the Apple Watch. Neither will have any data showing up besides the clock on the watch simulator:
Create your watch interface
Open the Interface.storyboard under the WatchKit App folder in Xcode and add the following elements in this order: Label, Separator, Group, Label, Label, Label. The Group is optional but adds a bit more space between the separator and the second label.
Select the first label you added and open the Attributes Inspector. Change the label Text to “My Sabbatical” and the Horizontal Alignment to “Center”.
For the other three labels, change the Width to “Relative to Container”. Your interface should now look like this:
Update WatchKit Extension InterfaceController
Now open the WatchKit Extension’s InterfaceController in Xcode’s Assistant Editor and control-drag to create outlets for the last three labels on your interface. Name these outlets “yearsLabel”, “monthsLabel” and “daysLabel”.
Add the following function to the InterfaceController:
func startCountDown(timer: NSTimer) { // create calendar, date and formatter variables let userCalendar = NSCalendar.currentCalendar() let dateFormatter = NSDateFormatter() dateFormatter.calendar = userCalendar dateFormatter.dateFormat = "yyyy-MM-dd" // create variable to hold 7 years let sevenYears: NSDateComponents = NSDateComponents() sevenYears.setValue(7, forComponent: NSCalendarUnit.Year); // hard-code start date value for part one of this tutorial let startDateIntertech: NSDate = dateFormatter.dateFromString("2005-06-01")! // add 7 years to our start date to calculate the date of our sabbatical var sabbaticalDate = userCalendar.dateByAddingComponents(sevenYears, toDate: startDateIntertech, options: NSCalendarOptions(rawValue: 0)) // since we get a sabbatical every 7 years, add 7 years until sabbaticalDate is in the future while sabbaticalDate!.timeIntervalSinceNow.isSignMinus { sabbaticalDate = userCalendar.dateByAddingComponents(sevenYears, toDate: sabbaticalDate!, options: NSCalendarOptions(rawValue: 0)) } // create year, month and day values for display let flags: NSCalendarUnit = [.Year, .Month, .Day] let dateComponents = userCalendar.components(flags, fromDate: NSDate(), toDate: sabbaticalDate!, options: []) let year = dateComponents.year let month = dateComponents.month let day = dateComponents.day // set labels on interface yearsLabel.setText(String(format: "%d Years", year)) monthsLabel.setText(String(format: "%d Months", month)) daysLabel.setText(String(format: "%d Days", day)) }
This method figures out when the user’s sabbatical will begin based on a hard-coded (for now) start date and displays the countdown on the watch.
Call the startCountDown function you just added from the InterfaceController’s awakeWithContext method:
override func awakeWithContext(context: AnyObject?) { super.awakeWithContext(context) // start/refresh countdown using a one-second timer NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("startCountDown:"), userInfo: nil, repeats: true) }
The awakeWithContext function is much like viewDidLoad in regular iOS development and is the place to set up your watch interface. Here we create a 1-second timer and run our startCountDown function using that timer.
Run the app and you should see a working countdown!
The code for this tutorial is on GitHub.
In this first part of this Apple Watch development tutorial series we built a functioning countdown app for the Apple Watch / watchOS 2. Come back next week for part 2 of this series where we will build an iPhone app to allow the user to set their own start date.
Check out the other posts in the series:
Apple Watch Development Tutorial (Part 2): Countdown App