0

Disclaimer: Another very basic question below. I am trying to learn the basics of IOS development.

I'm currently trying to parse data from an API to a SwiftUI project and am not able to successfully do so.

The code goes as follows:

import SwiftUI

struct Poem: Codable, Hashable {
    let title, author: String
    let lines: [String]
    let linecount: String
}


struct ContentView: View {
        
    var poems = [Poem]()
        
    var body: some View {
            VStack {
                if let poem = poems.first {
                    Button("Refresh") {getPoem()}
                    Text("\(poem.author): \(poem.title)").bold()
                    Divider()
                    ScrollView {
                        VStack {
                            ForEach(poem.lines, id: \.self) {
                                Text($0)
                            }
                        }
                    }
                }
            }
        }
}

func getPoem() {
    let url = URL(string: "https://poetrydb.org/random/1")!
    // 2.
    URLSession.shared.dataTask(with: url) {(data, response, error) in
        do {
            if let poemData = data {
                // 3.
                let decodedData = try JSONDecoder().decode([Poem].self, from: poemData)
                DispatchQueue.main.async {
                    self.poems = decodedData
                }
            } else {
                print("No data")
            }
        } catch {
            print("Error")
        }
    }.resume()
}

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

The code does not build. The error thrown happens in the Func getPoem where "Cannot find 'self' in scope".

Any ideas? All help is appreciated.

1
  • Your func getPoem is outside of the struct, hence there is no self since it refers to an instance of the current type. Commented Dec 22, 2020 at 8:38

1 Answer 1

1

I meant something like

class FetchPoem: ObservableObject {
  // 1.
  @Published var poems = [Poem]()
     
    init() {
        getPoem()
    }
    
    func getPoem() {
        let url = URL(string: "https://poetrydb.org/random/1")!
        // 2.
        URLSession.shared.dataTask(with: url) {(data, response, error) in
            do {
                if let poemData = data {
                    // 3.
                    let decodedData = try JSONDecoder().decode([Poem].self, from: poemData)
                    DispatchQueue.main.async {
                        self.poems = decodedData
                    }
                } else {
                    print("No data")
                }
            } catch {
                print("Error")
            }
        }.resume()
    }
}

struct PoemContentView: View {
        
    @ObservedObject var fetch = FetchPoem()
    
    var body: some View {
        VStack {
            Button("Get Next Poem") { fetch.getPoem() }
            if let poem = fetch.poems.first {
                Text("\(poem.author): \(poem.title)").bold()
                Divider()
                ScrollView {
                    VStack {
                        ForEach(poem.lines, id: \.self) {
                            Text($0)
                        }
                    }
                }
            } else {
                Spacer()
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.