Vai al contenuto

[iOS] Problema con json e List


Messaggi raccomandati

ciao!

 

sto cercando di riempire una Lista da json, che ha questo formato:

{
	"books": [{
		"id": "87",
		"title": "2001 odissea nello spazio",
		"author_id": null,
		"author": "arthur c. clarke",
		"editor_id": null,
		"editor": "longanesi",
		"price": "0.00",
		"isbn": "",
		"note": ""
	}, {
		"id": "86",
		"title": "2010 odissea due",
		"author_id": null,
		"author": "arthur c. clarke",
		"editor_id": null,
		"editor": "rizzoli",
		"price": "0.00",
		"isbn": "",
		"note": ""
	}, {
		"id": "2",
		"title": "odissea",
		"author_id": null,
		"author": "clive cussler",
		"editor_id": null,
		"editor": "tea due",
		"price": "8.50",
		"isbn": "88-502-0984-3",
		"note": ""
	}]
}

io ho creato questa struct:

struct Book: Decodable, Identifiable {
    
    public var id: Int;
    public var title: String;
    public var isbn: String;
    
    enum CodingKeys: String, CodingKey {
        case id = "id";
        case title = "title";
        case isbn = "isbn";
    }
    
}

questa la classe per recuperare i dati in remoto:

import Foundation

public class GetBooks: ObservableObject {
    
    @Published var books = [Book]();
    
    init() {
        load();
    }
    
    func load() {
        let url = URL(string: "https://www.mattepuffo.com/api/book/get.php")!;
        
        URLSession.shared.dataTask(with: url) {
            (data, response, error) in
            do {
                if let d = data {
                    let decodedLists = JSONDecoder();
                    decodedLists.keyDecodingStrategy = .convertFromSnakeCase;
                    let dec = try decodedLists.decode([Book].self, from: d);
                    DispatchQueue.main.async {
                        self.books = dec;
                    }
                } else {
                    print("Non ci sono libri");
                }
            } catch {
                print(error)
            }
            
        }.resume();
        
    }
}

qui ottengo un errore:

typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))

penso di aver capito quale sia il problema, ma non capisco come risolverlo.

nel senso che il problema è che il json inizia con un oggetto (books) e non con un array.

ma non capisco come devo modificare il codice!

Link al commento
Condividi su altri siti

Dovrebbe bastare modificare questa riga togliendo le parentesi quadre:

 

let dec = try decodedLists.decode(Book.self, from: d);

 

 

An  a tuesday keeps the doctor away.

proud member of < noi finti professionisti > club - tessera 044

Link al commento
Condividi su altri siti

ciao!

 

intanto grazie per la risposta.

ho provato come dici tu, ma mi da errore (l'ho messo come commento nel codice):

import Foundation

public class GetBooks: ObservableObject {
    
    @Published var books = [Book]();
    
    init() {
        load();
    }
    
    func load() {
        let url = URL(string: "https://www.mattepuffo.com/api/book/get.php")!;
        
        URLSession.shared.dataTask(with: url) {
            (data, response, error) in
            do {
                if let d = data {
                    let decodedLists = JSONDecoder();
                    decodedLists.keyDecodingStrategy = .convertFromSnakeCase;
                    let dec = try decodedLists.decode(Book.self, from: d);
                    DispatchQueue.main.async {
                        self.books = dec; // Cannot assign value of type 'Book' to type '[Book]'
                    }
                } else {
                    print("Non ci sono libri");
                }
            } catch {
                print(error)
            }
            
        }.resume();
        
    }
}

penso ci sia un'altra modifica da fare sopra sul @Published, ma anche qui non ho capito bene quale.

 

Link al commento
Condividi su altri siti

Archiviato

Questa discussione è archiviata e chiusa a future risposte.

×
×
  • Crea Nuovo...