【问题标题】:How do I enable Local Storage in my WebKit-based application?如何在基于 WebKit 的应用程序中启用本地存储?
【发布时间】:2010-12-24 18:59:20
【问题描述】:

我有一个嵌入 WebKit WebView 的 Cocoa/Objective-C 应用程序。我需要打开数据库支持和本地存储。我知道它可以完成——我让它在 Safari 中工作——但我找不到如何在我自己的应用程序中进行设置的示例。

我发现this (unanswered) SO question 提供了一个示例,但正如原始海报所提到的那样,它不起作用。事实上,他使用的方法(setDatabasesEnabled、setLocalStorageEnabled)并没有在我的 WebKit.framework(Xcode 3.2.5)中定义,尽管如果我自己定义它们似乎存在。

谁能提供一个如何为基于 WebKit 的 Cocoa 应用程序启用本地数据库存储的示例?非常感谢!

更新:我有一些工作......我对“数据库”和“本地存储”感到困惑,这显然是完全不同的东西。这是有效的代码:

WebPreferences* prefs = [webView preferences];
[prefs _setLocalStorageDatabasePath:@"~/Library/Application Support/MyApp"];
[prefs setLocalStorageEnabled:YES];

这样可行,但它需要私有方法 _setLocalStorageDatabasePath,这对我来说意味着没有 App Store。所以我现在修改的问题是:有没有办法让这项工作使用私有方法?我找到了WebDatabaseDirectory preference key in this answer,它控制数据库 的去向。但是我在源中的任何地方都找不到本地存储的相应密钥。或者有没有办法让我强制本地存储使用数据库,所以 WebDatabaseDirectory 键?有什么想法吗?

【问题讨论】:

    标签: objective-c ios webkit local-storage


    【解决方案1】:

    我使用此代码向 Mac App Store 提交了一个应用程序,Apple 批准了它:

    Objective-C

    WebPreferences* prefs = [webView preferences];
    [prefs _setLocalStorageDatabasePath:@"~/Library/Application Support/MyApp"];
    [prefs setLocalStorageEnabled:YES];
    

    斯威夫特 3

    var prefs: WebPreferences? = webView.preferences
    prefs?._setLocalStorageDatabasePath("~/Library/Application Support/MyApp")
    prefs?.localStorageEnabled = true
    

    他们是否会继续批准,我不知道,但他们在 2011 年 1 月 29 日允许我的申请。 更新:他们还批准了同一个应用程序的版本更新,所以它经历了两次。

    【讨论】:

    • 终于设法清除了最后一组箍,我的应用程序现在也在商店中。
    • 你把它放在哪里了? @执行? 。H?澄清赞赏..抱歉愚蠢...
    • 一般来说,Apple 会批准大多数 WebKit 私有方法,因为 WebKit 本身是开源的。
    • 这个问题最后一次活跃是在大约一年前,所以 Apple 可能已经取消了对 _setLocalStorageDatabasePath:setLocalStorageEnabled: 方法的支持,因为我找不到在任何地方使用它们的方法,但是如果你知道支持仍然存在,我如何在我的代码中获得对这些方法的支持以便我可以使用它们?
    • 你是如何在 Swift 中做到这一点的?
    【解决方案2】:

    我将采用 Javascript 到 Objective-C 的桥接方法并将所有内容存储在核心数据中。将 localStorage 设置为 false,然后使用相同的方法构建一个 JS 对象和一个名为“localStorage”的实例。我的 javascript 开发人员不会知道其中的区别,而且我已经不得不对 Air 做同样的事情(基本上)。还有另一种方法可以保持 localStorage 完整,即使它实际上并没有将它们存储在持久数据库中。这些元素可以在 javascript 中迭代并从那里进行操作,但我认为用我自己的对象替换对象会更好。

    【讨论】:

    • 这听起来像是一个有趣的解决方案(Apple 不会标记它)。我真的很想看一些代码:)
    • 这种方法的唯一问题是,如果你使用 sqlite,查询会异步运行,所以alert(localStorage.getItem('a')); 将不起作用。
    • 在哪里可以找到这种方法的示例?
    • 开源这个桥会很棒。
    • 您是如何设法将 window.localStorage 替换为您自己的?我成功实现了一个 LocalStorage 对象,但是我无法分配给 window.localStorage。
    【解决方案3】:

    在经历了很多痛苦和挫折之后,我找到了一种启用本地存储并让它在应用程序正常运行时保持不变的方法。此解决方案专门针对 OSX,但也可能适用于 iOS。

    下载此头文件并将其添加到您的项目中。它不包含在 XCode Webkit 发行版中。

    click to download WebStorageManagerPrivate.h

    添加以下几行:

    static NSString* _storageDirectoryPath();
    + (NSString *)_storageDirectoryPath;
    

    这些允许您检索 WebKit 本地存储跟踪器数据库的目录位置。这很重要,因为由于 WebKit 中的一个错误,如果您不将 LocalStorage WebView 文件存储在与跟踪器数据库相同的目录中,那么每隔一次运行应用程序时它们就会被删除。我没有在 WebStorageManager 代码中看到为单个应用程序更改此位置的方法。它始终从用户首选项中读取。

    在您的 appDelegate 中包含 WebStorageManagerPrivate.h。

    #include "WebStorageManagerPrivate.h"
    

    您需要下载 XCode 发行版中未包含的另一个标头并将其包含在您的项目中。将其保存为 WebPreferencesPrivate.h

    click to download WebPreferencesPrivate.h

    在您的 appDelegate 中包含 WebPreferencesPrivate.h。

    #include "WebPreferencesPrivate.h"
    

    现在在您的 applicationDidFinishLaunching 处理程序中使用以下代码来初始化和启用 LocalStorage。该代码假定您有一个名为“webView”的 IBOutlet,用于您正在使用的 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 中得到正确修复。

    【讨论】:

    • 您遇到了什么问题?错误?不保存?我已经在 10.7 下测试过了。
    • 在 10.11 (El Capitan) 以下不再有效。我不得不求助于桥接本机代码来进行保存和加载操作。为了尽量减少 Javascript 的更改,您可以覆盖 Storage.prototype 中的标准“set”和“get”函数并调用您的桥接函数。 Apple 填补了使用本地文件引用为 Webkit 应用程序存储 localStorage 的安全处理方面的差距。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    • 2011-10-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多