Базовые данные на клиенте (iOS) для кэширования данных с сервера. Стратегия - PullRequest
57 голосов
/ 02 февраля 2011

Я написал много приложений для iOS, которые общались с бэкэндом.Почти каждый раз я использовал HTTP-кеш для кеширования запросов и анализа данных ответов (JSON) в объекты target-C.Для этого нового проекта мне интересно, имеет ли смысл подход Core Data.

Вот что я подумал:

Клиент iOS делает запрос к серверу и анализирует объекты из JSON вМодели CoreData.

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

Однако, если объект не существует или срок его действия истек (здесь может быть применена некоторая логика кэширования), я бы выбрал объект изсервер и обновите CoreData соответственно.

Я думаю, что наличие такой архитектуры могло бы помочь в следующем: 1. Избегать ненужных запросов к бэкэнду 2. Разрешить полную поддержку автономного просмотра (Вы все еще можете делать реляционные запросы сСУБД DataCore)

Теперь вот мой вопрос к таким богам:

  1. Я знаю, что это своего рода требует повторного кодирования логики бэкэнда (Server + CoreData), но это перебор?1016 *
  2. Есть ли какие-то ограничения, которые я недооценил?
  3. Есть еще идеи?

Ответы [ 3 ]

93 голосов
/ 03 февраля 2011

Прежде всего, если вы являетесь зарегистрированным разработчиком iOS, у вас должен быть доступ к сессиям WWDC 2010.Одна из этих сессий охватила кое-что из того, о чем вы говорите: «Сессия 117, Создание пользовательского интерфейса на основе сервера».Вы должны быть в состоянии найти его в iTunes .

. Умная комбинация REST / JSON / Core Data работает как чудо и значительно экономит время, если вы планируете повторно использовать свой код, но потребует знания HTTP (и знаний о Core Data, если вы хотите, чтобы ваши приложения работали хорошо и безопасно).

Таким образом, ключ к пониманию REST и Core Data.

  • Понимание REST означает Понимание методов HTTP (GET, POST, PUT, DELETE, ... HEAD?) И кодов ответов (2xx, 3xx, 4xx, 5xx) и заголовков (Last-Modified, If-Modified-Since, Etag, ...)

  • Понимание базовых данных означает, что вы знаете, как проектировать вашу модель, устанавливать отношения, обрабатывать трудоемкие операции (удалять, вставлять), обновления), и как заставить вещи происходить в фоновом режиме, чтобы ваш пользовательский интерфейс оставался отзывчивым.И, конечно же, как делать локальные запросы в sqlite (например, для предварительной выборки идентификаторов, чтобы вы могли обновлять объекты вместо создания новых, как только вы получите их эквиваленты на стороне сервера).

