Codable vs ObjectMapper

Снимка от https://unsplash.com/photos/_rNVw54xZZg

Наскоро експериментирах с новия Codable протокол на Swift като начин да нанесе JSON, получен от отдалечена услуга, в обект на модел Swift.

За малко на фона, Codable беше добавен в Swift 4 като начин за чисто разрешаване на обектите да се преобразуват във и извън външно представителство. Самият Codable е просто един тип на Decodable и Encodable.

За тази публикация ще се съсредоточа върху частта за декодиране, тъй като това е преобразуването от отдалечено представяне на JSON, което ме интересува.

сравнение

В миналото използвах широко ObjectMapper, но тъй като Codable вече е вграден в Swift, исках да направя сравнение на двете. Характеристиките, които искам да сравня са:

  • Валидиране ️
  • Персонализирана трансформация (картографиране в персонализирани типове, например картографиране на JSON низ в регекс)
  • Грешка при работа с

Данните, които ще анализирам, са реални конфигурации, които получаваме отдалечено за приложението BBC Sport

Това е доста проста структура на JSON, но има няколко Регулярни изрази, в които бих искал да бъдат картографирани в NSRegularExpression, а не в String

ObjectMapper

Структурите, необходими за картографиране на този модел JSON с ObjectMapper, са както следва.

Всички студи съответстват на протокола ImmutableMappable, което означава, че се нуждаят от конструктор, който взема обект Map и хвърля грешка, ако картографирането не успее.

утвърждаване

За да извършите валидирането, можете да използвате незадължителни. В този пример решихме, че приложението може да функционира без тези имейл адреси, така че имейлите не са задължителни. map.values ​​(„имейли“) хвърля грешка, ако ключът не е налице или не може да бъде прехвърлен към правилния тип. Възползваме се от опита? да заснемете тази грешка и просто да я превърнете в нулева стойност, ако има грешка.

Ако решим, че даден имот е необходим, не го маркираме като незадължителен и допускаме грешката да се разпространява.

Като цяло валидирането е много направо, използвайки ImmutableMappable

Може би сте забелязали, че има допълнителен аргумент, предаван в този разговор map.value („regex“, използвайки: RegexTransformer ()). Това е за персонализираната трансформация, за да превърне String в NSRegularExpression, което ме води хубаво към следващата ми точка!

Персонализирана трансформация

ObjectMapper поддържа персонализирани трансформации извън кутията и е много прав.

Тук просто изпълняваме протокола TransformType и свързания метод transformFromJSON. Това отнема тип и който ние хвърляме към String и след това безопасно да опитаме? да конвертирате String в NSRegularExpression.

След това този трансформатор е достъпен за повторна употреба навсякъде

Грешка при работа

За да тествам обработката на грешки, ще използвам JSON файл с липсващия изходен ключ.

Когато изпълняваме това през ObjectMapper, получаваме приятно полезно съобщение за грешка.

Получих грешка при картографирането.
- причина: Не може да се добави към „String“
- местоположение: Config.init (карта :): 30
- ключ: изход
- currentValue: нула

Това ни казва всичко, което трябва бързо да намерим къде е проблемът. Открих, че когато използвате интеграцията AlamofireObjectMapper, грешките се потискат, което е по-малко от идеалното.

Codable

Извън кутията еквивалентната Codable реализация е както следва

Много е подобен на ObjectMapper, въпреки че ключовете са дефинирани като enums, използвайки протокола CodingKey.

Има наистина приятна функция, използваща Codable, тъй като първоначалният може да бъде генериран за вас, ако те изброяват случаите, са равни на свойството, а типът, който сме картографирали, е самият Decodable Пример за това е CodableConfig по-горе. Тъй като всички негови свойства са сами по себе си декодируеми, не е необходимо да пишем инициализатор!

утвърждаване

Това работи точно както ObjectMapper

Инициализаторът изхвърля грешка, ако има картографиране на грешки, с което може да се работи в сайта за повикване. Отново, използвайте тук опциите, за да решите как най-добре да се справите с грешките.

Персонализирана трансформация

Ще забележите в горния код, всичко става малко по-малко ясно, когато се опитваме да пренасочим към нашия тип NSRegularExpression. Изведнъж трябва да внедрим инициализатора init (от декодер: Декодер) и да си вземем KeyedDecodingContainer от декодера

Вече има страхотно описание на това, ако искате повече подробности, които няма да преглеждам тук.

Кодът става доста многословен за писане сега, а ние повтаряме кода за трансформация. Това е само допълнителен ред в този случай, но често има случаи, когато искам да напиша по-сложни трансформации, които бих искал да изолирам, както мога с ObjectMapper

Така че направих малка библиотека за добавяне на поддръжка за персонализирани трансформации това е достъпно чрез CocoaPods или можете просто да копирате източника, тъй като това е само няколко файла.

Може да помислите да добавите разширение към типа, който не притежавате, но има добро обяснение защо това не е възможно в Swift Evolution.

С помощта на библиотеката CodableExtensions вече можем да опростим кода ни да изглежда много подобен на ObjectMapper

И RegexCodableTransformer също е много подобен на този, който преди имахме с ObjectMapper

Библиотеката също опростява интерфейса към container.decode (), така че типът вече не е необходимо да се предава, тъй като е изведен.

Грешка при работа

Използвам същия файл JSON, за да сравня предаването на грешки както преди. Грешката изглежда така

. KeyNotFound (config_spike.CodableRewriter (CodingKeys в _4D474241C6D85B5C48988D77CA644850) .output, Swift.DecodingError.Context (codingPath: [config_spike.CodableConfig (CodingKeys в _4D474241C6D85B5C48988D77CA644850) .rewriter.], DebugDescription: "Не стойност, свързана с ключовата изход (\" изход \ ").", underlyingError: nil))

Грешката не е толкова изглеждаща , но има всичко, за да отстрани грешката в проблема.

заключение

Има много повече прилики, отколкото разлики между двата подхода. Ако трансформациите са важни, тогава ObjectMapper работи извън кутията. Въпреки това, един от основните мотиватори за превключване преминава към стандарта, който Apple са създали, без да се налага да въвеждат друга библиотека.

Ако трансформациите са важни, като добавите няколко протокола, можете да получите същото поведение с Codable

Решихме да се преместим в Codable сега за всичките ни нови функции напред. Сигурен съм, че има функции, които съм пропуснал от този списък, но избрах най-важните за нас.