Here's how to dynamically set the predicates for your fetch request. First, the properties I have in my SwiftUI view:
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \Pokemon.id, ascending: true)],
animation: .default
) private var pokedex: FetchedResults<Pokemon>
@State var searchText = ""
@State var filterByFavorites = false
var compoundPredicate: NSPredicate {
var predicates: [NSPredicate] = []
// Add search predicate
if !searchText.isEmpty {
predicates.append(NSPredicate(format: "name contains[c] %@", searchText))
}
// Add favorite filter predicate
if filterByFavorites {
predicates.append(NSPredicate(format: "favorite == %d", true))
}
// Combine predicates
return NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
}
Notice I don't set any predicate in the fetch request at this point. Also notice, the part that makes this all work is the compoundPredicate computed property. I start with an empty predicates array, then I check my searchText and append the appropriate predicate if the condition is true. Then I check my filterByFavorites property and do the same.
Alright, now the code inside the body var that makes it work. I won't post my whole view since most of it is irrelevant, but here is where I add my List view which shows my pokedex fetched results:
List(pokedex.filter { compoundPredicate.evaluate(with: $0) }) { pokemon in
I filter my pokedex fetched results with the compoundPredicate and evaluate every single pokemon in the list to make sure only those that match the criteria are shown.
I also have a .searchable(text: $searchText, prompt: "Find a Pokemon") modifier on the List view to manage the searching part. And then I have a button the user can tap to toggle filterByFavorites between true and false.
Post
Replies
Boosts
Views
Activity
Ok, I finally decided to just go with the App Group, but now I am getting an error in my preview container. This code:
struct PersistenceController {
...
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
let samplePokemon = Pokemon(context: viewContext)
samplePokemon.id = 1
samplePokemon.name = "bulbasaur"
samplePokemon.types = ["grass", "poison"]
samplePokemon.hp = 45
samplePokemon.attack = 49
samplePokemon.defense = 49
samplePokemon.specialAttack = 65
samplePokemon.specialDefense = 65
samplePokemon.speed = 45
samplePokemon.sprite = URL(string: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png")
samplePokemon.shiny = URL(string: "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/1.png")
samplePokemon.favorite = false
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
...
}
From my PersistenceController catches an error on the try viewContext.save() line when I try to run my widget, but it still works fine when running my app.
Here's my new app group shared container code in the same PersistenceController:
init(inMemory: Bool = false) {
let sharedStoreURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.myApGroup")!.appending(path: "Poke.sqlite")
let description = NSPersistentStoreDescription(url: sharedStoreURL)
container = NSPersistentContainer(name: "Poke")
if inMemory {
container.persistentStoreDescriptions = [description]
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
}
The error is not here, but again in my static var preview area when I try to save the viewContext.
Here's my console:
Any help with this would be much appreciated.
@deeje Obviously that's the solution if I can't get it to work the same way it did in beta 3, but I'd rather not do the extra work of creating an app group if I don't need it.