WatchOS (Swift): Horoscope Application
Tags: watchos, swift, xcode
Published: 2019-03-31 23:27:28

---
title: WatchOS (Swift): Horoscope Application
published: true
description: In this tutorial an application for WatchOS will be made, based on consulting a horoscopes REST API
tags: #watchos,#swift,#xcode
cover_image: https://cdn-images-1.medium.com/max/2600/1*Zp3rGVAw4zIr_0aWeTbxMQ.jpeg
---

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.

![xcode](https://cdn-images-1.medium.com/max/1600/1*-GDIcQQtPquaF4D36UY-Ew.png)


The **Include Notification Scene** option is unchecked and the location where the project is saved is selected.

![xcode](https://cdn-images-1.medium.com/max/1600/1*0ylHOKqjM0pNJel-prS-ew.png)

#First screen

![xcode](https://cdn-images-1.medium.com/max/1600/1*iTYINYeOQ0rex59CUZnd-w.png)

Drag a **table** element.

![xcode](https://cdn-images-1.medium.com/max/1600/1*8E5E1DnEyb9TOUbOb_8jGA.png)

Two labels are added inside the **table**:

- **First label** with the following alignment properties.

![xcode](https://cdn-images-1.medium.com/max/1600/1*S6oi0gU_xKc961XyjNcPFw.png)

- **Second label** with the following alignment properties.

![xcode](https://cdn-images-1.medium.com/max/1600/1*zRjQOmbcIp9JoY7VSeeNRw.png)

The **Row** element of the table is assigned the identifier with the same name Row.

![xcode](https://cdn-images-1.medium.com/max/1600/1*SyKBc1m6k5LarEKB_J8yPA.png)

A **Row** class is created that inherits from **NSObject** and we link the corresponding outlets.


```swift

import WatchKit

class Row: NSObject {
    @IBOutlet weak var lblIcon: WKInterfaceLabel!
    
    @IBOutlet weak var lblZodiac: WKInterfaceLabel!
}

```

The code of the ***Interface Controller*** is as follows:

```swift

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:


```swift

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.

![xcode](https://cdn-images-1.medium.com/max/1600/1*U4K4KlPnQp6Q93nLs_busA.png)


The Results Controller code is the following:

```swift

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

![xcode](https://cdn-images-1.medium.com/max/1600/1*06Q8B_OQjQcbDQLuUcrAyQ.png)

![xcode](https://cdn-images-1.medium.com/max/1600/1*MsqGNBazthY4vwGDxHl1iw.png)

#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](https://github.com/andreslopezrm/WatchOS_Swift_Horoscope) repository.