Повышение устойчивости локального хранилища в гибридном приложении - PullRequest
0 голосов
/ 23 января 2019

Я разработал гибридное мобильное приложение, которое работает на IOS, Android и Chrome достаточно хорошо более 5 лет.Мое приложение использует базу данных indexedDB для поддержания состояния приложения и сохранения его между перезапусками, однако в некоторых случаях IOS может очистить indexedDB, особенно если на клиентском устройстве недостаточно памяти.

Я бы хотелнекоторая помощь в том, как поддерживать параллельную копию indexedDB с использованием собственной базы данных SQL на устройстве IOS, чтобы повысить устойчивость моего приложения, исходя из надежды на то, что IOS не решит произвольно очистить внутреннюю базу данных SQL, принадлежащуюк приложению.

Я понимаю, как общаться в обоих направлениях между Objective C и Javascript, но у меня нет самой туманной идеи в Objective C, как:

  1. Создать базу данных SQL вфайловая система приложения
  2. Выберите место для размещения базы данных SQL в файловой системе приложения
  3. Как записать новую пару значений ключа в базу данных
  4. Перезаписать существующее значение ключапара в базе данных
  5. Считывание всех пар ключ-значение из database (я предполагаю, что на практике их может быть до 1000), и эффективно передайте их обратно в код javascript.
  6. Очистите базу данных и начните снова.

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

Я просто хотел бы добавить, что я не использую Cordova или любую другую подобную среду разработки приложений, поэтому, пожалуйста, не предлагайте SQLiteплагин, который является частью большей среды.Я попал туда, где я нахожусь с индивидуальным подходом кодирования, и я хотел бы сохранить его таким.

1 Ответ

0 голосов
/ 08 февраля 2019

Я исследовал идею параллельного сохранения каждого indexedDB сохранения с записью в файл в папке документов IOS App с надеждой, что это будет менее вероятно стерто, чем в папке Caches.

После каждого setItem indexedDB с парой ключ-значение я передаю запрос к коду приложения IOS Objective-C для создания текстового файла в подпапке, созданной с помощью папки документов приложения, с именем «key» .txt и содержимое установлено в значение.

После каждого indexIdB removeItem я передаю запрос в код приложения IOS Objective-C для удаления соответствующего текстового файла 'key'.txt.

После очистки каждой индексированной БД я удаляю всю созданную выше подпапку.

Теперь, когда приложение запускается и обнаруживает пустую базу данных localForage, я передаю запрос к коду IOS-приложения Objective-C, чтобы проверить, есть ли подпапка с ключевыми элементами или нет.

Если это не так, то это новая установка приложения, и в таком случае она продолжается как обычно.

если это так, то это случай, когда база данных indexedDB была удалена.

В таком случае я прошу код приложения IOS target-C вернуть набор ключей, изучив содержимое созданной выше папки и удалив бит .txt, а в случае IOS Simulator игнорируя DS_Store файл.

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

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

Этот подход, кажется, работает, и я могу проверить это в любое время, используя действия на вкладке Ресурсы разработчика Safari, чтобы очистить базу данных, а затем вручную перезапустить приложение. Используя ту же вкладку, вы можете наблюдать за пополнением базы данных indexedDB.

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

Следующие примечания предназначены для тех, кто хочет попробовать этот подход и предполагает использование Objective C в XCode 10.1

  1. Используйте NSHomeDirectory () и stringByAppendingPathComponent @ "Documents", чтобы получить папку Documents.
  2. Используйте stringByAppendingPathComponent, чтобы создать путь к подпапке для подпапки ключей.
  3. Используйте fileExistsAtPath, чтобы проверить, существует ли подпапка ключей уже
  4. Используйте createDirectoryAtPath, если это не так.
  5. При сохранении или изменении элементов в indexedDB используйте stringByAppendingPathComponent для создания пути имени файла ключа, например, Base.txt для ключа 'Base'.
  6. Используйте fileHandleforWritingAtPath, чтобы получить fileHandle для файла
  7. если fileHandle не существует, необходимо создать его с помощью writeToFile для создания файла 'key'
  8. если fileHandle существует, то truncateFileAtOffseyt: 0 (важно), чтобы очистить его, а затем использовать writeData для создания новой версии файла 'key'.
  9. В обоих вышеперечисленных случаях укажите кодировку UTF8.
  10. При удалении элементов из indexedDB сделайте то же самое, чтобы получить путь к файлу ключа, а затем используйте removeItemAtPath.
  11. Устройство можно очистить, удалив всю подпапку с помощью removeItemAtPath.
  12. Процесс восстановления использует contentOfDirectoryAtPath для чтения набора ключей в подпапке.
  13. Процесс восстановления для каждого элемента использует stringWithContentsOfFile для чтения файлов данных и возврата содержимого, заключенного в кавычки, с использованием вызова stringByEvaluatingJavaScriptFromString

Надеюсь, это поможет.

...