无法将本地 html 文件加载到仅设备上的 WKWebView(在模拟器上工作)
Cannot load a local html file into a WKWebView on device only (works on simulator)
下面的本地代码将本地 HTML 文件(来自应用程序容器,而不是应用程序包)加载到 WKWebView 中。
- (void)loadIndexConteneurWithHash:(NSString *)hash
{
NSString *fileName = @"index.html";
NSString *subpath = hash ? [NSString stringWithFormat:@"%@#%@", fileName, hash] : fileName;
NSString *rootContainerDirectoryPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www/v2"];
NSURL *URL = [NSURL URLWithString:subpath relativeToURL:[NSURL fileURLWithPath:rootContainerDirectoryPath]];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[self.webView loadFileURL:URL allowingReadAccessToURL:URL];
// This below has the same effect (works on simulator and not on device)
// NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
// [self.webView performSelectorOnMainThread:@selector(loadRequest:) withObject:request waitUntilDone:true];
}
设备上的文件 url 是:file:///var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html
在模拟器上:file:///Users/<me>/Library/Developer/CoreSimulator/Devices/4A5B9713-6589-4DCA-ABBD-F4FF1246AE43/data/Containers/Data/Application/717B54FD-1344-41D3-8B53-FC0767FFE892/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html
这段代码在我试过的任何模拟器上都能正常工作 (ios 12 / ios 13).
但是它不会在设备上加载 HTML 文件。当我使用 Safari 调试器时,我看到 webview 处于“about:blank”状态。
我在运行时没有错误,它似乎只是静静地停止执行 loadFileURL
。
我能做些什么来解决/调查这个问题?
编辑 1
设备上既没有调用 didFailNavigation 也没有调用 didFinishNavigation...
编辑 2
添加此代码:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(@"%@ exists? %d",URL.absoluteString,[fileManager fileExistsAtPath:URL.absoluteString]);
在设备上给出这个:
2019-10-17 18:42:48.955588+0200 gall-app[881:230671] /var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html exists? 1
所以它存在于预期的位置。我还使用 XCode 从设备下载了应用程序容器,我看到了文件应该在的位置。
编辑 3
经过进一步测试,似乎 [self.webView loadFileURL:...
不适用于 ios 12(包括模拟器),但适用于 ios 13...
它们之间可能存在一些安全规则差异?
在我的 info.plist 中,我有:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
我的网络视图是用这段代码初始化的:
- (void)viewDidLoad
{
[super viewDidLoad];
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
self.webView.configuration.preferences.javaScriptEnabled = YES;
self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
[self.webView.configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
[self.webView.configuration setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
[self addUserScriptToUserContentController:self.webView.configuration.userContentController];
好的,我发现 "why" 它不起作用。我改变了这个:
[self.webView loadFileURL:URL allowingReadAccessToURL:URL];
对此:
[self.webView loadFileURL:URL.absoluteURL allowingReadAccessToURL:rootAppURL];
其中 rootAppURL
为:
NSString *rootappPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www"];
NSURL *rootAppURL = [NSURL fileURLWithPath:rootappPath isDirectory:YES];
它现在适用于 ios < 13
下面的本地代码将本地 HTML 文件(来自应用程序容器,而不是应用程序包)加载到 WKWebView 中。
- (void)loadIndexConteneurWithHash:(NSString *)hash
{
NSString *fileName = @"index.html";
NSString *subpath = hash ? [NSString stringWithFormat:@"%@#%@", fileName, hash] : fileName;
NSString *rootContainerDirectoryPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www/v2"];
NSURL *URL = [NSURL URLWithString:subpath relativeToURL:[NSURL fileURLWithPath:rootContainerDirectoryPath]];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[self.webView loadFileURL:URL allowingReadAccessToURL:URL];
// This below has the same effect (works on simulator and not on device)
// NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
// [self.webView performSelectorOnMainThread:@selector(loadRequest:) withObject:request waitUntilDone:true];
}
设备上的文件 url 是:file:///var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html
在模拟器上:file:///Users/<me>/Library/Developer/CoreSimulator/Devices/4A5B9713-6589-4DCA-ABBD-F4FF1246AE43/data/Containers/Data/Application/717B54FD-1344-41D3-8B53-FC0767FFE892/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html
这段代码在我试过的任何模拟器上都能正常工作 (ios 12 / ios 13).
但是它不会在设备上加载 HTML 文件。当我使用 Safari 调试器时,我看到 webview 处于“about:blank”状态。
我在运行时没有错误,它似乎只是静静地停止执行 loadFileURL
。
我能做些什么来解决/调查这个问题?
编辑 1
设备上既没有调用 didFailNavigation 也没有调用 didFinishNavigation...
编辑 2
添加此代码:
NSFileManager *fileManager = [NSFileManager defaultManager];
NSLog(@"%@ exists? %d",URL.absoluteString,[fileManager fileExistsAtPath:URL.absoluteString]);
在设备上给出这个:
2019-10-17 18:42:48.955588+0200 gall-app[881:230671] /var/mobile/Containers/Data/Application/3CF58895-866D-400A-B0E0-4CA98BF143F7/Library/Application%20Support/<my.app.id>/LocalContents/www/v2/indexConteneur.html exists? 1
所以它存在于预期的位置。我还使用 XCode 从设备下载了应用程序容器,我看到了文件应该在的位置。
编辑 3
经过进一步测试,似乎 [self.webView loadFileURL:...
不适用于 ios 12(包括模拟器),但适用于 ios 13...
它们之间可能存在一些安全规则差异?
在我的 info.plist 中,我有:
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
我的网络视图是用这段代码初始化的:
- (void)viewDidLoad
{
[super viewDidLoad];
self.webView.UIDelegate = self;
self.webView.navigationDelegate = self;
self.webView.configuration.preferences.javaScriptEnabled = YES;
self.webView.configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
[self.webView.configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
[self.webView.configuration setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
[self addUserScriptToUserContentController:self.webView.configuration.userContentController];
好的,我发现 "why" 它不起作用。我改变了这个:
[self.webView loadFileURL:URL allowingReadAccessToURL:URL];
对此:
[self.webView loadFileURL:URL.absoluteURL allowingReadAccessToURL:rootAppURL];
其中 rootAppURL
为:
NSString *rootappPath = [NSFileUtility pathRelativeToContentDirectoryForSubpath:@"/www"];
NSURL *rootAppURL = [NSURL fileURLWithPath:rootappPath isDirectory:YES];
它现在适用于 ios < 13