Обработка ошибок с использованием JSONDecoder в Swift

#json #swift

#json #swift

Вопрос:

Я использую JSONDecoder() в Swift и мне нужно получать более качественные сообщения об ошибках.

В описании отладки (например) Я могу видеть сообщения типа «Предоставленные данные не были действительными в формате JSON», но мне нужно знать, что это так, а не сетевая ошибка (например).

     let decoder = JSONDecoder()
    if let data = data{
        do {
            // process data

        } catch let error {
           // can access error.localizedDescription but seemingly nothing else
    }
  

Я попытался выполнить приведение к DecodingError , но, похоже, это не дает дополнительной информации. Мне, конечно, не нужна строка — даже код ошибки намного полезнее, чем это…

Комментарии:

1. Вы должны преобразовать ошибку к определенному типу, чтобы получить доступ к свойствам. Ознакомьтесь с документацией для получения более подробной информации. docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html

2. Я знаю, я пробовал DecodingError. Но в нем не больше деталей, чем в самой ошибке.

3. Можете ли вы опубликовать код, который вы пробовали? Это поможет нам получить больше информации о вашей проблеме.

4. print («Ошибка при чтении данных», ошибка как! Ошибка декодирования) печать («ошибка», error.localizedDescription) пусть decerr = ошибка как! Ошибка декодирования print (decerr.ErrorDescription) print («resaon», decerr.ErrorDescription)

Ответ №1:

Никогда не печатайте error.localizedDescription в блоке декодирования catch . Это возвращает совершенно бессмысленное общее сообщение об ошибке. Всегда выводите error экземпляр. Затем вы получаете желаемую информацию.

 let decoder = JSONDecoder()
    if let data = data {
        do {
            // process data

        } catch  {
           print(error)
    }
  

Или для полного набора ошибок используйте

 let decoder = JSONDecoder()
if let data = data {
    do {
       // process data
    } catch let DecodingError.dataCorrupted(context) {
        print(context)
    } catch let DecodingError.keyNotFound(key, context) {
        print("Key '(key)' not found:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch let DecodingError.valueNotFound(value, context) {
        print("Value '(value)' not found:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch let DecodingError.typeMismatch(type, context)  {
        print("Type '(type)' mismatch:", context.debugDescription)
        print("codingPath:", context.codingPath)
    } catch {
        print("error: ", error)
    }
  

Комментарии:

1. localizedDescription следует использовать только в том случае, если вам нужно что-то отобразить конечному пользователю.

2. Мне действительно нравится этот ответ. Единственным отличием — для моей собственной отладки — было исключение context переменной, поскольку она была слишком подробной. catch let DecodingError.keyNotFound(key, _) { print("[!]Key '(key)' not found")