我试图引用[Item]
中的@EnvironmentObject
列表,但是在SwiftUI
List
中访问它时,出现错误。我不明白的是,遵循Apple's Landmark tutorial时不会弹出此错误。
据我所知,[Item]
列表正在正确加载,因为我可以打印出来并执行其他功能。当将它用于SwiftUI
List
时,它会出错,我错过了什么吗?
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
}
}
}
}
下面的支持代码:
项目结构:
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
}
]
答案 0 :(得分:3)
正如您在答案中提到的,ForEach
需要一个Identifiable
对象的列表。但是,如果您不想使对象实现该协议(或者由于某种原因而不能),则可以使用以下技巧:
item.identifiedBy(\.self)
答案 1 :(得分:1)
显然,我错过了确保我的模型(在这种情况下为Item
)是否符合Identifiable
协议对其进行修复的保证。不过,我希望苹果公司对他们的错误消息更加清楚。
答案 2 :(得分:0)
要符合Identifiable
,只需为id
或uid
变量赋予唯一值即可。
一个简单的方法是:
var uid = UUID()
因此您的完整结构应为:
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
}
答案 3 :(得分:0)
我遇到了同样的问题,它与生产线本身无关,它与花括号/花括号有关,因此,如果有人遇到相同的问题并且不知道问题出在哪里,请尝试跟踪花括号和括号