Обновление: Основная проблема с Базовыми данными, похоже, решена в iOS 12.1 (проверено в бета 4 ).Мы сохраним обходной путь, описанный ниже, в нашем приложении и не будем рекомендовать использовать опцию Внешнее хранилище в ближайшее время.
После разговора с инженерами Apple и подачи Радар, упомянутый выше , мы не могли дождаться исправления, поэтому мы приняли удар и переключились на хранение файлов в файловой системе и сами управляли им.
Другой альтернативой, которую мы рассмотрели, былоМиграция нашей модели не позволяет использовать внешнее хранилище для больших двоичных объектов, но я не знаю, какое влияние это окажет на производительность, и я также беспокоился о миграции модели в то время, когда эта часть iOS кажется нестабильной, особенно после чтения.истории, подобные этой в прошлом: Основные данные: не храните большие файлы в виде двоичных данных - Александр Эдж - Средний
Самостоятельно реализовать локальное хранилище было не так уж и сложно,Вам просто нужно иметь уникальный идентификатор для каждой записи, который вы можете использовать для создания имени файла, чтобы вы могли сопоставлять файлы с записями.Мы добавили расширение к нашему подклассу управляемых объектов с методами для чтения, записи и удаления файлов.Теперь вместо вызова, например, article.photo = image.pngData()
, теперь нам нужно вызвать что-то вроде article.savePhoto(image.pngData())
, а затем мы делаем аналогичное, когда хотим получить изображение.Вы также можете добавить код к этим методам для поддержки обратной совместимости с любыми изображениями, которые в данный момент хранятся в Core Data.
Удаление было немного сложнее, потому что наши объекты были удалены из нескольких мест в коде, включая каскадированиеудалений.В конце концов я решил сделать это в методе prepareForDeletion
управляемого объекта, но он не идеален.Существует множество дискуссий о том, как лучше всего реализовать это здесь: какао - Как обработать очистку внешних данных при удалении несохраненных объектов Core Data?- Переполнение стека
Наконец, чтобы предотвратить сбой нашего приложения, когда из-за этой ошибки пропал необязательный двоичный атрибут, я переопределяю awakeFromFetch
в моем подклассе управляемых объектов, чтобы гарантировать, что все необходимые атрибутыне ноль, и если они есть, я устанавливаю для них изображение-заполнитель, чтобы они могли быть сохранены без проверки.