Andres Lopez
Posted on March 31, 2019
In this tutorial an application for WatchOS will be made, based on consulting a REST API of horoscopes.
Requirements
- Xcode 10.2 or higher
- Mac OS Mojave or higher
- IPhone simulator
- Apple Watch Simulator
Creation of the project
Open XCode and create a new WatchOS project.
The Include Notification Scene option is unchecked and the location where the project is saved is selected.
First screen
Drag a table element.
Two labels are added inside the table:
- First label with the following alignment properties.
- Second label with the following alignment properties.
The Row element of the table is assigned the identifier with the same name Row.
A Row class is created that inherits from NSObject and we link the corresponding outlets.
import WatchKit
class Row: NSObject {
@IBOutlet weak var lblIcon: WKInterfaceLabel!
@IBOutlet weak var lblZodiac: WKInterfaceLabel!
}
The code of the Interface Controller is as follows:
import WatchKit
import Foundation
class InterfaceController: WKInterfaceController {
@IBOutlet weak var table: WKInterfaceTable!
let zodiac = [
("♈", "Aries"),
("♉", "Taurus"),
("♊", "Gemini"),
("♋", "Cancer"),
("♌", "Leo"),
("♍", "Virgo"),
("♎", "Libra"),
("♏", "Scorpio"),
("♐", "Sagittarius"),
("♑", "Capricorn"),
("♒", "Aquarius"),
("♓", "Pisces")
]
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
table.setNumberOfRows(zodiac.count, withRowType: "Row")
for (index, sign) in zodiac.enumerated() {
guard let row = table.rowController(at: index) as? Row else { return }
row.lblIcon.setText(sign.0)
row.lblZodiac.setText(sign.1)
}
}
override func table(_ table: WKInterfaceTable, didSelectRowAt rowIndex: Int) {
print(zodiac[rowIndex].1)
let context = ["sing": zodiac[rowIndex].1]
presentController(withName: "Results", context: context)
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}
Model
The following structure is used for the response model:
import Foundation
struct Horoscope: Codable {
var currentDate: String
var description: String
enum CodingKeys: String, CodingKey {
case currentDate = "current_date", description
}
}
Second Screen
It is responsible for consuming the API, its interface is very simple and is built only with tags, which work very similar to iOS.
The Results Controller code is the following:
import WatchKit
import Foundation
class ResultsController: WKInterfaceController {
@IBOutlet weak var lblSing: WKInterfaceLabel!
var sing: String?
@IBOutlet weak var lblDate: WKInterfaceLabel!
@IBOutlet weak var lblDescription: WKInterfaceLabel!
override func awake(withContext context: Any?) {
super.awake(withContext: context)
// Configure interface objects here.
guard let context = context as? [String: String] else { return }
guard let sing = context["sing"] else { return }
lblSing.setText(sing)
DispatchQueue.global(qos: .userInteractive).async {
self.fetchData(sing: sing.lowercased())
}
}
func fetchData(sing: String) {
guard let url = URL(string: "https://aztro.sameerkumar.website/?sign=\(sing)&day=today") else { return }
print("https://aztro.sameerkumar.website/?sign=\(sing)&day=today")
var urlRequest = URLRequest(url: url)
urlRequest.httpMethod = "POST"
URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
if let data = data {
self.parse(data)
} else {
print("vacio")
}
}.resume()
}
func parse(_ contens: Data) {
let decoder = JSONDecoder()
guard let result = try? decoder.decode(Horoscope.self, from: contens) else { return }
DispatchQueue.main.async {
self.lblDate.setText(result.currentDate)
self.lblDescription.setText(result.description)
}
}
override func willActivate() {
// This method is called when watch view controller is about to be visible to user
super.willActivate()
}
override func didDeactivate() {
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
}
The application running
Conclusions
Consuming a REST API in WatchOS is relatively easy and very similar to how it is done in iOS. You can find the project code in the following github repository.
Posted on March 31, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.