Сохранение рисунков пользователя в Core Data
Трансформируемые атрибуты полезны для хранения нестандартных типов объектов в Core Data.
Например, вы можете сохранить экземпляр UIImage
в Core Data, установив для его типа атрибута значение Transformable
.
В этой статье мы пойдем еще дальше, чтобы увидеть, как мы можем хранить массив пользовательских типов данных в Core Data с помощью Transformable и NSSecureCoding
.
Представьте, что мы хотим хранить рисунки пользователя в Core Data для вымышленного приложения для рисования. Мы создали 2 класса для моделирования данных чертежа:
И в нашем собственном подклассе холста UIView
мы рисуем наши пути следующим образом:
Теперь пришло время сохранить данные чертежа в Core Data.
Давайте откроем наш редактор модели CoreData
(исходный файл с расширением .xcdatamodeld
) и добавим атрибут с именем drawings для нашего объекта Canvas, а затем установим его тип атрибута на Transformable.
Но теперь мы получаем предупреждение, в котором говорится:
Canvas.drawing
использует нулевой или небезопасный преобразователь значений. Переключитесь наNSSecureUnarchiveFromDataTransformerName
или на собственныйNSValueTransformer
подклассNSSecureUnarchiveFromDataTransformer
Причина, по которой мы получаем это предупреждение, заключается в том, что, начиная с iOS 13, Apple хочет, чтобы мы использовали NSSecureCoding
(а не NSCoding
) для наших пользовательских типов данных CoreData для повышения безопасности.
Давайте продолжим, чтобы наши классы модели данных соответствовали NSSecureCoding
.
Здесь довольно много изменений, давайте пробежимся по некоторым моментам.
- Мы делаем наши модельные классы подклассами
NSObject
, чтобы их можно было сериализовать. Кроме того, мы делаем их соответствующими протоколуNSSecureCoding
; - Мы устанавливаем статическое свойство
supportsSecureCoding
в значение true; - Мы используем
decodeObject(of: forKey:)
для декодирования объекта при извлечении данных из Core Data; - Поскольку
CGPoint
не соответствует протоколуNSSecureCoding
, мы конвертируем его вNSString
и затем кодируем. Когда мы декодируем его, мы затем конвертируем его обратно вCGPoint
; - Поскольку
Path
— это пользовательский класс, нам нужно включить типPath
в массив ожидаемых классов, которым должен соответствовать декодируемый объект.
Теперь мы привели наши классы моделей в соответствие с NSSecureCoding
. Давайте перейдем к созданию подкласса NSSecureUnarchiveFromDataTransformer
для нашего атрибута drawings
, чтобы он знал, как преобразовать свое значение из NSData
в правильные типы данных при извлечении из Core Data.
Здесь мы добавляем класс Paths
в массив allowedTopLevelClasses
, потому что это класс верхнего уровня в процессе преобразования значений. Мы также создаем статический метод с именем Register
, который позволяет нам зарегистрировать пользовательский преобразователь в нашем приложении, и это то, что мы будем делать дальше.
Давайте откроем файл AppDelegate.swift
и внесем следующие изменения, чтобы зарегистрировать наш пользовательский преобразователь:
Затем мы возвращаемся в наш редактор модели Core Data и указываем Transformer
и CustomClass
для атрибута drawings
:
После всех этих шагов наше приложение может сохранять рисунки пользователя в Core Data.