Menu Close

News App – SwiftUI – Part I

In this project I made a News App with SwiftUI and a API. I used the api from newsapi.org. Visit the site to generate your own API-Key.

In Part One we are creating all Models which help us to use the API and more!

Models/News.swift
Models/NetworkManager.swift
Models/ImageLoader.swift

In the Models/News.swift File, we create a Results struct. The Results struct has an Array of News. The News are also defined as an struct. Both are Decodable and the News struct is also Identifiable.

import Foundation

struct Results: Decodable {
    let articles: [News]
}

struct News: Decodable, Identifiable {
    var id: String {
        return publishedAt
    }
    
    let publishedAt: String
    let title: String
    let description: String
    let urlToImage: String?
    let url: String?
}

The News struct has to have a id to be Identifiable. I linked the id with the publishedAt constant. All constants in both of the structs are defined by the JSON of the news api url. They have to be named exactly the same.

The Models/NetworkManager.swift File is the core for retrieving the data from the JSON Url.

import Foundation

class NetworkManager: ObservableObject {
    
    @Published var news = [News]()
    
    func fetchData() {
        if let url = URL(string: "https://newsapi.org/v2/top-headlines?country=de&apiKey=05f24edac22347af992881b990f47934") {
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, response, error) in
                if error == nil {
                    let decoder = JSONDecoder()
                    if let safeData = data {
                        do {
                            let results = try decoder.decode(Results.self, from:  safeData)
                            DispatchQueue.main.async {
                                self.news = results.articles
                            }
                        } catch {
                            print(error)
                        }
                    }
                }
            }
            task.resume()
        }
    }
}

In the Network Manager File we decode the data from the news api url. Here you have to implement your own API-Key. The class is an Observable Object, so the class will be observed, when Changes happen. The news Variable is marked as @Published.

The Models/ImageLoader.swift File helps us to load Images from a url.

import Foundation

class ImageLoader: ObservableObject {
    @Published var data: Data?

    init(urlString:String) {
        guard let url = URL(string: urlString) else { return }
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else { return }
            DispatchQueue.main.async {
                self.data = data
            }
        }
        task.resume()
    }
}

It behaves similar as the Network Manager, because the image url is also a path.

The complete project you can download at GitHub:

https://github.com/DKoenig82/news_app_swiftui

Leave a Reply

Your email address will not be published. Required fields are marked *