Как прочитать значения свойств объекта ошибки JSON с помощью Combine в Swift? - PullRequest
0 голосов
/ 28 мая 2020

Все мои конечные точки API возвращают ответ, который в Postman выглядит примерно так:

{
    "statusCode": 401,
    "error": "Unauthorized",
    "message": "Missing authentication"
}

Я хотел бы сделать запрос и получить доступ к этим свойствам в Swift. В некоторых случаях я использую значение свойства сообщения об ошибке в начале приложения. Это будет определяться возвращенным statusCode.

Сейчас у меня есть следующее:

    private var cancellable: AnyCancellable?
    let url = URL(string: "http://abc336699.com/create")
    self.cancellable = URLSession.shared.dataTaskPublisher(for: url!)
      .map { $0.data }

До этого я пробовал tryMap, но тип возвращаемой ошибки не дайте мне необходимую гибкость. Затем я двинулся дальше и попробовал Almofire, но мне показалось, что это излишнее убийство того, что я хочу сделать.

Я хотел проверить, что возвращается в полученном мной ответе, но получаю следующую ошибку:

Cannot assign value of type 'Publishers.Map<URLSession.DataTaskPublisher, Data>' to type 'AnyCancellable'

Мне нужен простой доступ к моим ошибкам ответа, чтобы я мог интегрировать API во все приложение с помощью комбайна.

1 Ответ

1 голос
/ 29 мая 2020

Я не уверен, откуда вы будете получать свои данные, так как в ответе JSON нет ключа для данных. Перед написанием приведенного ниже кода я понял, что вы хотите проверить error и statusCode из упомянутого ответа JSON, а затем перейти к своему бизнес-логу c. Приведенный ниже код дает вам смутное представление о том, как это сделать.

    enum CustomError: Error {

    case custom(_ error: String)
    case unknownStatusCode
    case errorOccurred
}

let url = URL(string: "http://abc336699.com/create")

    func load() -> AnyPublisher<Data,CustomError> {
    URLSession.shared.dataTaskPublisher(for: url!)
        .map(\.data)
        .tryMap { (data) -> Data in
            let genericModel = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: AnyObject]

            if let statusCode = genericModel?["statusCode"] as? String {
                switch statusCode {
                case "200":
                    guard let data = genericModel?["message"] as? Data else {
                        throw CustomError.custom("Parsing error")
                    }
                    return data
                default:
                    if let error = genericModel?["error"] as? String {
                        throw CustomError.custom(error)
                    } else {
                        throw CustomError.unknownError
                    }
                }
            }
            throw CustomError.errorOccurred
    }
    .decode(type: YourCustomDecodableModel.self, decoder: JSONDecoder())
    .mapError({ $0 as? CustomError ?? CustomError.errorOccurred })
    .eraseToAnyPublisher()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...