在performBackgroundTask关闭中引发异常

时间:2018-10-26 05:06:57

标签: swift core-data swift4.2

有一个功能,我可以使用Cora Data将Web响应中的数据存储到数据库中。如果某些数据丢失,或者为空或null等,则该函数应引发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 :(得分:1)

不幸的是,这并不容易。 如果processLittleItems的调用者期望该函数发生异常(或返回值),则它必须等待直到所有内容都存储完为止。因此,在这种情况下,异步处理将不起作用。 因此,您必须重新考虑如何在应用程序中进行错误处理:

  • processLittleItems的调用者都需要等待,因此您必须删除后台作业并同步进行所有操作
  • 否则,调用者不得等待(因为这会阻止UI线程)。在这种情况下,调用者可以提供一个完成处理程序,然后您将从后台封闭程序内部完成该处理程序并上交错误/成功代码。

答案 1 :(得分:1)

Andreas Oetjen对此是正确的。您基本上会为同步方法而不是异步方法抛出异常。

一个选项是根据逻辑定义您自己的完成处理程序或回调,并使用它向后发送错误并在需要时使用它。 样本:

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

以及发生异常时。 completion('your exception', nil)

希望有帮助。