我有一个HTML文件,其中包含的本地资源文件,如css,js和png文件的内容。这些本地资源文件采用zip格式。我的应用程序使用WKWebView显示这个html文件。我希望找到一个解决方案来拦截web视图请求,以检测哪些本地资源文件与这个html文件一起加载,然后解压缩它们,如果它们仍然是zip格式的。
我的HTML数据内容包含数千个本地资源文件,因此我无法在显示内容之前将它们全部解压缩。使用UIWebView,我们使用NSURLProtocol子类来拦截请求,检测本地资源文件,并根据用户正在查看的html页面按需解压它。
在将UIWebView转换为WKWebView时,我遇到了这个问题。类似的问题在这里发布:https://forums.developer.apple.com/thread/87474
=======更新=======>
我用WKURLSchemeHandler.弄明白了
注意:为了使用WKURLSchemeHandler,您需要将文件方案更改为自定义方案,因为它不能与文件、http、https等标准方案一起工作。
1.向WKWebView注册自定义方案
let configuration = WKWebViewConfiguration()
configuration.setURLSchemeHandler(self, forURLScheme: "x-file")
webView = WKWebView(frame: view.bounds, configuration: configuration)2.将文件方案转换为自定义方案(x文件),然后用WKWebView加载它。
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
var htmlURL = URL(fileURLWithPath: htmlPath!, isDirectory: false)
htmlURL = self.changeURLScheme(newScheme: "x-file", forURL: htmlURL)
self.webView.load(URLRequest(url: htmlURL))3.实现WKURLSchemeHandler协议的2种方法,并处理WKURLSchemeTask.的3种委托方法
func webView(_ webView: WKWebView, start urlSchemeTask: WKURLSchemeTask) {
print("Function: \(#function), line: \(#line)")
print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")
// Your local resource files will be catch here. You can determine it by checking the urlSchemeTask.request.url.
// From here I will unzip local resource files (js, css, png,...) if they are still in zip format
....
// Handle WKURLSchemeTask delegate methods
let url = changeURLScheme(newScheme: "file", forURL: urlSchemeTask.request.url!)
do {
let data = try Data(contentsOf: url)
urlSchemeTask.didReceive(URLResponse(url: urlSchemeTask.request.url!, mimeType: "text/html", expectedContentLength: data.count, textEncodingName: nil))
urlSchemeTask.didReceive(data)
urlSchemeTask.didFinish()
} catch {
print("Unexpected error when get data from URL: \(url)")
}
}
func webView(_ webView: WKWebView, stop urlSchemeTask: WKURLSchemeTask) {
print("Function: \(#function), line: \(#line)")
print("==> \(urlSchemeTask.request.url?.absoluteString ?? "")\n")
}发布于 2020-02-25 13:30:28
如果WKWebView加载了一个本地html文件,您只需让WKWebView访问本地应用程序资源,如下所示:
NSURL *documentDirectoryURL = [NSURL fileURLWithPath:DOCUMENTS_DIRECTORY];
// This code gives acces to a file that is outside of our webview html file root directory
[self.webView loadFileURL:documentDirectoryURL allowingReadAccessToURL:documentDirectoryURL];
// If you use one of these loads after, they will too have access if they are in app html files
[self.webView loadRequest:<inAppHTMLFile>];
[self.webView loadHTMLString: baseURL:];这里允许访问文档目录中的所有文件。
当我想将本地资源链接到在线页面时,我发现您的解决方案很有帮助。
WKUserContentController *contentController = [[WKUserContentController alloc]init];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc]init];
CustomFileShemeHandler *schemeHandler = [[CustomFileShemeHandler alloc] init];
[config setURLSchemeHandler:schemeHandler forURLScheme:@"myApp-images"];
config.userContentController = contentController;
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
//CustomFileShemeHandler.m
@implementation CustomFileShemeHandler
- (void)webView:(nonnull WKWebView *)webView startURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
NSURL *customFileURL = urlSchemeTask.request.URL;
NSString *securityFilter = [NSString stringWithFormat:@"Documents/LocalAppImages"];
if (![customFileURL.absoluteString containsString:securityFilter]) {
return;
}
NSURL *fileURL = [self changeURLScheme:customFileURL toScheme:@"file"];
NSURLRequest* fileUrlRequest = [[NSURLRequest alloc] initWithURL:fileURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:.1];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:fileUrlRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSURLResponse *response2 = [[NSURLResponse alloc] initWithURL:urlSchemeTask.request.URL MIMEType:response.MIMEType expectedContentLength:data.length textEncodingName:nil];
if(error){
[urlSchemeTask didFailWithError:error];
}
[urlSchemeTask didReceiveResponse:response2];
[urlSchemeTask didReceiveData:data];
[urlSchemeTask didFinish];
}];
[dataTask resume];
}
- (void)webView:(nonnull WKWebView *)webView stopURLSchemeTask:(nonnull id<WKURLSchemeTask>)urlSchemeTask {
NSLog(@"DUNNO WHAT TO DO HERE");
}
- (NSURL *)changeURLScheme:(NSURL *)url toScheme:(NSString *)newScheme {
NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:YES];
components.scheme = newScheme;
return components.URL;
}这样,在webView中打开的任何页面都可以使用本地资源的完整路径(自定义方案)链接到本地资源:
<img src="myApp-images:///<YourDocumentsAppPahtHere>/LocalAppImages/funnyDog.jpg">发布于 2021-06-18 14:58:57
在h3dkandi的回答之后,这个评论帮助我解决了我的问题:(快速更新代码)
如果你第一次使用:
// use this in order to access images, css files etc..
webView.loadFileURL(baseURL, allowingReadAccessTo: baseURL)
// use this method to actually load the html with images, css etc..
webView.loadHTMLString(htmlString, baseURL: baseURL)其中baseURL是我的本地.html文件存在的路径。
https://stackoverflow.com/questions/58385398
复制相似问题