从回调创建发布者
Make a Publisher from a callback
我想包装一个简单的回调,以便它能够用作 Combine Publisher
。特别是 NSPersistentContainer.loadPersistentStore 回调,这样我就可以在容器准备就绪时发布。
func createPersistentContainer(name: String) -> AnyPublisher<NSPersistentContainer, Error> {
// What goes here?
// Happy path: send output NSPersistentContainer; send completion.
// Not happy path: send failure Error; send completion.
}
例如,上面给出的 createPersistentContainer
函数的内部结构如何使我能够在我的 AppDelegate
.
中执行类似的操作
final class AppDelegate: UIResponder, UIApplicationDelegate {
let container = createPersistentContainer(name: "DeadlyBattery")
.assertNoFailure()
.eraseToAnyPublisher()
// ...
}
主要归结为,如何将回调包装在 Publisher
中?
Combine 的 Future
似乎是完成这项工作的正确工具。
func createPersistentContainer(name: String) -> AnyPublisher<NSPersistentContainer, Error> {
let future = Future<NSPersistentContainer, Error> { promise in
let container = NSPersistentContainer(name: name)
container.loadPersistentStores { _, error in
if let error = error {
promise(.failure(error))
} else {
promise(.success(container))
}
}
}
return AnyPublisher(future)
}
作为之前的发帖人之一@Ryan ,解决方案是使用 Future
发布者。
不过,仅使用 Future
的问题在于它是急切的,这意味着它在创建时开始执行其 promise 闭包,而不是在订阅时开始执行。该挑战的答案是将其包装在 Deferred
发布者中:
func createPersistentContainer(name: String) -> AnyPublisher<NSPersistentContainer, Error> {
return Deferred {
Future<NSPersistentContainer, Error> { promise in
let container = NSPersistentContainer(name: name)
container.loadPersistentStores { _, error in
if let error = error {
promise(.failure(error))
} else {
promise(.success(container))
}
}
}
}.eraseToAnyPublisher()
}
NSPersistentContainer
只是围绕核心数据堆栈的便利包装,您最好订阅源代码:
NotificationCenter.default.publisher(for: .NSPersistentStoreCoordinatorStoresDidChange)
我想包装一个简单的回调,以便它能够用作 Combine Publisher
。特别是 NSPersistentContainer.loadPersistentStore 回调,这样我就可以在容器准备就绪时发布。
func createPersistentContainer(name: String) -> AnyPublisher<NSPersistentContainer, Error> {
// What goes here?
// Happy path: send output NSPersistentContainer; send completion.
// Not happy path: send failure Error; send completion.
}
例如,上面给出的 createPersistentContainer
函数的内部结构如何使我能够在我的 AppDelegate
.
final class AppDelegate: UIResponder, UIApplicationDelegate {
let container = createPersistentContainer(name: "DeadlyBattery")
.assertNoFailure()
.eraseToAnyPublisher()
// ...
}
主要归结为,如何将回调包装在 Publisher
中?
Combine 的 Future
似乎是完成这项工作的正确工具。
func createPersistentContainer(name: String) -> AnyPublisher<NSPersistentContainer, Error> {
let future = Future<NSPersistentContainer, Error> { promise in
let container = NSPersistentContainer(name: name)
container.loadPersistentStores { _, error in
if let error = error {
promise(.failure(error))
} else {
promise(.success(container))
}
}
}
return AnyPublisher(future)
}
作为之前的发帖人之一@Ryan Future
发布者。
不过,仅使用 Future
的问题在于它是急切的,这意味着它在创建时开始执行其 promise 闭包,而不是在订阅时开始执行。该挑战的答案是将其包装在 Deferred
发布者中:
func createPersistentContainer(name: String) -> AnyPublisher<NSPersistentContainer, Error> {
return Deferred {
Future<NSPersistentContainer, Error> { promise in
let container = NSPersistentContainer(name: name)
container.loadPersistentStores { _, error in
if let error = error {
promise(.failure(error))
} else {
promise(.success(container))
}
}
}
}.eraseToAnyPublisher()
}
NSPersistentContainer
只是围绕核心数据堆栈的便利包装,您最好订阅源代码:
NotificationCenter.default.publisher(for: .NSPersistentStoreCoordinatorStoresDidChange)