1

I've been working on a fetch request which seems to working fine using the answer here: https://stackoverflow.com/a/60723054/1254397

import CoreData
import SwiftUI

struct DynamicFetchView<T: NSManagedObject, Content: View>: View {
    let fetchRequest: FetchRequest<T>
    let content: (FetchedResults<T>) -> Content

    var body: some View {
        self.content(fetchRequest.wrappedValue)
    }

    init(predicate: NSPredicate?, fetchLimit:Int = 5, sortDescriptors: [NSSortDescriptor], @ViewBuilder content: @escaping (FetchedResults<T>) -> Content) {
        fetchRequest = FetchRequest<T>(entity: T.entity(), sortDescriptors: sortDescriptors, predicate: predicate, fetchLimit)
        self.content = content
    }

    init(fetchRequest: NSFetchRequest<T>, @ViewBuilder content: @escaping (FetchedResults<T>) -> Content) {
        self.fetchRequest = FetchRequest<T>(fetchRequest: fetchRequest)
        self.content = content
    }
}

In my view:

DynamicFetchView(predicate: NSPredicate(format: "Brand CONTAINS %@", "GAP"), sortDescriptors: [NSSortDescriptor(keyPath: \store.brandName, ascending: false)]) { (clothing: FetchedResults<Store>) in
    HStack {
        Text("Number of Gap products: \(clothing.count)")
            .bold()
            .underline()
        List {
            ForEach(clothing) { Store in
                Text("Clothing Name: \(Store.clothingName!)")
            }
        }
    }

the DynamicFetchView works well to show everything in the fetch request, however I would like to limit it to 5. I tried adding fetchLimit=5 but that didn't seem to make any difference.

TylerP
  • 9,600
  • 4
  • 39
  • 43
zeem
  • 95
  • 10

1 Answers1

1

Here is a solution:

struct DynamicFetchView<T: NSManagedObject, Content: View>: View {
    let fetchRequest: FetchRequest<T>
    let content: (FetchedResults<T>) -> Content

    var body: some View {
        self.content(fetchRequest.wrappedValue)
    }

    init(predicate: NSPredicate?, fetchLimit:Int = 5, sortDescriptors: [NSSortDescriptor], @ViewBuilder content: @escaping (FetchedResults<T>) -> Content) {
        guard let entityName = T.entity().name else { fatalError("Unknown entity") }

        let request = NSFetchRequest<T>(entityName: entityName)
        request.fetchLimit = fetchLimit
        request.sortDescriptors = sortDescriptors
        request.predicate = predicate

        self.init(fetchRequest: request, content: content)
    }

    init(fetchRequest: NSFetchRequest<T>, @ViewBuilder content: @escaping (FetchedResults<T>) -> Content) {
        self.fetchRequest = FetchRequest<T>(fetchRequest: fetchRequest)
        self.content = content
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • Wow thank you so much really appricaite it, worked perfectly, just one small question is it possible to state how many results i want in my view when i call the DynamicFetchView? – zeem May 06 '20 at 10:43
  • @zeem, what do you mean? Just specify in constructor `DynamicFetchView(predicate: NSPredicate(...), fetchLimit: 10, sortDescriptors...` – Asperi May 06 '20 at 10:52
  • my bad, i read it was just always going to return 5 results, added in the contructor and bingo it worked. Once again thank you so much! – zeem May 06 '20 at 11:10