SwiftUI – How to call a Rest API

By | 28/07/2021

In this post, we will see how to consume a Rest API in SwiftUI.
We will use a Rest API that it will get us the list of the annual holiday in Italy for the 2022.

We open Xcode and we create a new iOS app called TestWebAPI where, we will define our MVVM components:

[MODEL – HOLIDAY.SWIFT]

import Foundation

// Codable -> it allows us to serialize Json data in this struct
struct Holiday:  Codable 
{
    var date: String
    var localName: String
    var countryCode: String
}



[VIEW MODEL – COREDATA.SWIFT]

import Foundation

// ObservableObject -> it allows us to define an observable object (Holidays)
class CoreData: ObservableObject {
    
    // url service
    let url = URL(string: "https://date.nager.at/api/v2/publicholidays/2022/it")
    
    // variable used to store the list of holidays
    @Published var Holidays = [Holiday]()
    
    func GetHoliday()
    {
        // here we create a publisher that’ll emit a value when its data task succeeds (or fails)
        URLSession.shared.dataTaskPublisher(for: url!)
            // After we had the data, we will decode it into an array of Holiday
            .map { $0.data }
            .decode(type: [Holiday].self, decoder: JSONDecoder())
            // It will replace any errors in the stream with the provided element.
            .replaceError(with: [])
            // it will erase the type of the upstream publisher
            .eraseToAnyPublisher()
            // Since the data needs to be rendered on UI, we want to receive it on the MainThread.
            .receive(on: DispatchQueue.main)
            // It assigns the result at our array called Holidays
            .assign(to: &$Holidays)
    }
}



[VIEW – CONTENTVIEW.SWIFT]

import SwiftUI

struct ContentView: View {
    // we define viewModel as an observedObject
    @ObservedObject var viewModel = CoreData()
    var body: some View {
        NavigationView{
            List(viewModel.Holidays, id: \.date){item in
                VStack(alignment: .leading)
                {
                    Text("\(item.localName)")
                        .font(.system(size: 20, weight: .bold))
                        .foregroundColor(.blue)
                        .padding(.bottom)
                    
                    HStack{
                        Text("\(item.date)")
                            .font(.body)
                            .fontWeight(.bold)
                        Spacer()
                        Text("\(item.countryCode)")
                            .font(.body)
                            .foregroundColor(.red)
                    }
                }
            }.navigationBarTitle("Italy Holidays - 2022")
                        .onAppear {
                            // when it appears, app will call GetHoliday method
                            self.viewModel.GetHoliday()
                        }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(viewModel: CoreData())
    }
}



We have done and, if we run the application, this will be the result:



Leave a Reply

Your email address will not be published.