То, что у вас хорошо выглядит, за исключением нескольких подходов к обработке ошибок.В одном случае вы используете try?
, а в другом - do... catch
, и, вероятно, ваш getJsonData(url:)
может выдать наблюдаемую ошибку.Вы повсюду.Я предлагаю вам выбрать одну систему обработки ошибок и придерживаться ее.Самый гибкий - 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) }
}
Обратите внимание, что я просто позволяю ошибкам декодирования переходить в событие наблюдаемой ошибки.Не нужно иметь дело с 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)
}
}
Поскольку вы терпите крах, если любая из попыток все равно не удалась, просто положите на них !
.Это имеет тот же эффект.Вам следует рассмотреть возможность помещения блока ошибок в отдельную тестируемую функцию, потому что нет никакой гарантии, что вы попадете на него во время обычного запуска программы, и он может быть сломан, даже если вы этого не заметите.
Наконец,с учетом вышесказанного нет причин предоставлять обработчик onError:
в подписке, поскольку наблюдаемая getConfigFile()
никогда не выдаст ошибку.Возможно, вы захотите, чтобы функция возвращала драйвер, чтобы сделать этот факт более явным.