UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Day 59 Core Data - search from multiple entities

Forums > 100 Days of SwiftUI

Hi, I want to search from both candies and countries. But, it searches only from countries, and shows all the candies related to country.

1.How to make that search from candies works too?

Edit: Somehow working, but there's another Issue. When picker choise is "candy", origin country reprints each time

It shows:

UNITED KINGDOM

Mars

UNITED KINGDOM

KitKat

Instead of

UNITED KINGDOM

Mars

KitKat

2.How to understand that there's no match for request? so I can display "No matching results."

// this is what I've tried
@FetchRequest(entity: [Country.entity(), Candy.entity()], sortDescriptors: []) var countries: FetchedResults<Country, Candy>
init(filterKey: String,
         filterValue: String,
         strategy: FilterStrategy = .beginsWith,
         sortDescriptors: [NSSortDescriptor],
         @ViewBuilder content: @escaping (SomeCoreDataObject) -> Content) {

        var predicate = ""
        switch strategy {
        case .beginsWith:
            predicate = "BEGINSWITH"
        case .contains:
            predicate = "CONTAINS"
        case .endsWith:
            predicate = "ENDSWITH"
        }

        // Create and run the fetch request
        fetchRequest = FetchRequest<SomeCoreDataObject>(entity: SomeCoreDataObject.entity(),
                                                        sortDescriptors: sortDescriptors,
                                                        predicate: NSPredicate(format: "%K \(predicate)[c] %@", filterKey, filterValue))
        self.content = content
    }
struct ContentView: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(entity: Country.entity(), sortDescriptors: []) var countries: FetchedResults<Country>

    private let keys = [Key(userFacingName: "country", internalName: "fullName"), 
                        Key(userFacingName: "candy", internalName: "name")]
    @State private var selectedKey = 0

    struct Key {
        var userFacingName: String
        var internalName: String
    }

    private let strategies = ["begins with", "contains", "ends with"]
    @State private var selectedStrategy = 0

    @State private var letters = ""

    var body: some View {
        VStack {
            if letters.isEmpty {
                List {
                    ForEach(countries, id: \.self) { country in
                        Section(header: Text(country.wrappedFullName)) {
                            ForEach(country.candyArray, id: \.self) { candy in
                                Text(candy.wrappedName)
                            }
                        }
                    }
                }
            }
            else if selectedKey == 1 {
                FilteredList(filterKey: keys[selectedKey].internalName,
                             filterValue: letters,
                             strategy: FilterStrategy(rawValue: selectedStrategy)!,
                             sortDescriptors: []) { (candy: Candy) in

                    Section(header: Text(candy.originCountryName)) {
                        Text(candy.wrappedName)
                    }
                }

            } else if selectedKey == 0 {
                FilteredList(filterKey: keys[selectedKey].internalName,
                             filterValue: letters,
                             strategy: FilterStrategy(rawValue: selectedStrategy)!,
                             sortDescriptors: []) { (country: Country) in

                    Section(header: Text(country.wrappedFullName)) {

                        ForEach(country.candyArray, id: \.self) { candy in
                            Text(candy.wrappedName)
                        }
                    }
                }
            }

            Form {

                Section(header: Text("Filter on Key")) {

                    // How to filter?
                    Picker("Filter Strategy", selection: $selectedKey) {
                        ForEach(0..<keys.count) {
                            Text(keys[$0].userFacingName)
                        }

                    }
                    .pickerStyle(SegmentedPickerStyle())
                }

                Section(header: Text("Filter Strategy")) {

                    // How to filter?
                    Picker("Filter Strategy", selection: $selectedStrategy) {
                        ForEach(0..<strategies.count) {
                            Text(strategies[$0])
                        }

                    }
                    .pickerStyle(SegmentedPickerStyle())
                }

                Section() {
                    TextField("Search", text: $letters)
                }
     }

3      

why do you want

UNITED KINGDOM

Mars

KitKat

if it is sorted by candy? it looks like sorted by country for me.

If you want to sorted by candy, i might use this type of format:

Mars /UNITED KINGDOM

KitKat /UNITED KINGDOM

xxxx/......

Lastly, In all your code you loop candies under country, it might not be suprising for the result you got?

3      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.