#ios #swift #rx-swift
#iOS #swift #rx-swift
Вопрос:
Представьте, что у меня есть сетевой клиент, использующий RxSwift
для переноса URLSession
.
Я хотел бы использовать guard
инструкцию и вернуть ошибку, однако я получаю ошибку, которая
Функция Non-void должна возвращать значение
Что имеет смысл, однако я не уверен, как справиться с этим с RxSwift
.
class NetworkClient {
var task: URLSessionDataTask = URLSessionDataTask()
var session: SessionProtocol = URLSession.shared
var request: URLRequest?
func call<T: Codable>(_ request: URLRequest) -> Single<T> {
return Single<T>.create(subscribe: { [weak self] observer -> Disposable in
guard let `self` = self else { observer(.error(NSError(domain: "", code: 0, userInfo: [:]))); return }
self.task = self.session.dataTask(with: request, completionHandler: { data, response, error in
})
return Disposables.create {
self.task.cancel()
}
})
}
}
Комментарии:
1. Примечание:
observer(.error(NSError(domain: "", code: 0, userInfo: [:]))
Мне бы очень не понравилось, если бы я столкнулся с ошибкой без сообщения, кода или информации о пользователе.2. Конечно, я просто собрал очень простой пример, который будет компилироваться. Это ни в коем случае не ошибка, которую я бы когда-либо вернул в любом приложении 🙂
3. Хорошо, просто проверяю 🙂
Ответ №1:
Просто используйте:
guard let `self` = self else { observer(.error(NSError(domain: "", code: 0, userInfo: [:]))); return Disposables.create() }
Тем не менее, я должен сказать, что я совсем не фанат этого класса. Во-первых, RxSwift уже имеет оболочку вокруг dataTask:
func response(request: URLRequest) -> Observable<(response: HTTPURLResponse, data: Data)>
который может быть вызван с помощью:
URLSession.shared.rx.response(request: myRequest)
Также есть data(request:)
который проверяет StatusCode и выдает ошибку, если ее нет в 200-х годах.
Вы можете просто внедрить функцию вместо того, чтобы усложнять ее перенос в объект, который не предоставляет добавленной стоимости. Например:
struct MyViewModel {
init(serverResponse: @escaping (URLRequest) -> Observable<Data>)...
}
Который может быть вызван с помощью:
let myViewModel = MyViewModel(serverResponse: URLSession.shared.rx.data)
При тестировании вы можете просто передать замыкание, которое возвращает Observable<Data>.just(myTestData)
.
Комментарии:
1. Большое вам спасибо за все ваши комментарии. Я очень ценю, что вы нашли время поделиться своими мыслями, они также были невероятно полезны.
2. Приятно, у тебя есть блог, Дэниел?
3.medium.com/@danielt1263 У меня также есть несколько примеров проектов: github.com/danielt1263/RxMyCoordinator github.com/danielt1263/RxEarthquake github.com/danielt1263/RxMultiCounter