Я создаю простой каталог контактов с функциями CRUD и хочу, чтобы функция редактирования была автономной. Моя база данных контактов будет храниться на сервере Parse.com. Возможно ли это, используя функциональность кэша Parse, или мне лучше прибегнуть к использованию Core Data?
Может анализировать кеш, заменяя основные данные
Ответы (3)
Нет, не может. Parse просто кэширует результаты ваших запросов. Это чрезвычайно ограничивает и не то же самое, что кэширование всех ваших PFObjects. Например, предположим, что вы выполнили запрос для всех ваших «контактов» PFObjects. Единственное, что вы сможете сделать с кешем, — это снова запустить тот же запрос позже (и получить точно такой же результат). Вы даже не могли запросить подмножество этих кэшированных данных.
Другая проблема заключается в том, что кешированные объекты не будут обновляться при любых изменениях, которые ваш пользователь вносит в ваши PFObjects. Например, предположим, что пользователь редактирует контакты в автономном режиме, а ваш код вызывает saveEventually
, чтобы сохранить эти изменения в Parse, когда это возможно. Когда вы получите кешированный результат запроса, изменения пользователя не будут отражены в ваших PFObjects. То же самое касается удаленных и добавленных PFObjects, я думаю. Это сделало бы автономное использование ужасным. Вот ветка с форума Parse, которая затрагивает эту тему:
Я видел, как разработчики Parse упоминали улучшенное кэширование объектов Parse, которое появится в будущем. Однако этой функции пока нет, и неизвестно, когда она появится. В то же время, если вы хотите поддерживать автономное использование, вы должны использовать Core Data или какое-либо другое локальное хранилище. FTASync (который я никогда не использовал) предназначен для синхронизации объектов Parse с Core Data:
https://github.com/itsniper/FTASync
Вы также можете написать свой собственный код для синхронизации двух наборов данных.
Parse iOS/OSX SDK предоставляет локальное хранилище данных, которое можно использовать для хранения и извлечения объектов PFObject, даже когда сеть недоступна. Чтобы включить эту функцию, добавьте libsqlite3.dylib и вызовите [Parse enableLocalDatastore] перед вызовом setApplicationId:clientKey:.
Как указано в документации Parse:
Вы можете сохранить PFObject в локальном хранилище данных, закрепив его. Закрепление PFObject является рекурсивным, как и сохранение, поэтому любые объекты, на которые указывает тот, который вы закрепляете, также будут закреплены. Когда объект закреплен, каждый раз, когда вы обновляете его, извлекая или сохраняя новые данные, копия в локальном хранилище данных будет обновляться автоматически. Вам не нужно беспокоиться об этом вообще.
PFObject *gameScore = [PFObject objectWithClassName:@"GameScore"]; gameScore[@"score"] = 1337; gameScore[@"playerName"] = @"Sean Plott"; gameScore[@"cheatMode"] = @NO; [gameScore pinInBackground];
Если у вас есть несколько объектов, вы можете закрепить их все одновременно с помощью удобного метода pinAllInBackground.
[PFObject pinAllInBackground:listOfObjects];
Извлечение объекта из локального хранилища данных работает так же, как извлечение объекта по сети. Единственная разница заключается в вызове метода fromLocalDatastore, чтобы сообщить PFQuery, где искать его результаты.
PFQuery *query = [PFQuery queryWithClassName:@"GameScore"]; [query fromLocalDatastore]; [[query getObjectInBackgroundWithId:@"xWMyZ4YE"] continueWithBlock:^id(BFTask *task) { if (task.error) { // Something went wrong. return task; } // task.result will be your game score return task; }];
Любой PFQuery можно использовать с локальным хранилищем данных так же, как и с сетью. Результаты будут включать любой закрепленный вами объект, соответствующий запросу. Любые несохраненные изменения, внесенные вами в объект, будут учтены при оценке запроса. Таким образом, вы можете найти соответствующий локальный объект, даже если он никогда не возвращался с сервера для данного конкретного запроса.
PFQuery *query = [PFQuery queryWithClassName:@"GameScore"]; [query fromLocalDatastore]; [query whereKey:@"playerName" equalTo:@"Joe Bob"]; [[query findObjectsInBackground] continueWithBlock:^id(BFTask *task) { if (task.error) { NSLog(@"Error: %@", task.error); return task; } NSLog(@"Retrieved %d", task.result.count); return task; }];
Когда вы закончили работу с объектом и он больше не нужен в локальном хранилище данных, вы можете просто открепить его.
[gameScore unpinInBackground];
Также есть способ открепить несколько объектов одновременно.
[PFObject unpinAllInBackground:listOfObjects];
Дополнительные сведения об использовании локального хранилища данных Parse см. в документации по локальному хранилищу данных для iOS/OSX на веб-сайте parse.
Нет, не может. Это далеко не то же самое, я предлагаю https://github.com/itsniper/FTASync