Type of expression is ambiguous without more context in Xcode 11
Solution 1
Apparently I missed making sure my models (Item
in this case) conformed to the Identifiable
protocol fixed it. Still, I wish Apple was more clear with their error messages.
Solution 2
As you mentioned in your answer, a ForEach
needs a list of Identifiable
objects. If you don't want to make your object implement that protocol (or can't for some reason), however, here's a trick:
item.identifiedBy(\.self)
Solution 3
I had the same problem and it wasn't something related to the line itself, it was related to the curly braces/brackets, so that if someone faced the same problem and doesn't know where the problem is, try to trace the curly braces and the brackets
Solution 4
To conform to Identifiable
, just give the id
or uid
variable a unique value.
An easy way to do this is this:
var uid = UUID()
So your full struct would be:
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
}
Lorenzo Ang
Updated on July 09, 2022Comments
-
Lorenzo Ang almost 2 years
I'm trying to refer to an
[Item]
list within an@EnvironmentObject
however when accessing it within aSwiftUI
List
, I get the error. What I don't understand is, this error doesn't pop up when following Apple's Landmark tutorial.As far as I can tell, the
[Item]
list is loading correctly as I can print it out and do other functions with it. It just bugs out when using it for aSwiftUI
List
Is there something I've missed?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 } } } }
Supporting code below:
Item Struct:
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 } ]
-
Lorenzo Ang about 5 yearsThanks for the tip piebie! It works out for
Item
since it already hasvar id: Int
which automatically makes it conform toIdentifiable
. I'll keep it in mind though in case I need it in the future!