(Изначально) получение повторяющихся результатов из FetchedObjectsIOS

Программируем под IOS
Ответить
Anonymous
 (Изначально) получение повторяющихся результатов из FetchedObjects

Сообщение Anonymous »

Я хожу на курсы программирования для iOS и работаю над классным проектом, связанным с базовыми данными, фильтрацией и сортировкой. Класс плохо преподает, но я близок к этому. Я не хочу, чтобы кто-то делал за меня мой проект, но, думаю, я запутался в отладке того, что сейчас вижу.
Это приложение с меню. Существует функция, которая извлекает пункты меню из вызова Rest и добавляет их в объект Core Data. Я вполне уверен, что мне позвонят и вставят 12 элементов в сущность «Блюдо».
У меня есть представление, которое пытается позволить вам просмотреть все блюда, оно включает панель поиска для сужения поиска. Когда я впервые вижу это представление загруженным, оно показывает 24 блюда; каждое блюдо появляется дважды. Код для этого:

Код: Выделить всё

NavigationView {
FetchedObjects(
predicate: buildPredicate(),
sortDescriptors: buildSortDescriptors()
) { (dishes: [Dish]) in
List {
Text(String(dishes.count) + " dishes")

ForEach(dishes, id: \.self) { dish in
DisplayDish(dish).onTapGesture { apGesture in
self.showAlert.toggle()
}
}
}
}
}.searchable(text: $searchText, prompt: "Search items")
(Я включил этот текст вместе с количеством блюд, чтобы сузить суть происходящего, и он действительно говорит, что при первом появлении представления есть 24 блюда)
Предикат строится следующим образом:

Код: Выделить всё

private func buildPredicate() -> NSPredicate {
if searchText.isEmpty {
NSPredicate(value: true)
} else {
NSPredicate(format: "name CONTAINS[cd] %@", searchText)
}
}
Я очень открыт для возможности того, что делаю что-то не так, хех. Но вот что меня действительно сбивает с толку: если я ввожу что-то в строку поиска, она не только правильно фильтрует, но и не находит дубликатов. Это немного странно. Теперь я очищаю строку поиска и прекращаю поиск, поэтому мне следует вернуться к использованию истинного предиката, и теперь он говорит, что есть 12 блюд и не показывает дубликатов. Все это заставляет меня думать, что на самом деле в сущности всего 12 блюд, и мое внимание сужается до выяснения того, почему FetchObjects возвращает 24 при первом использовании представления.
Я понимаю, что есть много кода, который я не включил; если я упустил что-то, что кажется важным/необходимым, я могу дополнить. Еще одна вещь, которую я заметил и которая может иметь значение, это то, что функция, загружающая блюда, действительно вызывается дважды. Но первый вызов получает NSError об отмене, предположительно потому, что второй приземляется и заменяет его, и когда пыль очищается, функция загрузки фактически сохраняет только один раз, и запрос сразу после этого показывает 12 блюд, а не 24.
Любая помощь будет принята с благодарностью.
Как загружаются данные:
Через их код, есть эта задача в ранее упомянутом Просмотр навигации:

Код: Выделить всё

.task {
await dishesModel.reload(viewContext)
}
Эта перезагрузка выглядит так:

Код: Выделить всё

    func reload(_ coreDataContext:NSManagedObjectContext) async {
let url = URL(string: "https://raw.githubusercontent.com/Meta-Mobile-Developer-PC/Working-With-Data-API/main/littleLemonSimpleMenu.json")!
let urlSession = URLSession.shared

do {
let (data, _) = try await urlSession.data(from: url)
let fullMenu = try JSONDecoder().decode(JSONMenu.self, from: data)
menuItems = fullMenu.menu

// populate Core Data
print("Before: \(menuItems.count)")
Dish.deleteAll(coreDataContext)
Dish.createDishesFrom(menuItems:menuItems, coreDataContext)
print("After: \(menuItems.count)")

}
catch let error as NSError {
print("found the problem: \(error.localizedDescription)")
}
}
Большая часть этого была предоставлена ​​ими, но кое-что я написал, и эта отладка убедила меня, что она отменяется один раз и завершается только с 12 блюдами.
Код, который фактически выполняет загрузку:

Код: Выделить всё

    static func exists(context: NSManagedObjectContext, title: String) -> Bool {
let request: NSFetchRequest = Dish.fetchRequest()
request.predicate = NSPredicate(format: "name == %@", title)
return try! context.fetch(request).count > 0
}

static func createDishesFrom(menuItems:[MenuItem],
_ context:NSManagedObjectContext) {
print("Creating dishes from menu")
menuItems.forEach { menuItem in
if !Dish.exists(context: context, title: menuItem.title) {
let dish = Dish(context: context)
dish.name = menuItem.title
dish.price = Float(menuItem.price) ?? 0.0
print("Added dish \(menuItem.title)")
}
}

do {
guard context.hasChanges else {
return
}
try context.save()
}
catch {
print("error trying to save dishes")
}

let request: NSFetchRequest = Dish.fetchRequest()
request.predicate = NSPredicate(value: true)
let results = try! context.fetch(request)
print("Fetched \(results.count) dishes")
}
Это снова указывает на то, что было получено 12 блюд, а не 24.

Подробнее здесь: https://stackoverflow.com/questions/798 ... hedobjects
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»