-2

I decoded json data from an API and now I want to transfer the decoded data to my view where it can be displayed.

the problem is that I cannot transfer the decoded data to my view with @Observable Object.

My decoding class looks like this:

class apirefresh: ObservableObject {

@Published var datareturn : DataClass

func refreshData() {
        let url = URL(string: "http://localhost:3000/Data")!
    
        url.getResult { (result: Result<DataClass, Error>) in
            switch result {
            case let .success(dataout):
                self.datareturn = dataout
                print(dataout)
                //print(dataout.klasse[0].aktive[0].name) //dataout.klasse[0].aktive[0].name
            case let .failure(error):
                print(error)
            }
        }
    }
}

and my error like this: Class Error

I also got an error in my View but this error seams to be related to the previous error.

View Error

And my json model looks like this:

// MARK: - APICall
struct APICall: Codable {
    let data: DataClass

    enum CodingKeys: String, CodingKey {
        case data = "Data"
    }
}

// MARK: - DataClass
struct DataClass: Codable {
    let klasse: Klasse
    let update: Update
}

// MARK: - Klasse
 struct Klasse: Codable {
    let aktive, bjugend, cjugend, djugend: [Verein]
    let ejugend, fjugend, bambini: [Verein]
}

// MARK: - Aktive
struct Verein: Codable {
    let id, place: String
    let name: String
    let tore, punkte: String
    let gruppe: String
}

// MARK: - Update
struct Update: Codable {
    let last: String
}

Thanks for your help in advance.

1 Answers1

0

The problem is that datareturn in this class doesn't have an initial value, which is why the compiler is asking for a class initializer wherein you would give datareturn an initial value. So you must either do that:

class apirefresh: ObservableObject {

@Published var datareturn : DataClass

init(datareturn: DataClass) {
    self.datareturn = datareturn
}

func refreshData() {
        let url = URL(string: "http://localhost:3000/Data")!
    
        url.getResult { (result: Result<DataClass, Error>) in
            switch result {
            case let .success(dataout):
                self.datareturn = dataout
                print(dataout)
                //print(dataout.klasse[0].aktive[0].name) //dataout.klasse[0].aktive[0].name
            case let .failure(error):
                print(error)
            }
        }
    }
}

Or make datareturn an optional (which makes its initial value nil).

class apirefresh: ObservableObject {

@Published var datareturn : DataClass?

func refreshData() {
        let url = URL(string: "http://localhost:3000/Data")!
    
        url.getResult { (result: Result<DataClass, Error>) in
            switch result {
            case let .success(dataout):
                self.datareturn = dataout
                print(dataout)
                //print(dataout.klasse[0].aktive[0].name) //dataout.klasse[0].aktive[0].name
            case let .failure(error):
                print(error)
            }
        }
    }
}
trndjc
  • 11,654
  • 3
  • 38
  • 51
  • That init fixed my class but I am still getting an error in my view "Missing argument for parameter 'datareturn' in call" – Nicodimarco Dec 15 '21 at 17:22
  • @Nicodimarco whenever you instantiate an `apirefresh` class, if it has this initializer, you must call it with its initializer `let refresh = apirefresh(datareturn: someValue)`. You should name types (structs, classes, enums, etc.) with capital letters if you care about conventional programming (which I think you should). – trndjc Dec 15 '21 at 18:51