Вы задаете два вопроса.Я отвечу на них не по порядку.
Codable и CodingKeys обрабатываются на более глубоком уровне, чем то, что раскрывается через API?
Да, компилятор Swiftзнает о протоколах Encodable
, Decodable
и CodingKey
и имеет специальный код для них.
Компилятор может синтезировать CodingKey
-совместимый enum
с именем CodingKeys
, init(from:)
инициализатор и метод encode(to:)
, если выполняются некоторые условия.Условия прописаны в SE-0166 :
Encodable
& Decodable
. Также могут быть автоматически синтезированы для определенных типов:
- Типы, соответствующие
Encodable
, все свойства которых Encodable
, получают автоматически сгенерированные String
-обеспеченные CodingKey
enum
сопоставления свойств с именами дел.Аналогично для Decodable
типов, чьи свойства имеют все Decodable
- Типы, попадающие в (1), и типы, которые вручную предоставляют
CodingKey
enum
(с именем CodingKeys
, напрямую или через typealias
), случаи которых отображают свойства 1-в-1 в Encodable
/ Decodable
по имени - получают автоматический синтез init(from:)
и encode(to:)
в зависимости от ситуации, используя эти свойства и ключи - Типы, которыеНи в (1), ни (2) не потребуется предоставлять пользовательский тип ключа, если это необходимо, и предоставлять свои собственные
init(from:)
и encode(to:)
, в зависимости от ситуации
Обратите внимание, что CodingKey
-поддерживаемый тип обычно не имеет с именем CodingKeys
или даже enum
, если вы не полагаетесь на соответствие, синтезированное компилятором.
Кроме того, обратите внимание, чтоТип CodingKeys
, соответствующий CodingKey
, должен иметь регистр для каждого члена включающего его типа, если вы полагаетесь на компилятор, чтобы синтезировать init(from:)
или encode(to:)
.
Если вы вручнуюреализуя init(from:)
и encode(to:)
, вы можете использовать любое имя для вашего CodingKey
-подобного типа, и он должен иметь только те случаи, которые вас волнуют.Вам даже не нужен CodingKey
-совместимый тип, если вы используете для хранения только контейнер с одним значением или контейнер без ключа.
Если нет, есть ли способ реализоватьФункциональность CodingKeys вне Codable?
Если под «функциональностью» вы подразумеваете способ, которым компилятор автоматически синтезирует реализации, то единственный способ - использовать генератор кода (например, Sourcery или gyb) для генерацииисходный код и передайте его компилятору.
Если под «функциональностью» вы подразумеваете способ, которым компилятору требуется ключевой элемент для каждого Encodable
/ Decodable
члена включающего типа, то единственныйпуть заключается в запуске отдельной программы, которая анализирует ваш исходный код и выявляет ошибки, если какой-либо случай отсутствует.Вы не можете заставить стандартный компилятор Swift сделать это за вас.