如果Alamofire请求失败,如何从服务器解析失败状态JSON

时间:2018-09-28 20:15:14

标签: ios json swift alamofire

下面是一个我向服务器发出AF请求的用例。函数“ manage”进行调用,并使用“ 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() }
    }

}

0 个答案:

没有答案