Как стать автором
Обновить

Быстрый, простой, сложный: как мы выпилили Realm

Время на прочтение18 мин
Количество просмотров20K
Всего голосов 46: ↑46 и ↓0+46
Комментарии47

Комментарии 47

Шикарная статья, с реальной проблемой и в довольно редком формате — «Удаление технологии из проекта». Когда обычно пишут про то как втащить в проект новую свистелку.

Пожалуйста, продолжайте писать про реальные кейсы.

Спасибо, писать буду :-)

Плюсую!
уже вторая статья за последние дни, как выпиливают Realm)) Но реально круто смотреть, как к такому процессу подходят системно.
В очередной раз задумаешься – стоит ли тащить в проект third party библиотеки
Практически любой относительно крупный проект состоит из «third party библиотек». Это нормально.
Надо просто оценивать риски и понимать цену этого, так как есть часть кода, которая не контролируется как свой.
Он может состоять из них только по большой глупости. Как раз таки в большие проекты затаскивать сторонние библиотеки очень рискованно, при этом оправданность из затаскивания будет чрезвычайно мала. Ну, либо, как писал автор статьи — надо сразу закладывать время на их выпил
Похоже, мы совсем о разном.
Если писать всё самому, то такой проект имеет риск никогда не запуститься из-за высокой сложности.
Да и до какого уровня можно спуститься? Взять работу с БД. Отказаться от библиотеки и напрямую работать с sqlite файлами или полностью писать свою реализацию протокола работы с MySQL?

sqlite – это уже и есть библиотека

Не совсем, это главным образом БД. Просто так случилось, что библиотека для работы с ней так же называется.
Но главное не это, главное — что это «3rd party». Затаскивать ли в свой проект стороннюю библиотеку?

sqlite уже затащен в iOS с самой первой версии, нужно только импортировать sqlite.h

Верно. Там много что уже «затащено», но всё равно это «3rd party». Я об этом.

Тоже бодаемся с реалмом. Удалить его есть задача. Но никак руки не доходят.

на что планируете заменить, если не секрет?

Пока это серьезно не обсуждалось. В нашем случае нам сперва тоже все не связанное напрямую с хранилищем надо перетащить в UserDefaults. А для остальных случаем нам подойдет вполне просто база данных закрытая каким нить Repository паттерном.

RX-ы будет выпиливать сложнее…

Не добавляли, поэтому и выпиливать не придется

К слову, в Rx проблема совсем другого характера — сам фреймворк весьма стабилен (за все несколько лет, что я с ним работал, столкнулся с проблемой только в Rx 1 — refCount в нескольких тредах могли устроить deadlock), и единственным камнем преткновения может стать его сложность для новых разработчиков. Ну и дикая кривая сложности написания своих операторов, которые работают с Backpressure (но это весьма специфичный случай).
Просто не надо делать Rx-лапшу, тогда и выпиливать не прийдётся. Используем Rx только в имплементации сервисов/вьюх. Наружу в протоколах Rx не торчит. Так что выпилить или заменить на тот же Combine задача на один день.

Сколько лет работаю с Realm одно удовольствие. Каскадное удаление уже давно завезли кстати. Это правда что есть много нюансов и легко выстрелить в ногу, но когда имеешь хороший опыт не вижу проблем. У Room их намного больше...

Вполне может быть.


Статьей я хотел показать, что не все просто с популярным инструментом, надо понимать его задачи, сильные стороны и особенности.

А с какой версии завезли каскадное удаление? Недавно пытался искать инфу, и натыкался только на то, что «нет и пока не предвидтся»
посмотрите Embedded objects, это и есть каскадное удаление.
Версию посмотрите от 10.0.0 и выше.
Согласен, большинство минусов Realm (из начала статьи) точно так же применимы к CoreData. Статью можно было назвать «Как мы отказались от БД в пользу UserDefaults и сериализации JSON в файлы». Но за рефакторинг подкреплённый тестами и метриками :like:
Спасибо, очень интересная статья!
Особенно методология и организация работ по рефакторингу.

Я так понимаю что ошибку с миграций (которая была первым звоночком) не получилось поймать в CI тестах на апдейт приложения, поскольку она случалась не между текущей и предыдущей версией а между текущей и какой-то древней?

Ага, там разница времени была года полтора

Года четыре-пять назад, помню, ходила шутка: «Realm используют те, кому лень разбираться с CoreData», он позиционировался чуть ли не как серебряная пуля на все проблемы с хранилищем в iOS. На деле уже тогда, тем кто знал Core Data было понятно, что невозможно «просто» решить комплексные вещи.

Прям с языка снял!

После аутсорсеров всегда переписывать приходится.

пока читаешь статью складывается ощущение что проблема была далеко не в рилме ) а рилм первый кто отказался работать в таких условиях и потребовал рефакторинга кода ) история интересная, читать приятно ) спасибо )

Нет целей обвинять инструмент, он просто инструмент. Для нас он оказался избыточен, это показало время, а я просто рассказал что вокруг него произошло.

Крутая статья, спасибо, прочитал с удовольствием)

