Type of expression is ambiguous without more context in Xcode 11

26,085

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
}
Share:
26,085
Lorenzo Ang
Author by

Lorenzo Ang

Updated on July 09, 2022

Comments

  • Lorenzo Ang
    Lorenzo Ang almost 2 years

    I'm trying to refer to an [Item] list within an @EnvironmentObject however when accessing it within a SwiftUI 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 a SwiftUI 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
    Lorenzo Ang about 5 years
    Thanks for the tip piebie! It works out for Item since it already has var id: Int which automatically makes it conform to Identifiable. I'll keep it in mind though in case I need it in the future!