Search code examples
swiftuicore-data

Cannot fetch values from CoreData entity


I am trying to get all records from Coredata Entity 'Location' and pull the data from the entity to create an array of strings and display in a MenuPicker. In getLocationNames() ForEach statement it never pulls locations even though there are records. Also I do have a warning on that line: Result of 'ForEach<Data, ID, Content>' initializer is unused. How to fix this?

struct WeatherView: View {

@Environment(\.managedObjectContext) private var viewContext
@Environment(\.presentationMode) var presentationMode

@FetchRequest(
    sortDescriptors: [NSSortDescriptor(keyPath: \Location.locationName, ascending: true)],
    animation: .default)
private var locations: FetchedResults<Location>


@State private var locationNames: [String] = []
@State private var locationDetails:[String] = []
@State private var selectedLocation: String? = nil
@State private var location: Location? = nil
var body: some View {
    NavigationView {
        ScrollView (showsIndicators: false) {
            HStack {
                Text("Select Location")
                
                Picker("Location", selection: $selectedLocation  , content: {
                    ForEach(locationNames,id: \.self, content: { locationName in
                        Text(locationName )
                    })
                })
                .pickerStyle(MenuPickerStyle())
                .onReceive([self.selectedLocation].publisher.first()) { value in
                    selectedLocation = value
                    print("selectedLocation: \(selectedLocation ?? "not found")")
                }
                .onTapGesture {
                        self.getLocationNames()
                }
                
                
                }
            header: {
                Text("**Current **")
                    .padding(.top, 10)
            }
            }
            .navigationTitle("Locations")
            .toolbar {
                ToolbarItem(placement: .confirmationAction) {

                    Button("Detail", action: { onAdd()
                        
                    } )
                    
                    .foregroundColor(.blue)
                    
                }
            }
        }
        .onAppear{
            self.getLocationNames()
        }
    }
    func getLocationNames() -> (Void){
       
        ForEach(locations) { location in
            let locationStr = self.getLocationString(location: location)
        }
       

    }
    private func getLocationString(location: Location) -> String {
        var locDetails: String = location.locationType! + "; "
           locDetails += location.locationName! + ", "
           locDetails += location.zip!
        locationNames.append(locDetails)
        return locDetails
    }
   
}

Solution

  • In SwiftUI, ForEach is a view builder, so it only makes sense and works as part of a View. The first problem here is that you're calling ForEach in a function that returns Void, so you're using something that builds views but then throwing the result away by not using it anywhere. That's what the error message is telling you-- You used ForEach to create views, and the function code would return the views, but you're not doing that because you return Void.

    The second problem is that ForEach is a view builder-- so the closure inside it needs to return Views. Only you're not doing that-- you're assigning a value to a local variable called locationStr, which don't use for anything. You need to create a View of some kind in that closure. You might want to use locationStr in a Text or a Label or something else, but you need to create some kind of View in there for ForEach to do anything useful.