SwiftData fetch returns 37 objects on Device A and 0 objects on Device B

47 Views Asked by At

This is driving me crazy. Device A is an iPhone14 Pro running 17.3. Device B is an iphone13 running 17.3.1. In the following fetch, I get 37 objects returned on Device A. Running the exact same code on Device B is giving me 0 objects. WTH?

let categoryFetchDescriptor = FetchDescriptor<Category>(predicate: #Predicate {
    $0.isActive == true &&
    $0.woozles.count > 2
}, sortBy: [SortDescriptor(\.sortPriority, order: .forward)])
            
let allCategories = try! modelContext.fetch(categoryFetchDescriptor)
print("fetched active categories: \(allCategories.count)") //37 on one device, 0 on the other

Category is defined like this:

@Model
class Category: Decodable, Identifiable, ObservableObject {
    var id: Int
    var title: String
    var isActive: Bool
    @Relationship var woozles = [Woozle]()
    ...
}

How is this possible? Also, in a view I can do this:

@Query var categories: [Category]
...

.onAppear {
    print ("categories in SwiftData: \(categories.count)")
}

And that shows 37 category objects in SwiftData on both devices.

But I have to do the fetching the viewModel because there's a lot of manipulation going on based on UI. What is wrong with the fetch that it would fail on one device and not the other?

EDIT: The fetch also gives 0 results on an iPhone13 simulator running 17.2

1

There are 1 best solutions below

1
soleil On

I think I have fixed this by moving $0.woozles.count > 2 out of the predicate and then filtering. I'd love to know more about why we can't use multiple conditions in the predicate.

let categoryFetchDescriptor = FetchDescriptor<Category>(predicate: #Predicate {
    $0.isActive == true
}, sortBy: [SortDescriptor(\.sortPriority, order: .forward)])
            
let allCategories = try! modelContext.fetch(categoryFetchDescriptor)
            
let validCategories = allCategories.filter { $0.woozles.count >= 2 }