Как включить локальное хранилище в моем приложении на основе WebKit?
У меня есть приложение Cocoa/Objective-C, которое включает WebKit WebView. Мне нужно включить поддержку базы данных и локальное хранилище. Я знаю, что это можно сделать - я работаю в Safari, но я не могу найти пример того, как это установить в моем собственном приложении.
Я нашел этот (неотвеченный) вопрос SO, который дает пример, но, как упоминает оригинальный плакат, не работает. Фактически, методы, которые он использует (setDatabasesEnabled, setLocalStorageEnabled), не определены в моей программе WebKit.framework(Xcode 3.2.5), хотя они, похоже, существуют, если я сам их определяю.
Может ли кто-нибудь указать пример включения локального хранилища баз данных для приложения Cocoa на основе WebKit? Большое спасибо, если да!
Обновление: У меня что-то работает... Меня смутило "базы данных" и "локальное хранилище", которые, по-видимому, совсем разные. Вот код, который работает:
WebPreferences* prefs = [webView preferences];
[prefs _setLocalStorageDatabasePath:@"~/Library/Application Support/MyApp"];
[prefs setLocalStorageEnabled:YES];
Итак, это работает, но для этого требуется частный метод _setLocalStorageDatabasePath, что означает отсутствие для меня магазина приложений. Итак, мои измененные вопросы сейчас: есть ли способ сделать эту работу без использования частного метода? Я нашел ключ предпочтения WebDatabaseDirectory в этом ответе, который контролирует, куда идут базы данных. Но я не мог найти соответствующий ключ для локального хранилища в любом месте источников. Или есть способ заставить локальное хранилище использовать базу данных, и поэтому ключ WebDatabaseDirectory? Любые идеи?
Ответы
Ответ 1
Я отправил приложение, используя этот код в Mac App Store, и Apple одобрила его:
Objective-C
WebPreferences* prefs = [webView preferences];
[prefs _setLocalStorageDatabasePath:@"~/Library/Application Support/MyApp"];
[prefs setLocalStorageEnabled:YES];
Swift 3
var prefs: WebPreferences? = webView.preferences
prefs?._setLocalStorageDatabasePath("~/Library/Application Support/MyApp")
prefs?.localStorageEnabled = true
Будут ли они продолжать утверждать это, я не знаю, но они разрешили его для моего приложения с 2011-01-29. Обновление: Они также одобрили обновление версии для того же приложения, поэтому оно прошло дважды.
Ответ 2
Я собираюсь использовать Javascript для моста Objective-C и хранить все в основных данных. Установите localStorage в false, затем создайте объект JS и экземпляр с именем "localStorage" с теми же методами. Мои разработчики javascript не будут знать разницу, и я уже должен был сделать то же самое с Air (в основном). Есть еще один способ оставить неприменимым хранилище данных, хотя на самом деле он не хранит их в постоянном db. Элементы можно повторить в javascript и манипулировать оттуда, но я думаю, что будет лучше просто заменить объект своим.
Ответ 3
После большой боли и разочарования я нашел способ включить локальное хранилище и обеспечить его постоянное выполнение приложений. Это решение специально для OSX, но оно может быть применимо и к iOS.
Загрузите и добавьте этот заголовочный файл в свой проект. Он не включен в дистрибутив XCode Webkit.
нажмите, чтобы загрузить WebStorageManagerPrivate.h
Добавьте к нему следующие строки:
static NSString* _storageDirectoryPath();
+ (NSString *)_storageDirectoryPath;
Это позволяет получить местоположение каталога базы данных отслеживания локального хранилища WebKit. Это важно, потому что из-за ошибки в WebKit, если вы не храните файлы LocalStorage WebView в том же каталоге, что и база данных трекера, они удаляются каждый раз, когда вы запускаете приложение. Я не видел способа в коде WebStorageManager изменить это местоположение для отдельного приложения. Он всегда считывается из пользовательских настроек.
Включите WebStorageManagerPrivate.h в appDelegate.
#include "WebStorageManagerPrivate.h"
Вам нужно загрузить и включить в свой проект другой заголовок, не включенный в дистрибутив XCode. Сохраните его как WebPreferencesPrivate.h
нажмите, чтобы загрузить WebPreferencesPrivate.h
Включите WebPreferencesPrivate.h в appDelegate.
#include "WebPreferencesPrivate.h"
Теперь используйте код ниже в обработчике applicationDidFinishLaunching для инициализации и включения LocalStorage. В коде предполагается, что вы используете IBOutlet с именем "webView" для WebView, который вы используете.
NSString* dbPath = [WebStorageManager _storageDirectoryPath];
WebPreferences* prefs = [self.webView preferences];
NSString* localDBPath = [prefs _localStorageDatabasePath];
// PATHS MUST MATCH!!!! otherwise localstorage file is erased when starting program
if( [localDBPath isEqualToString:dbPath] == NO) {
[prefs setAutosaves:YES]; //SET PREFS AUTOSAVE FIRST otherwise settings aren't saved.
// Define application cache quota
static const unsigned long long defaultTotalQuota = 10 * 1024 * 1024; // 10MB
static const unsigned long long defaultOriginQuota = 5 * 1024 * 1024; // 5MB
[prefs setApplicationCacheTotalQuota:defaultTotalQuota];
[prefs setApplicationCacheDefaultOriginQuota:defaultOriginQuota];
[prefs setWebGLEnabled:YES];
[prefs setOfflineWebApplicationCacheEnabled:YES];
[prefs setDatabasesEnabled:YES];
[prefs setDeveloperExtrasEnabled:[[NSUserDefaults standardUserDefaults] boolForKey: @"developer"]];
#ifdef DEBUG
[prefs setDeveloperExtrasEnabled:YES];
#endif
[prefs _setLocalStorageDatabasePath:dbPath];
[prefs setLocalStorageEnabled:YES];
[self.webView setPreferences:prefs];
}
Я надеюсь, что это поможет другим бороться или все еще борется с этой проблемой, пока она не будет исправлена правильно в WebKit.