Это приложение с меню. Существует функция, которая извлекает пункты меню из вызова 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")
Предикат строится следующим образом:
Код: Выделить всё
private func buildPredicate() -> NSPredicate {
if searchText.isEmpty {
NSPredicate(value: true)
} else {
NSPredicate(format: "name CONTAINS[cd] %@", searchText)
}
}
Я понимаю, что есть много кода, который я не включил; если я упустил что-то, что кажется важным/необходимым, я могу дополнить. Еще одна вещь, которую я заметил и которая может иметь значение, это то, что функция, загружающая блюда, действительно вызывается дважды. Но первый вызов получает 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)")
}
}
Код, который фактически выполняет загрузку:
Код: Выделить всё
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")
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... hedobjects
Мобильная версия