Но мне кажется есть какая-то излишняя щепетильность.
Типа камон, это просто приложение чтоб заказать пиццу, без обид.
Тут нет важных данных. Это не ПО для жизнеобеспечения)
Если бы приложение раз в год предложило условно снова выбрать город я бы глазом не моргнул. Думаю как и остальные люди.
Человек не обновлялся полтора года и тут обновился. Вам так сильно важно чтоб у этого плюс минус единственного человека все сработало идеально? Стерли бы все к чертям и дело с концом, пусть на чистую все создается грузится

Человек может заказывать и несколько раз в месяц. Почему у него буквально между двумя запусками должны пропасть какие-то настройки?

Ну, не каждый же день реалм выпиливаете из проекта)
И естественно я не о чем то критичном, типа слетевшей авторизации.

Как пользователь скажу что меня больше бы выбесило 6 раз за неделю обновлять ваше приложение чем один раз снова тыкнуть свой город.

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

Включите автобновление на телефоне :-)

Люблю почитать чейнджлоги)
И ненавижу ежедневные апдейты с шаблонным тестом :(
Раз уж разговариваю с таким важным человеком
Позвольте немножко фидбека оставить
Статья заставила установить ваше приложение на телефон (купил новый пару месяцев назад, а так стояло)

Первый запуск.

На милисекунду появляется список стран и тут же без анимации пушится контроллер уже с городами. Так понимаю определилась страна это хорошо, но почему без анимации то? Страшно очень

Тыкаю в серч контроллер у него сразу отступ появляется и он съезжает вниз. Скролом не возвращается на место :) Наверное как-то связано с largeTitle

Кстати истории заказов почему-то нет. Они хранятся определенное время? Вполне возможно что заказывал года полтора назад

На главной банер с акцией по Apple Pay
По нажатию всплывает карточка с описанием и кнопкой показать.
Кнопка просто скрывает карточку. Немного сбивает с толку. Что я должен был увидеть то :)

У всех «питательных» товаров кнопка i в карточке продукта показывает всплывающее окно с пищевой ценностью. Но есть товары типа «Додо Клюв»
И эта кнопка не делает ничего. Так если нет доп. информации может стоит кнопку скрыть?

Карточки с пиццами мое почтение. Очень красиво и прикольно :)
Особенно та где половинки выбирать
А удалось посчитать реальную разницу в размере кода? Как я понял, одним из недостатков Realm был увеличенный объем. Realm убрали, заменили репозиториями — и какой эффект в этом отношении получился в числах? Скажем, убрали 1000 строк кода, а добавили 10. Не считали?

Рилм занимал 8 МБ кода.


По самому проекту значительной разницы нет в размере, пару тысяч строк наверно. А вот в чистоте и типизированности кода стало значительно лучше

Да, меня интересовала разница в количестве кода исключительно, не объем бандла.
Еще относительно UserDefaults. Как решили вопрос миграций в них?

Храним в файле, в UserDefaults только пара айдишников.


Пока не мегрировали, но как предполагаю может быть.


  1. Заводим новую модель, старую оставляем рядом.
  2. Даем репозиторию пачку модейле что он может прочитать.
  3. Если не смог самую новую прочитать, то читает предыдущую. Если смог, то должна вызваться функция миграции из одной модели в другую. Все типизировано, легко тестировать.
  4. После миграции сохраняет данные.

Но я предполагаю, что большинство репозиториев можно будет просто снести и заново получить с сервера.

Понятно. Вопрос появился из-за того, что проблема с миграциями — не от их наличия, а от обращения с ними. Сам-то инструмент полезный. Собственно, если переехать на UserDefaults — то вопрос с миграциями останется. Вот только, по моему мнению, он проигрывает Realm: если у Realm миграции предусмотрены штатно, то в UserDefaults их к тому же и нет (то есть проблем становится больше: и завести, и правильно использовать).
Ну и, кроме того, Realm имеет настройку удалять БД при миграциях: можно их не писать, а просто чистить базу. Как я понял из ответа, примерно к тому же и пришли в UserDefaults.

Можно чистить при миграции.


А еще откат версии надо обрабатывать в другом месте, если файл не прочитался.


А еще если места на диске нет. Много этих «еще»

Я в данном случае не спорю и не высказываю свое мнение ни в одну из сторон, цель — разобрать с непредвзятой точки зрения плюсы и минусы обоих способов. Если беспристрастно — отсутствие места на диске аналогично разрушительно и для Realm, и для UserDefaults.
А вот про «много еще» было бы интересно послушать — правда, желательно, с обеих сторон. Если это возможно, конечно. На этом примере открывается одна из сравнительно редких возможностей решить одну задачу двумя разными способами и сравнить их на практике. Как правило бывает, что разработчики выбирают одно из решений, реализуют его. И видят все плюсы/минусы полученного решения, а плюсы/минусы других решений можно оценить только умозрительно. А в вашем случае можно сесть, составить таблицу параметров и расставить оценки кандидатам. Получится объективный счет.
Эстония, Нарва… Пиццерия в этом городе ещё не открылась ;-(
Зарегистрируйтесь на Хабре, чтобы оставить комментарий