Создание исключения в закрытии executeBackgroundTask - PullRequest
0 голосов
/ 26 октября 2018

Есть функция, я храню данные из веб-ответа в моей базе данных, используя Cora Data. Функция должна выдавать исключение DataError, если некоторые данные отсутствуют, или пустые или нулевые и т. Д. Операции с базой данных должны выполняться в фоновом режиме с privateQueueContext. Перед сохранением данных в базе данных я проверяю, существует ли она уже (через fetchRequest). Если результат пуст, я начинаю обрабатывать данные и сохранять их в базе данных.

Я могу выдать исключение за пределами замыкания, но я бы тоже хотел выбросить исключение в замыкании performBackgroundTask, но я получаю ошибку сборки.

Вот метод:

private func processLittleItems(informationsFromWebServiceResponse : GetInformationsFromWebServiceResponse) throws {
    guard let littleItemListDataFromResponse = informationsFromWebServiceResponse.littleItemList else {
        throw DataError.dataMissing("littleItemList")
    }
    CoreDataStack.shared.persistentStoreContainer.performBackgroundTask { privateQueueContext in
        for littleItem in littleItemListDataFromResponse {
            let littleItemRequest = LittleItem.fetchRequest() as NSFetchRequest<LittleItem>
            littleItemRequest.predicate = NSPredicate(format: "id = %@", littleItem.iD!)
            littleItemRequest.fetchLimit = 1

            do {
                let littleItemlist = try privateQueueContext.fetch(littleItemRequest)
                if (littleItemlist.isEmpty) {
                    let newLittleItem = LittleItem(context: privateQueueContext)
                    guard let littleItemId = littleItem.iD else {
                        return  // HERE SHOULD BE THROW EXCEPTION, NOT JUST A RETURN
                    }
                    newLittleItem.id = littleItemId

                    newLittleItem.optionalThing = littleItem.optionalThing ?? false
                }
            } catch let error as NSError {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
        do {
            try privateQueueContext.save()
        } catch let error as NSError {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    }
}

Не могли бы вы помочь с этим?

Заранее благодарим за любую помощь, которую вы можете оказать.

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Андреас Отьен прав насчет этого.вы бросаете в основном исключения для методов синхронизации, а не асинхронных методов.

Один из вариантов - это определить собственный обработчик завершения или обратный вызов в зависимости от вашей логики и использовать его для отправки ошибки назад и использования при необходимости.пример:

private func processLittleItems(informationsFromWebServiceResponse : GetInformationsFromWebServiceResponse, completion: (_ error: Error?, object: Any?) -> Void)

и при возникновении исключения.completion('your exception', nil)

надеюсь, это поможет.

0 голосов
/ 26 октября 2018

К сожалению, это не так просто. Если вызывающий processLittleItems ожидает исключения (или возвращаемого значения) из функции, он должен ждать, пока все не будет сохранено. Следовательно, асинхронная обработка не будет работать в этом случае. Поэтому вы должны переосмыслить порядок обработки ошибок в вашем приложении:

  • Либо абонент processLittleItems должен подождать, поэтому необходимо удалить фоновое задание и сделать все синхронно
  • Или вызывающая сторона не должна ждать (потому что это заблокирует поток пользовательского интерфейса). В этом случае вызывающая сторона может предоставить обработчик завершения, который вы затем изнутри своего фонового закрытия и передадите код ошибки / успеха.
...