let data = try! Data(contentsOf: fileUrl)
let cards = try! JSONDecoder().decode([Card].self, from: data)
//self.cards = cards
return cards
}
O nome da função diverge da funcionalidade em si, o listarCards pega dados em formato de data e decoda para cards, poderia ser fetchCards ou algo no estilo.
Caso não consiga dar um fetch nos cards utilizando o force ! você mata a aplicação na face do usuário.
Tem várias formas de contornar isso, uma sugestão é usar Result Type mapeados com enum
enum CardPresentationError: Error {
case couldNotLoad
// casos de falha aqui
}
do {
let data = try? Data(contentsOf: fileUrl)
let cards = try? JSONDecoder().decode([Card].self, from: data)
completion(.success(cards))
} catch let error {
completion(.failure(.couldNotLoad))
}
}
Com o result você garante os tipos possíveis, trazendo os tipos para o seu lado, assim nada de inesperado pode acontecer.
Caso de uso seria esse:
CardDao().fetchCards({ result in
switch result {
case .success(let cards): //pega os cards e os manipula
case .error(let error): //Você pode mostrar o error pro usuário
}
})
Outra sugestão é criar um Dao genérico, para não ter que ficar definindo lógica de implementação, toda vez que for criar um dao específico, lógica de fetch e tudo seria responsabilidade do Dao, eu passaria o tipo que esperaria que ele manipulasse struct Dao<T> // caso fosse [Card] ele faria um fetch em cards sem precisar de um dao só para isso
Várias dessas coisas podem ser aplicadas a outras partes do código.
Espero ajudar em algo, qualquer coisa pode falar na issue.
Função:
O nome da função diverge da funcionalidade em si, o listarCards pega dados em formato de data e decoda para cards, poderia ser fetchCards ou algo no estilo.
Caso não consiga dar um fetch nos cards utilizando o force ! você mata a aplicação na face do usuário.
Tem várias formas de contornar isso, uma sugestão é usar Result Type mapeados com enum
Com o result você garante os tipos possíveis, trazendo os tipos para o seu lado, assim nada de inesperado pode acontecer.
Caso de uso seria esse:
Outra sugestão é criar um Dao genérico, para não ter que ficar definindo lógica de implementação, toda vez que for criar um dao específico, lógica de fetch e tudo seria responsabilidade do Dao, eu passaria o tipo que esperaria que ele manipulasse
struct Dao<T> // caso fosse [Card] ele faria um fetch em cards sem precisar de um dao só para isso
Várias dessas coisas podem ser aplicadas a outras partes do código.
Espero ajudar em algo, qualquer coisa pode falar na issue.