Как проанализировать состояние ошибки JSON с сервера, если запрос Alamofire не выполнен - PullRequest
0 голосов
/ 28 сентября 2018

Ниже приведен пример использования, который я использую для отправки запроса AF на сервер.Функция «управление» выполняет вызов и сериализует ответ с помощью «GetCommentsResponseModel».Если результатом AF является сбой или если я не могу сериализовать ответ на мою модель, будет другой JSON с сервера с сообщением о состоянии и кодом состояния.Мне нужно получить сообщение о состоянии и показать его в оповещении.

import Dispatch
import Alamofire

final public class FetchCommentsUseCase: UseCase<Int, GetCommentsResponseModel> {

    // MARK: - Properties

    private let networkRequester = NetworkRequester()
    private var request: DataRequest?
    private var workItems: [DispatchWorkItem] = []
    private var resultModel: GetCommentsResponseModel!

    // MARK: - Private methods

    private func decode(request: DataRequest) -> Result<DataRequest> {
        self.request = request
        let semaphore = DispatchSemaphore(value: 0)
        defer { semaphore.wait() }
        return .success(request.responseJSONDecodable(queue: .additional) { self.manage(response: $0, with: semaphore) })
    }

    private func manage(response: DataResponse<GetCommentsResponseModel>, with semaphore: DispatchSemaphore) {
        guard response.result.value?.status == "success", let value = response.result.value else {
            propagate(error: NetworkError.invalidResponse(error: response.result.error))
            return
        }
        resultModel = value
        semaphore.signal()
    }

    private func propagate(error: Error) {
        DispatchQueue.main.async { [unowned self] in
            self.errorHandler?({ throw error })
            self.alwaysCompletion?()
            self.cancel()
        }
    }

    fileprivate func getComments(for sno: Int) {
        networkRequester.execute(request: CommentsConvertible.getComments(sno: sno))
            .next(decode)
            .next(propagate)
    }

    fileprivate func finished() -> (() -> Void) {
        return {
            self.successCompletion?(self.resultModel)
            self.alwaysCompletion?()
        }
    }

    // MARK: - Public methods

    public override func execute(with sno: Int) -> Self {
        let getComments = workItem(sno) { self.getComments(for: $0) }
        workItems.append(getComments)
        DispatchQueue.networking.async(execute: getComments)
        getComments.notify(queue: .main, execute: finished())

        return self
    }

    public override func cancel() {
        request?.cancel()
        successCompletion = nil
        alwaysCompletion = nil
        workItems.forEach { $0.cancel() }
    }

}
...