mac os x嵌入式webkit webview中的脱机应用程序缓存支持

时间:2016-05-04 01:17:43

标签: swift macos caching webview offline

我正在编写OS X HTML5应用程序,它必须在线和离线运行。脱机应用程序缓存基于this进行了原型设计,并且在Safari中运行良好。当我在Xcode中使用webview进行简单测试时,清单文件似乎永远不会被webview获取。一种简单的测试方法是使用这个最小的html文件:

<html manifest="example.manifest"><head> <title>Test with
manifest</title> </head> <body> Test with manifest<br> <br>
</body></html>

清单文件example.manifest包含:

CACHE MANIFEST
# ver 1
CACHE:

当我在Safari中查看此页面时,页面会加载,并且会读取清单。如果我退出safari,请离线,然后启动Safari并刷新此页面,它从缓存加载。这里的离线缓存似乎工作正常。

当我用Web视图重复此操作时,在Xcode 7.3 Mac OS 10.11中,使用以下代码(storyboard在窗口内的视图控制器中有一个Web视图):

class ViewController: NSViewController {
@IBOutlet var webview: WebView!

let THEURL:String = "http://192.168.23.180/WithManifest/"

override func viewDidLoad() {
    super.viewDidLoad()
    let url = NSURL(string: THEURL)
    let request = NSURLRequest(URL: url!, cachePolicy:NSURLRequestCachePolicy.UseProtocolCachePolicy ,timeoutInterval: 10)
    webview.mainFrame.loadRequest(request)
   }
}

在Web视图的情况下,页面加载正常,但在退出并重新启动脱机后,页面无法加载。在查看网络流量时,很明显从未向客户端请求清单文件。我已经尝试了所有不同的缓存策略但没有成功。我也尝试创建自己的共享URL缓存,如其他地方所建议的那样没有成功。

    let cacheSizeMemory:Int = 4*1024*1024; // 4MB
    let cacheSizeDisk:Int = 32*1024*1024; // 32MB
    let sharedCache:NSURLCache = NSURLCache(memoryCapacity:cacheSizeMemory, diskCapacity:cacheSizeDisk, diskPath:"nsurlcache")
    NSURLCache.setSharedURLCache(sharedCache)

我的问题:

1)OS X中的webkit webview是否支持离线应用程序缓存,如html5?

中所述

2)如果是的话,必须采取哪些措施才能使其发挥作用?

我的解决方法是实现NSURLProtocol的子类,该子类实现自定义缓存并在应用程序中执行加载逻辑(离线与在线)。如果可能的话,我宁愿使用标准方法。

1 个答案:

答案 0 :(得分:1)

在不同的地方和人们的帮助下,我能够找到答案。有一个名为setOfflineWebApplicationCacheEnabled的Objective-C webview首选项,由于某种原因没有在swift中公开。要使其工作,首先要创建一个桥接头文件。使用Xcode创建一个头文件并将其放入其中:

#import <Foundation/Foundation.h>
#import <WebKit/WebKit.h>

@interface WebPreferences (WebPreferencesPrivate)
- (void)_setLocalStorageDatabasePath:(NSString *)path;
- (void) setLocalStorageEnabled: (BOOL) localStorageEnabled;
- (void) setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEnabled;
- (void) setDatabasesEnabled:(BOOL)databasesEnabled;
@end

并将其保存在您的项目中。转到Build Settings-&gt; Swift Compiler - Code Generation并选择'Objective C Bridging Header'。双击右侧并将相对路径(基于文件系统,而不是项目组织)放入头文件。在我的例子中,它是testwebviewmanifest / Header.h,其中testwebviewmanifest文件夹与.xcodeproj文件处于同一级别。

一旦完成并且您可以成功构建(如果路径错误,可能会抱怨它无法找到您的头文件),请将此行放在您拥有webview句柄的启动位置。对我来说,很容易将它放在ViewController中。

    webview.preferences.setOfflineWebApplicationCacheEnabled(true)

完成后,将下载缓存清单,并且应用程序缓存似乎完美无缺。尚未进行广泛的测试。如果发现任何陷阱,我会更新...

可在此处找到演示项目:https://github.com/graySquirrel/testwebviewmanifest