Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Core Data vs FMDB->sqlite

#objective_c #ios #coredata #sqlite


Стартовые условия - есть уже работающие сервер (MSSQL->JSON) и клиент (JSON->CoreData)
под iOS, и пишется клиент под Android который будет локально работать на sqlite. Руководство
хочет уйти от привязки к JSON'у на iOS, которую сделал исполнитель, и перевести iOS-клиент
на работу с sqlite, чтобы сделать в будущем highload-backend с которым потенциально
смогут работать обе мобильные платформы (а не два бекенда для каждой платформы как
сейчас). Передо мной (нынешний исполнитель) дилемма - перепиливать CoreData на прием
из сети sqlite и ее засовывание в CoreData, или переписывать все для FMDB->sqlite.
Все склоняется к тому чтобы использовать то, что будет быстрее работать на клиенте
визуально. Причиной создания данного топика стало то что возможности попробовать нет,
так как написание приложения на FMDB с нуля займет непозволительно много времени, и
если оно не окупится по итогу то много времени будет потрачено зря. Прошу не разводить
холивар на тему кому что больше нравится а описать какие-то практические данные с реальных
проектов, околограничные проблемы обоих решений, свой личный опыт о том что из этих
вариантов работает быстрее или имеет какие-то преимущества.     


Ответы

Ответ 1



Я немного запутался в вашем вопросе, но все равно попробую ответить. Мне странно, что ваше руководство "хочет уйти от привязки к JSON'у на iOS" и я, честно говоря, впервые слышу, чтобы работающий клиент (JSON->CoreData) перекраивали под то, чтобы работать с sqlite (то есть даже вообще впервые слышу, чтобы sqlite служил транспортом вместо JSON особенно в целях унификации платформ). Возможно я не знаю каких-то особых подходов и тонкостей, но, кажется, JSON является абсолютным стандартом при передаче данных в сетевой схеме взаимодействия между клиентом-приложением и сервером-бэкэндом. Я ни разу не встречал, чтобы топовые библиотеки в мире Apple/iOS работали с чем-то кроме JSON. Достаточно назвать AFNetworking и RestKit. Сказав это, добавлю что такое решение вашего руководства выглядит вдвойне странным в виду того, что, повторю еще раз, если я правильно понял, они стремятся добиться максимальной универсальности решения. Исходя из сказанного выше, мне кажется, что не должно быть никаких сомнений, что ваш сервер должен отдавать JSON (ну и замечательно будет, если все по REST-конвенциям спроектировано будет или уже), и должны быть клиенты iOS и Android соответственно, которые будут этот JSON переносить уже к себе с учетом своих специфик. Если сказанное до сих пор верно, можно уже поставить немного другой вопрос, на который я могу ответить тоже лишь частично и только про Apple/iOS: "ваш опыт налаживания подобных схем" и его подвопросы: стоит ли пользоваться RestKit (так как это единственное full-stack решение подобных задач, насколько я знаю работает только с Core Data), и если нет, то пользоваться ли Core Data или отказаться от него и использовать sqlite? Мой личный опыт такой: я занимаюсь разработкой именно iOS-приложений около 11 месяцев, все это время я делаю приложение, которое можно, сказав грубо, назвать клоном FourSquare - говорю это для того, чтобы показать, что я достаточно плотно столкнулся именно с вопросами взаимодействия сервера, спроектированного в соответствии с REST и отдающего JSON, и клиента, которому нужно этот JSON разложить в Core Data. Так получилось, что о RestKit узнал далеко не сразу. Поэтому оказалось, что научение тому, как сделать все грамотно, то есть разобраться с многопоточностью, GCD, Core Data, всему тому, что RestKit делает где-то за кулисами прямо из коробки, заняло у меня очень много времени (где-то месяцев 5). Позже оказалось (когда я-таки взглянул внимательно на RestKit), что для того, чтобы полностью реализовать работающую схему JSON<->Core Data, мне пришлось сделать код, весьма напоминающий по структуре код RestKit. Он не столь идеально абстрагирован по сравнению с RestKit, но с поставленными задачами справляется, и чем дальше продвигается мой проект, он все больше начинает на него походить, хотя и с небольшой разницей в наших подходах (кстати, судя по профилю на Гитхабе, автор RestKit работает на TripAdvisor - то есть вот against what он разрабатывает RK). Про свои недоумения относительно RestKit я задавал здесь на ХК вопрос, на который, к сожалению, так и не получил хотя бы одного внятного ответа: RestKit - за и против?. То есть после года экспериментов я все еще колеблюсь по поводу того, чтобы полностью перейти на RestKit, так как уже сам почти научился решать эти задачи и немного в более близком лично мне ключе, чем это делает RestKit, но, повторю, времени и усилий это заняло достаточно много! Резюмируя эту часть: если вы хотите сэкономить время на склейке JSON в Core Data, используйте готовое решение, - постарайтесь перейти на RestKit, если готового самописного еще не стало так много, что миграция окажется очень сложной --- RestKit прекрасно справится с задачей по переводу JSON в Core Data и обратно. Некоторые задачи там решаются настолько легко, что это и впрямь выглядит как magic. Теперь отвечу совсем немного про "Core Data vs FMDB->sqlite". Я начинал изучать iOS строго по гайдам и там все время мелькало Core Data, поэтому я опять же не сразу узнал, что бывают просто разнообразные ORM и оболочки и key-value store, работающие с sqlite. Мой результат - это то, что я вполне нормально освоился с Core Data и НИ РАЗУ не встретил СЕРЬЕЗНЫХ ограничений, которые заставляли бы меня подумать о переходе к каким-то другим решениям, хотя за это время я узнал о существовании не только FMDB, но и, например, таких вот решений: NanoStore, YapDatabase, iActiveRecord (особенно близкое и понятное мне, так как я имеющ опыт работы с ActiveRecord в Ruby on Rails). На этом пока все. Возможно позже я дополню свой ответ, если придумаю, как сделать его лучше. ОБНОВЛЕНО ПОЗЖЕ Я могу себе представить только один возможный случай, когда работа с sqlite (без JSON вообще) может оказаться адекватной - это случай так называемой оффлайн-работы. Приведу простой пример: у вас есть приложение с картами (Яндекс карты) и вы в момент начала пользования приложением скачиваете разом NN мегабайтовую карту и с этого момента пользуетесь исключительно скачанной картой, так как карта обновляется очень редко и вы можете быть уверены, что скачанная карта будет служить вам верой и правдой, хм, адекватно отражать местность и завтра и послезавтра. То есть, если база, с которой будет работать ваше приложение, является более или менее статичной, вы можете при первой загрузке приложения (в момент начала использования приложения) просто разово передавать ее одним большим файлом (чуть ли не дампом базы) и просто импортировать её средствами местной на клиенте DB (не узнавал, возможно ли такое в Core Data или в SQLite, но очевидно, что подходы должны существовать). Таким образом вы на корню рубите вопросы синхронизации, JSON, весь этот парсинг, маппинг, асинхронность и много других слов и проблем. Единственное требование к специфике приложения - это, чтобы оно не должно было постоянно лазить за чем-то очень свежим и постоянно обновляющимся на ваш сервер, в сеть. Мне кажется, мое описание этого случая вполне ясно. ОБНОВЛЕНО ЕЩЕ ПОЗЖЕ Интересный топик на SO, открытый авторами вопроса и ответа на эту тему: Improve process of mirroring server database to a client database via JSON.

