J'essaie de faire référence à un [Item]
liste dans un @EnvironmentObject
cependant lorsque j'y accède dans un SwiftUI
List
, j'obtiens l'erreur. Ce que je ne comprends pas, c'est que cette erreur n'apparaît pas lorsque vous suivez Tutoriel Landmark d'Apple .
Pour autant que je sache, le [Item]
la liste se charge correctement car je peux l'imprimer et faire d'autres fonctions avec. Il bogue juste quand on l'utilise pour un SwiftUI
List
Y a-t-il quelque chose que j'ai manqué?
ItemHome.Swift:
struct ItemHome : View {
@EnvironmentObject var dataBank: DataBank
var body: some View {
List {
ForEach(dataBank.itemList) { item in
Text("\(item.name)") // Type of expression is ambiguous without more context
}
}
}
}
Code de support ci-dessous:
Structure de l'article:
struct Item {
var id: Int
var uid: String
var company: String
var item_class: String
var name: String
var stock: Int
var average_cost: Decimal
var otc_price: Decimal
var dealer_price: Decimal
var ctc_price: Decimal
}
DataBank.Swift:
final class DataBank : BindableObject {
let didChange = PassthroughSubject<DataBank, Never>()
var itemList: [Item] = load("itemsResults.json") {
didSet {
didChange.send(self)
}
}
}
func load<T: Decodable>(_ filename: String, as type: T.Type = T.self) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
itemsResults.json:
[
{
"id": 1,
"uid": "a019bf6c-44a2-11e9-9121-4ccc6afe39a1",
"company": "Bioseed",
"item_class": "Seeds",
"name": "9909",
"stock": 0,
"average_cost": 0.0,
"otc_price": 0.0,
"dealer_price": 0.0,
"ctc_price": 0.0
},
{
"id": 2,
"uid": "a019bf71-44a2-11e9-9121-4ccc6afe39a1",
"company": "Pioneer",
"item_class": "Seeds",
"name": "4124YR",
"stock": 0,
"average_cost": 0.0,
"otc_price": 0.0,
"dealer_price": 0.0,
"ctc_price": 0.0
}
]
Comme vous l'avez mentionné dans votre réponse, un ForEach
a besoin d'une liste d'objets Identifiable
. Si vous ne voulez pas que votre objet implémente ce protocole (ou ne le peut pas pour une raison quelconque), voici une astuce:
item.identifiedBy(\.self)
Apparemment, j'ai manqué de m'assurer que mes modèles (Item
dans ce cas) étaient conformes au protocole Identifiable
. Pourtant, je souhaite Apple était plus clair avec leurs messages d'erreur.
Pour se conformer à Identifiable
, donnez simplement à la variable id
ou uid
une valeur unique.
Un moyen simple de le faire est le suivant:
var uid = UUID()
Donc, votre structure complète serait:
struct Item: Identifiable {
var id: Int
var uid = UUID()
var company: String
var item_class: String
var name: String
var stock: Int
var average_cost: Decimal
var otc_price: Decimal
var dealer_price: Decimal
var ctc_price: Decimal
}
J'ai eu le même problème et ce n'était pas quelque chose lié à la ligne elle-même, c'était lié aux accolades/crochets, de sorte que si quelqu'un faisait face au même problème et ne savait pas où était le problème, essayez de tracer le bouclé accolades et les supports