Если вы планируетеЧтобы реализовать повторно используемый API для упомянутых вами задач, вы должны убедиться, что вы понимаете REST и Core Data, потому что именно там вы, вероятно, будете выполнять больше всего кода.(Существующие API - ASIHttpRequest для сетевого уровня (или любого другого) и любая хорошая библиотека JSON (например, SBJSON ) для разбора сделают эту работу.

ключ к тому, чтобы сделать такой API простым, состоит в том, чтобы ваш сервер предоставлял службу RESTful, а ваши сущности содержат необходимые атрибуты (dateCreated, dateLastModified и т. д.), чтобы вы могли создавать запросы (легко выполняемые с помощью ASIHttpRequest, будь то GET, PUT, POST, DELETE) и добавьте соответствующие заголовки Http, например, для условного GET: If-Modified-Since.

Если вы уже чувствуете себя комфортно с Core Data и можете обрабатывать JSON и можете легко выполнять HTTP-запрос и обрабатывать ответы(опять же, ASIHttpRequest здесь очень помогает, но есть и другие, или вы можете придерживаться низкоуровневых Apple NS-классов и делать это самостоятельно), тогда все, что вам нужно, это установить правильные заголовки HTTP для ваших запросов и обработатьHttp-Response-Codes надлежащим образом (при условии, что ваш сервер заполнен REST).

Если ваша основная цель состоит в том, чтобы избежать повторного обновлениясущность Core-Data из серверного эквивалента, просто убедитесь, что в вашей сущности имеется атрибут «последний измененный», и выполните условное GET для сервера (установив для заголовка Http-заголовка If-Modified-Since значениеваша сущность "дата последнего изменения".Сервер ответит кодом состояния 304 (без изменений), если этот ресурс не изменился (при условии, что сервер заполнен REST).Если оно изменилось, сервер установит заголовок «Last-Modified» Http-заголовка на дату последнего изменения, ответит кодом состояния 200 и доставит ресурс в теле (например, в формате JSON).

Итак, как всегда, ответ на ваш вопрос, как всегда, вероятно, «это зависит».В основном это зависит от того, что вы хотели бы вставить в свой многоразовый слой «все для ядра» / «отдых».

Чтобы сказать вам цифры: у меня ушло 6 месяцев (в свободное время, в темпе3-10 часов в неделю), чтобы иметь мой, где я хотел, и, честно говоря, я все еще рефакторинг, переименование, чтобы он мог обрабатывать специальные сценарии использования (отмена запросов, откаты и т. д.) и обеспечитьдетализированные обратные вызовы (достижимость, сетевой уровень, сериализация, сохранение основных данных ...),.Но он довольно чистый, продуманный и оптимизированный, и, надеюсь, соответствует общим потребностям моего работодателя (онлайн-рынок для объявлений с несколькими приложениями для iOS).Это время включало в себя изучение, тестирование, оптимизацию, отладку и постоянное изменение моего API (сначала добавьте функциональность, затем улучшите ее, затем радикально упростите и снова отладьте).

Если ваше время выхода на рынок является вашим приоритетом, вам лучше воспользоваться простым и прагматичным подходом: не обращайте внимания на возможность повторного использования, просто помните об уроках и реорганизуйте их в следующем проекте, повторно используя и исправляя код здесь и там. В конце концов, сумма всего опыта может материализоваться в четком видении того, КАК работает ваш API и ЧТО оно предоставляет. Если вы этого еще не сделали, постарайтесь сделать его частью бюджета проекта и попробуйте использовать как можно больше стабильных сторонних API.

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

Если вы просто хотите обрабатывать определенные сценарии кэширования, чтобы разрешить автономное использование вашего приложения и минимизировать сетевой трафик, то вы, конечно, можете просто реализовать эти функции. Просто установите в вашем запросе заголовки if-updated-Since, проверьте последние измененные заголовки или etags и сохраняйте эту информацию постоянной в ваших персистентных сущностях, чтобы вы могли повторно передавать эту информацию в последующих запросах. Конечно, я бы также рекомендовал (постоянно) кэшировать ресурсы, такие как изображения, локально, используя те же заголовки HTTP.

Если вы можете позволить себе роскошную модификацию (в режиме REST) ​​службы на стороне сервера, то все в порядке, если вы правильно ее реализуете (по опыту вы можете сэкономить до 3/4 сети). / парсинг кода на стороне iOS, если служба ведет себя хорошо (возвращает соответствующие коды состояния HTTP, избегает проверок на nil, преобразований чисел из строк, дат, предоставляет идентификаторы поиска вместо неявных строк и т. д.).

Если у вас нет такой роскоши, то либо эта услуга, по крайней мере, REST-полная (что очень помогает), либо вам придется исправлять ошибки на стороне клиента (что часто является болью).

5 голосов
/ 01 ноября 2013

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

5 голосов
/ 02 августа 2011

Существует решение, которое я не смог бы попробовать, потому что я слишком далеко в своем проекте, чтобы реорганизовать аспект кэширования сервера в моем приложении, но это должно быть полезно для людей, которые все еще ищут ответ:

http://restkit.org/

Это именно то, что я сделал, но гораздо более отвлеченно, чем то, что я сделал.Очень проницательные вещи там.Надеюсь, это кому-нибудь поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...