Ответ 2



Последний раз с CoreData (с нуля) работал довольно давно, но периодически приходилось поддерживать существующие проекты. С sqlite приходилось работать в паре проектов, но последние проекты были в основном тонкими клиентами. Все последующие мысли не являются истинной правдой, они основаны на мои знаниях, а в них есть много пробелов (я плохо знаю CoreData). CoreData это не аналог и не замена sqlite. Это два абсолютно разных инструмента, и у них разные области применения. Если нужно делать какие-то очень хитрые запросы (например вычислять географическое расстояние), то здесь будет удобнее sqlite. В остальных случаях будет достаточно CoreData'ы. CoreData - Контекст и невалидные сущности. Если в контекст попала невалидная сущность, и вы проморгали ее удаление оттуда то сохранить контекст уже не удастся. - CoreData - отдельный стек, не похожий на SQL с которым мне приходилось работать до этого. Причем стек довольно большой, а т.к. область применения относительна невелика, то зачастую очень тяжело найти решение какой-нибудь нетривиальной проблемы. + Работает "из коробки", при использовании сторонних оберток (MagicalRecord, ObjectiveRecord) работа с ней становится гораздо приятней. + Система миграций, не нужно писать raw sql (зачастую это излишне) SQLite - Приходится много писать относительно низкоуровневых вещей, либо пользоваться каким-то враппером, но даже с тем же FMDB приходится писать много, т.к. это всего лишь адаптация sqlite3 API для Objective-C. Как я указал в комментарии, пытался писать свою обертку, но задача далеко не тривиальная, вылазит много граблей/костылей - Приходится руками создавать таблицы, накатывать миграции (iActiveRecord частично решает эту проблему). + Это все же SQL и используется на многих платформах, а потому гораздо проще найти решение проблем/вопросов. + Полный контроль над взаимодействием с БД. Резюме В последующих проектах при выборе между SQLite и CoreData я в первую очередь буду опираться на требования, т.к. оба подхода имеют свои минусы и плюсы, и как правило если что-то легко в CoreData, то сложно в SQLite. И наоборот.

Комментариев нет:

Отправить комментарий