Как я должен правильно использовать инструкцию guard с RxSwift Singles?

#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