gpt4 book ai didi

ios - 在 Combine 中处理发布者错误的最佳实践是什么? (从 CoreLocation 发布航向更新)

转载 作者:行者123 更新时间:2023-11-28 23:24:02 24 4
gpt4 key购买 nike

我一直在开发一个带有指南针的应用程序,它根据 this example 更新其标题。用于发布标题更改和 this example用于创建发布者来处理这些更改。

我是响应式编程的新手,但我遇到的问题似乎是一个常见问题,所以我想发布它,看看是否有人可以提供帮助。

有时它会工作一段时间,发布者会发布新标题并更新用户界面,但随后就会停止工作。其他时候,它永远不会开始更新(在任何标题更新之前都会传递错误)。无论哪种情况,事件都会停止,因为失败完成事件被发送到发布者:

func locationManager(_ manager: CLLocationManager,
didFailWithError error: Error) {

headingPublisher.send(completion: Subscribers.Completion.failure(error))

print("error: \(error.localizedDescription)")
}

首先,我试图弄清楚这些错误是什么,以便我可以尝试更好地处理它们……这些错误真的值得让发布商停止吗?我想知道标题更新的中途会发生什么样的错误,因为标题更新在错误后恢复,即使发布者停止。我尝试打印错误,但我得到的只是这个,这似乎没有帮助:错误:操作无法完成。 (kCLErrorDomain 错误 0。)

我不擅长 iOS,所以如果有人对如何在此处获得更好的错误描述有任何建议,请告诉我。

其次,我想知道如何忽略订阅发布者的错误,如果这是我应该做的,那么即使出现错误,.sink 也会继续获取航向更新.下面是我的发布商代码,基于示例:

    _ = headingProxy
.publisher
.receive(on: RunLoop.main)
.sink(receiveCompletion: { completion in },
receiveValue: { [weak self] (heading) in
self?.currentHeadingAccuracy = heading.headingAccuracy
self?.currentHeading = heading.trueHeading
})
.store(in: &cancellableSet)

我意识到我永远无法将错误发送给发布者(这是我应该做的吗?有一个特定的发布者只用于从不发送错误的标题更新?)但我假设做这件事的人包括发送有充分理由向发布者报告错误,最好的做法是在订阅端处理错误,或者有一些最佳做法可以在错误后恢复。

最佳答案

正如您所指出的,当发生错误时,将始终终止使用现成运算符构建的 Combine 管道。这是一个功能,而不是错误。特别令人惊讶的是,即使您使用像 catch 这样的错误处理运算符,管道也会结束。或 replaceError .

您可以通过包装可能在 flatMap 中发生错误的管道的任何部分来使管道对错误具有弹性.

将您的主管道视为“外部”管道,并将管道包裹在 flatMap 中作为“内部”管道。确保外部管道的错误类型是 Never它可以永远继续处理值。

考虑一个返回数字平方的端点:

let myNumberPublisher = PassthroughSubject<Int, Never>()

// Outer pipeline will never error (the Error type is Never):
myNumberPublisher
.map(String.init) // convert to string
.flatMap { number in
// Inner pipeline can error:
URLSession.shared.dataTaskPublisher(for: URL(string: "https://square?n=\(number)")!)
.replaceError(with: "Oopsies")
.map { answer in "The answer is \(answer)" }
}
.sink { result in print(result) }

myNumberPublisher.send("5")
// => The answer is 25
myNumberPublisher.send("3") // assume the endpoint errors here
// => The answer is Oopsies
myNumberPublisher.send("6")
// => The answer is 36


使用flatMap在您的情况下,出售发布者的类可能会要求您在发生错误时随时请求新的发布者。

或者,您可以修改您的 headingPublisher有一个Never错误类型。如果你走这条路,错误应该由提供 headingPublisher 的对象处理。 .

另一种选择是出售两个发布者,一个用于值,另一个用于错误:

  • AnyPublisher<ValueType, Never>
  • AnyPublisher<Error, Never>

这些选项中的任何一个都可以使用,您选择的选项将取决于您的需求。

关于ios - 在 Combine 中处理发布者错误的最佳实践是什么? (从 CoreLocation 发布航向更新),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59148845/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com