Hi I am getting a blank screen when I run the following code in my Xcode project

//

//  ContentView.swift

//  NewsReader

//

//  Created by Rashid  Vohra on 7/7/21.

//

import SwiftUI

struct Result: Codable {

    var articles: [Article]

}

struct Article: Codable {

    var url: String

    var title: String

    var description: String?

    var urlToImage: String?

}

struct ContentView: View {

    private let url = "https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=49d5bfa113c34ec0af781fab38395996"

    

    

    @State private var articles = [ Article ()

    

    func fetchData() {

        guard let url = URL(string: url) else {

            print("URL is not valid")

            return

        }

        

        let request = URLRequest(url: url)

        

        URLSession.shared.dataTask(with: request) {

            data, response, error in

            if let data = data {

                if let decodedResult = try?

                    JSONDecoder().decode(

                        Result.self, from: data) {

                    

                    DispatchQueue.main.async {

                      

                        self.articles =

                            decodedResult.articles

                    }

                    return

                }

            }

            print ("Error: (error?.localizedDescription ?? "Unknown Error") ")

        }.resume()

    }

    

    var body: some View {

        

        

        List(articles, id: .url) { item in

            HStack(alignment: .top) {

               

                VStack(alignment: .leading) {

                    Text(item.title)

                        .font(.headline)

                    Text(item.description ?? "")

                        .font(.footnote)

                }

            }.onAppear(perform: fetchData)

        }

    }

}

struct ContentView_Previews: PreviewProvider {

    static var previews: some View {

        ContentView()

    }

}

Please use the Code Block feature of this site, when you show your code.

Your code is sort of broken, it would confuse readers what you really tested. With fixing all of them by guess, the most critical issue is that you put onAppear at the wrong place.

Please try this:

struct ContentView: View {
    private let url = "https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=49d5bfa113c34ec0af781fab38395996"
    
    @State private var articles: [Article] = []
    
    func fetchData() {
        guard let url = URL(string: url) else {
            print("URL is not valid")
            return
        }
        
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let error = error {
                print("dataTask Error: \(error)")
                return
            }
            guard let data = data else {
                print("data is nil")
                return
            }
            //You should better not use `try?` when you do not know all the cases where errors would occur
            //Better use do-try-catch
            do {
                let decodedResult = try JSONDecoder().decode(Result.self, from: data)
                DispatchQueue.main.async {
                    self.articles = decodedResult.articles
                }
            } catch {
                print("Decoding Error: \(error)")
            }
        }.resume()
    }
    
    var body: some View {
        List(articles, id: \.url) { item in
            HStack(alignment: .top) {
                VStack(alignment: .leading) {
                    Text(item.title)
                        .font(.headline)
                    Text(item.description ?? "")
                        .font(.footnote)
                }
            }
            //.onAppear(perform: fetchData) //<- Move this line
        }
        .onAppear(perform: fetchData) //<- Here
    }
}

If onAppear is placed inside List, it would never be called while the list is empty.


By the way, you should not make apiKey publicly open. I recommend you to disable it and re-get a new one.

Is it the real code ? It cannot compile.

This is not correct syntax:

   @State private var articles = [ Article ()

It misses closing bracket

   @State private var articles = [Article] ()

And there is an extra quote and probably backslash here:

      print ("Error: `(error?.localizedDescription` ?? "Unknown Error") ")

Should be

            print ("Error: \(error?.localizedDescription ?? "Unknown Error") ")

I modified the code as follows

import SwiftUI

struct Result: Codable {
    var articles: [Article]
}

struct Article: Codable, Hashable {  // Hashable to be able to use \.self in List
    var url: String
    var title: String
    var description: String?
    var urlToImage: String?
}

struct ContentView: View {
    private let url = "https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=49d5bfa113c34ec0af781fab38395996"
    
    @State private var articles : [Article] = []  // Just for the forum editor
    
    func fetchData() {
        guard let url = URL(string: url) else {
            print("URL is not valid")
            return
        }
        
        let request = URLRequest(url: url)

        URLSession.shared.dataTask(with: request) {
            data, response, error in
            if let data = data {
                if let decodedResult = try?
                    JSONDecoder().decode(
                        Result.self, from: data) {
                    
                    DispatchQueue.main.async {
                      
                        self.articles =
                            decodedResult.articles
                        print("Articles", articles)
                    }
                    return
                }
            }
            print ("Error: \(error?.localizedDescription ?? "Unknown Error") ")
        }.resume()
    }
    
    var body: some View {
        VStack {    // Just to get something on screen
            List(articles, id: \.self) { item in
                HStack(alignment: .top) {
                    
                    VStack(alignment: .leading) {
                        Text(item.title)
                            .font(.headline)
                        Text(item.description ?? "")
                            .font(.footnote)
                    }
                }.onAppear(perform: fetchData)
            }
            Text("Count articles \(articles.count)")
        }
    }
}

You get 0 article: which means Article and JSON may not match (I did not inspect the JSON file). I tested with an explicit int(), removing onAppear. Same issue:

init() {     self.fetchData() }

Hi I am getting a blank screen when I run the following code in my Xcode project
 
 
Q