Свойства в Swift используются для хранения каких-то данных. Иногда у этих свойств есть какая-то логика, которая запускается при их изменении. Например, имея свойство, которое поддерживает состояние кеша, при его изменении приложению необходимо обновить значения до UserDefaults. Что-то вроде этого -

В этом примере при изменении isCacheUpdated и isUserDetailsUpdated необходимо сохранить значения в UserDefaults для поддержания состояния кеша. Если вы заметили, логика обновления userDefaults повторяется, а не является общей. Так что, если бы мы хотели поддерживать еще несколько состояний, нам нужно было бы написать большее количество строк кода.

То же самое и с userData и accountData, когда данные обновляются, их необходимо зашифровать перед сохранением в базе данных. Как мы можем решить эту проблему, если мы можем повторно использовать эту логику и сделать ее более общей? И прост в использовании 😃

Ответ - обертки свойств в Swift 5.1. Давайте посмотрим, как это работает и решает нашу проблему.

Упаковщики свойств

Оболочки свойств - это типы, которые обертывают данное значение и присоединяют к нему связанную логику. Его можно реализовать с помощью Struct или Class, добавив к нему аннотацию с помощью атрибута @propertyWrapper. Единственное реальное требование состоит в том, что каждый тип оболочки свойства должен содержать хранимое свойство с именем wrappedValue, которое сообщает Swift, какое базовое значение помещается в оболочку.

Давайте рассмотрим приведенный выше пример и посмотрим, как мы можем использовать оболочки свойств для isCacheUpdated и isUserDetailsUpdated -

В этом примере мы создали оболочку свойств UserDefaultsBacked, которая обертывает значения, которые необходимо сохранить в UserDefaults. Эта структура аннотирована с помощью @propertyWrapper и обертывает значения типа DataType (Generic).

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

Теперь посмотрим, как легко использовать его в коде -

это так просто 😀 Просто объявите переменную с аннотацией, и мы сможем сэкономить значительный объем кода и сделать его более универсальным.

См. Приведенный ниже код, чтобы реализовать Property Wrappers для обертывания userData и accountData -

Здесь мы создаем оболочку свойств SecureData и реализуем необходимое свойство wrappedValue. Посмотрите, как мы это используем -

Просто объявите userData и accountData с аннотацией @SecureData, и все настроено. Swift автоматически понимает, что userData и accountData заключены в оболочку свойств SecureData, и применяет связанную логику всякий раз, когда эти значения изменяются.

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

Спасибо за чтение 😀