我是 RxSwift 的新手。我有一个 BackendProvider 来处理与我的 API 的通信。我想要一个配置文件同步,以便我可以动态检索一些参数。我有一个后备案例,其中包含一个本地存储的 JSON 文件,如果我的 API 无法访问或我的 JSON 解析失败,我可以访问该文件:
ConfigFileBackendService
open func getLatestConfig() -> Observable<ConfigFile?> {
let urlString = IoC.urlProviderService.getConfigFileUrl()?.absoluteString ?? ""
let configFileJSONData = IoC.backendCommunicationService.getJsonData(url: urlString)
return configFileJSONData.map { data in
if let configFile = try? JSONDecoder().decode(ConfigFile.self, from: data) {
return configFile
} else {
return nil
}
}
}
ConfigFileProcessService
这是回退到本地存储文件的那个:
func getConfigFile() -> Observable<ConfigFile> {
return IoC.configFileBackendService.getLatestConfig()
.map { configFile in
guard let configFile = configFile else { fatalError() }
return configFile
}
.catchError { error in
// Use default config
let localURL = IoC.urlProviderService.getLocalConfigFileUrl()
do {
let data = try Data(contentsOf: localURL)
let configFile = try JSONDecoder().decode(ConfigFile.self, from: data)
return Observable.just(configFile)
} catch {
fatalError("Error loading local config")
}
}
}
这种方法有效,但我对 .map
/.catchError
block 有疑问。有没有更好的方法来处理错误情况?也许我应该先使用 onNext
然后使用 onError
?提前致谢!
最佳答案
除了处理错误的多种方法外,您所拥有的看起来不错。在一种情况下你使用 try?
而另一种情况使用 do...catch
并且你的 getJsonData(url:)
可能会发出一个 Observable 错误.你无处不在。我建议您选择一种错误处理系统并坚持使用。最灵活的是 Event.error
。所以像这样:
func getLatestConfig() -> Observable<ConfigFile> {
let urlString = IoC.urlProviderService.getConfigFileUrl()?.absoluteString ?? ""
let configFileJSONData = IoC.backendCommunicationService.getJsonData(url: urlString)
return configFileJSONData.map { try JSONDecoder().decode(ConfigFile.self, from: $0) }
}
请注意,我只是让解码错误路由到一个 Observable 错误事件中。无需以这种方式处理 nil
。
func getConfigFile() -> Observable<ConfigFile> {
return IoC.configFileBackendService.getLatestConfig()
.catchError { _ in
let localURL = IoC.urlProviderService.getLocalConfigFileUrl()
let data = try! Data(contentsOf: localURL)
let configFile = try! JSONDecoder().decode(ConfigFile.self, from: data)
return Observable.just(configFile)
}
}
如果任何一个尝试都失败了,你就会崩溃,所以只需在它们上面放一个 !
。它具有相同的效果。您应该考虑将错误 block 放入一个单独的、可测试的函数中,因为不能保证您会在程序的常规运行期间命中它,并且它可能在您没有意识到的情况下被破坏。
最后,对于上面的内容,没有理由在订阅中提供 onError:
处理程序,因为 getConfigFile()
observable 永远不会发出错误。您可能希望函数返回一个驱动程序,而不是让事实更明确。
关于ios - 在 RxSwift 中解析 JSON 并处理来自 API 的错误响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53867736/