Ответ 1
Ошибка компиляции
В какой строке есть ошибка компиляции? Мне кажется, что это будет строка:
.catchError {
error in
//...
return Observable.error(error) // is this the line causing the compilation error?
}
Если это так, вероятно, потому, что catchError
ожидает, что блок вернет Observable<Response>
, с которым он может продолжить в случае ошибки, а не Observable<ErrorType>
.
В любом случае, это помогает комментировать ваш код с большим количеством типов, чтобы вы могли точно определить такие проблемы, а также помочь компилятору Swift, который часто не может самостоятельно разобраться с этими вещами. Так что-то вроде этого помогло бы вам:
.catchError {
error -> Observable<Response> in
//...
return Observable.error(error) // Swift should have a more accurate and helpful error message here now
}
Обратите внимание, что я только показываю вам, что такое ошибка, и как получить Xcode, чтобы дать вам лучшие сообщения об ошибках. То, что вы пытаетесь вернуть, неверно.
Повторить только 401
Я не уверен, почему вы ожидаете, что этот код будет обрабатывать 401
по-другому (кроме публикации в центре уведомлений и регистрации). Как бы то ни было, вы уловили ошибку, но вы всегда возвращаете Observable
с событием Error
в конце (return Observable.error(error)
), поэтому он никогда не будет повторять попытку.
Чтобы выполнить попытку 401
, вы должны вернуть Observable
из блока retryWhen
, который отправит событие Next
(означающее, что вы хотите повторить попытку). Для всех остальных кодов состояния Observable
должен отправить Error
(как вы сейчас делаете), что означает, что вы не хотите повторять попытку, и что вы хотите, чтобы ошибка распространялась.
Так что-то вроде этого:
.retryWhen { errorObservable -> Observable<ErrorType> in
log.debug("ReAuth error: \(error)")
if case Error.StatusCode(let response) = error where response.statusCode == 401 {
log.debug("401:, force user logout")
NSNotificationCenter.defaultCenter().postNotificationName(Constants.Notifications.userNotAuthenticated, object: nil, userInfo: nil)
// If `401`, then return the `Observable<ErrorType>` which was given to us
// It will emit a `.Next<ErrorType>`
// Since it is a `.Next` event, `retryWhen` will retry.
return errorObservable
}
else {
// If not `401`, then `flatMap` the `Observable<ErrorType>` which
// is about to emit a `.Next<ErrorType>` into
// an `Observable<ErrorType>` which will instead emit a `.Error<ErrorType>`.
// Since it is an `.Error` event, `retryWhen` will *not* retry.
// Instead, it will propagate the error.
return errorObservable.flatMap { Observable.error($0) }
}
}