Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting error "Generic parameter 'Label' could not be inferred" with SwiftUI tutorial code

Tags:

swiftui

I'm working through this SwiftUI tutorial here: https://developer.apple.com/tutorials/swiftui/handling-user-input

And on Step 3 of the section "Adopt the Model Object in Your View", I get this error on the Toggle statement in line 16: "Generic parameter 'Label' could not be inferred."

My code is identical to that provided in the tutorial:

import SwiftUI

struct LandmarkList: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        NavigationView {
            List {
                Toggle(isOn: $userData.showFavoritesOnly) {
                    Text("Favorites Only")
                }
                ForEach(userData.landmarkData) { landmark in
                    if !self.userData.showFavoritesOnly || landmark.isFavorite {
                        NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
                            LandmarkRow(landmark: landmark)
                        }
                    }
                }
            }
            .navigationBarTitle(Text("Landmarks"))
        }
    }
}

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in
            LandmarkList()
                .previewDevice(PreviewDevice(rawValue: deviceName))
                .previewDisplayName(deviceName)
        }
    }
}

When I look at the code provided in the "Complete" folder, I see its nearly identical, except that the userData variable is made private—which I added to my "StartingPoint" version, though I can't imagine why it'd make a difference, and of course it still gives the same error and won't build. I can build and run the Complete version, so clearly the message about requiring a Generic parameter is wrong and it must have to do with something else like how the project is configured in settings.

I remember getting stuck earlier this summer with a similar issue in a different part of the tutorial, and found a post where someone explained why code would work in one project and not another, but I can't find that post now.

Is anyone familiar with this issue? Is there something else I need to understand about how to configure my project before I can reference an observable object in a toggle control in my view like this?

like image 662
Subcreation Avatar asked Nov 12 '19 15:11

Subcreation


2 Answers

So as I mentioned in the comments: Just add .environmentObject(UserData()) under the ForEach() in your LandmarkList_Previews struct.

That would result in:

import SwiftUI

struct LandmarkList: View {
    @EnvironmentObject var userData: UserData

    var body: some View {
        NavigationView {
            List {
                Toggle(isOn: $userData.showFavoritesOnly) {
                    Text("Favorites Only")
                }
                ForEach(userData.landmarkData) { landmark in
                    if !self.userData.showFavoritesOnly || landmark.isFavorite {
                        NavigationLink(destination: LandmarkDetail(landmark: landmark)
                            .environmentObject(self.userData)
                        ) {
                            LandmarkRow(landmark: landmark)
                        }
                    }
                }
            }
            .navigationBarTitle(Text("Landmarks"))
        }
    }
}

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(["iPhone SE", "iPhone XS Max"], id: \.self) { deviceName in
            LandmarkList()
                .previewDevice(PreviewDevice(rawValue: deviceName))
                .previewDisplayName(deviceName)
        }.environmentObject(UserData())
    }
}
like image 63
krjw Avatar answered Oct 09 '22 05:10

krjw


I had the exact same problem today and Ravi Mishra's comment resolved the issue for me (kudos to you). It must've been an autocomplete mistake.

ForEach(userData.landmarkData) should instead be ForEach(userData.landmarks)

like image 21
SolidCoder Avatar answered Oct 09 '22 04:10

SolidCoder