поэтому он может обрабатывать отсутствие конкретного параметра в ответ и установить значение как

ользуюCodable протокол от Swift 4 в первый раз, я не могу понять использованиеdecodeIfPresent изDecodable.

/// Decodes a value of the given type for the given key, if present.
///
/// This method returns `nil` if the container does not have a value associated with `key`, or if the value is null. The difference between these states can be distinguished with a `contains(_:)` call.
///
/// - parameter type: The type of value to decode.
/// - parameter key: The key that the decoded value is associated with.
/// - returns: A decoded value of the requested type, or `nil` if the `Decoder` does not have an entry associated with the given key, or if the value is a null value.
/// - throws: `DecodingError.typeMismatch` if the encountered encoded value is not convertible to the requested type.
public func decodeIfPresent(_ type: String.Type, forKey key: KeyedDecodingContainer.Key) throws -> String?

Здесь это предполагает, что это возвращаетnil, если значение отсутствует со связанным ключом. Если это единственная причина, то чем она отличается от необязательного свойства, так как необязательной переменной также присваивается значениеnil если значение не присутствует в ответе.

 Sweeper19 сент. 2017 г., 07:38
Знаете ли вы, что метод возвращаетString?, которыйявляется необязательный? Так что в принципе ты прав. Тамявляется использование опций.

Ответы на вопрос(2)

Я постараюсь объяснить это в соответствии с моим пониманием.

public class User : Decodable{

    public var firstName:String
    public var lastName:String
    public var middleName:String?
    public var address:String
    public var contactNumber:String


    public enum UserResponseKeys: String, CodingKey{
        case firstName = "first_name"
        case lastName = "last_name"
        case middleName = "middle_name"
        case address = "address"
        case contactNumber = "contact_number"
    }

    public required init(from decoder: Decoder) throws {

        let container = try decoder.container(keyedBy: UserResponseKeys.self)

        self.firstName = try container.decode(String.self, forKey: .firstName)
        self.lastName = try container.decode(String.self, forKey: .lastName)
        self.middleName = try container.decodeIfPresent(String.self, forKey: .middleName)
        self.address = try container.decode(String.self, forKey: .address)
        self.contactNumber = try container.decode(String.self, forKey: .contactNumber)
    }

}

Выше мойUser класс, в котором я отмеченmiddleName в качестве необязательного параметра, поскольку возможно, что ответ JSON может не обеспечитьmiddleName пара ключ-значение в ответе, поэтому мы можем использоватьdecodeIfPresent.

self.middleName = try container.decodeIfPresent(String.self, forKey: .middleName)

В то время как для других переменных, которые являются обязательными полями, поэтому мы уверены, что нет необходимости использовать дополнительные для этого. Мы использовали толькоdecode для этого, поскольку этот метод не возвращает необязательный.

public func decode(_ type: String.Type, forKey key: KeyedDecodingContainer.Key) throws -> String

Вышеdecode функция возвращаетString покаdecodeIfPresent возвращаетсяString?так что мы можем использовать необязательную переменную для хранения этого.

Таким образом, окончательный вывод заключается в том, что если вы не уверены в договоре об ответе на сервис или вы имеете дело с любыми сторонними сервисами, где ответ и параметры JSON могут изменяться без вашего ведома, вы можете использоватьdecodeIfPresent поэтому он может обрабатывать отсутствие конкретного параметра в ответ и установить значение какnil.

Решение Вопроса

// Exhibit 1
foo = try container.decode(Int?.self, forKey: .foo)
// Exhibit 2
foo = try container.decodeIfPresent(Int.self, forKey: .foo)

Экспонат 1 будет разобран:

{
  "foo": null,
  "bar": "something"
}

ноне:

{
  "bar": "something"
}

в то время как выставка 2 будет счастливо разбирать оба. Так что в обычных случаях использования дляJSON парсеры ты захочешьdecodeIfPresent для каждого дополнительного в вашей модели.

 Gunter Hager12 февр. 2019 г., 09:27
Нет, это не может быть проанализировано сfoo = try container.decode(Int.self, forKey: .foo), потому чтоInt не может держатьnull значение (т.е.nil).
 Honey20 дек. 2018 г., 14:04
так когда быdecodeIfPresent бросить тогда?
 Somoy Das Gupta01 февр. 2019 г., 11:19
может ли первый ответ быть проанализированfoo = try container.decode(Int.self, forKey: .foo) ?
 Honey20 дек. 2018 г., 17:09
нашел ответ: пока не упоминается в документацииВот, Это упоминается вкомментарии API сам, который также можно найти в вопросе: D. Это броситDecodingError.typeMismatch если обнаруженное закодированное значение не может быть преобразовано в запрошенный тип. decode Можно также скинуть три разные ошибки. ВидетьВот

Ваш ответ на вопрос