iOS中WKWebView的一些特殊使用總結
前言
現(xiàn)在大部分的app只支持iOS8以上的系統(tǒng)了,在接入H5時可以只管最新的WKWebView了。
WKWebView的優(yōu)勢
- 性能高,穩(wěn)定性好,占用的內存比較小,
- 支持JS交互
- 支持HTML5 新特性
- 可以添加進度條(然并卵,不好用,還是習慣第三方的)。
- 支持內建手勢,
- 據(jù)說高達60fps的刷新頻率(不卡)
本文將給大家總結下iOS中WKWebView的一些特殊使用,下面話不多說了,來一起看看詳細的介紹吧
WKWebView 加載本地網(wǎng)頁的方式
1.直接加載字符串
- (void)loadHTMLString {
//直接加載字符串
NSString *path = [[NSBundle mainBundle] pathForResource:@"story" ofType:nil];
NSString *body = [NSString stringWithContentsOfURL:[NSURL fileURLWithPath:path] encoding:(NSUTF8StringEncoding) error:nil];
NSString *cssPath = [[NSBundle mainBundle] pathForResource:@"css" ofType:nil];
NSString *css = [NSString stringWithContentsOfURL:[NSURL fileURLWithPath:cssPath] encoding:NSUTF8StringEncoding error:nil];
NSString *html = @"<html>";
html = [html stringByAppendingString:@"<head>"];
html = [html stringByAppendingString:@"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no,viewport-fit=cover\">"];
html = [html stringByAppendingString:@"<style type=\"text/css\">"];
html = [html stringByAppendingString:css];
html = [html stringByAppendingString:@"</style></head><body>"];
html = [html stringByAppendingString:body];
html = [html stringByAppendingString:@"</body></html>"];
[webview loadHTMLString:html baseURL:nil];
}
需要注意的是, baseURL 可以用來控制請求權限
2.加載本地文件
- (void)loadHTMLContent {
//加載本地文件
NSString *rootPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
NSURL *rootURL = [NSURL fileURLWithPath:rootPath];
NSString *bodyTargetPath = [rootPath stringByAppendingPathComponent:@"index.html"];
NSURL *url = [NSURL fileURLWithPath:bodyTargetPath];
//這里必須指定到沙盒的具體文件夾,不能再沙盒根目錄上
[webview loadFileURL:url allowingReadAccessToURL:rootURL];
}
重定向請求
1.通過 URLProtocol
新建 Protocol 的子類,并添加請求屬性
@property (nonnull,strong) NSURLSessionDataTask *task;
由于 WKWebview 的特殊性,這里需要新建類別,并注冊需要監(jiān)聽的請求頭 [NSURLProtocol wk_registerScheme:@"http"];
注冊監(jiān)聽 [NSURLProtocol registerClass:[BZURLProtocol class]];
過濾需要進行處理的請求,同時也要過濾那些已經處理過的請求。
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
if ([request.URL.absoluteString containsString:@"localhost"]) {
//看看是否已經處理過了,防止無限循環(huán)
if ([NSURLProtocol propertyForKey:kBZURLProtocolKey inRequest:request]) {
return NO;
}
return YES;
}
return NO;
}
將請求通過下面的方法,進行重新組裝,設置成我們自己的請求
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
將上面組裝好的請求,通過下面的方法發(fā)出。并在這里將發(fā)出的請求,進行標記,因為會重走流程,避免循環(huán)處理
- (void)startLoading {
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
//給我們處理過的請求設置一個標識符, 防止無限循環(huán),
[NSURLProtocol setProperty:@YES forKey:kBZURLProtocolKey inRequest:mutableReqeust];
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
self.task = [session dataTaskWithRequest:self.request];
[self.task resume];
}
這里通過 task 來進行網(wǎng)絡請求發(fā)送,也可以在這里進行請求的緩存處理,加快訪問
最后需要設置代理方法,保證請求被允許和接收到數(shù)據(jù)后的加載
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveResponse:(NSURLResponse *)response
completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
//允許請求加載
[[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageAllowed];
completionHandler(NSURLSessionResponseAllow);
}
- (void)URLSession:(NSURLSession *)session
dataTask:(NSURLSessionDataTask *)dataTask
didReceiveData:(NSData *)data {
//加載數(shù)據(jù)
[[self client] URLProtocol:self didLoadData:data];
}
停止請求的時候注意銷毀對象
- (void)stopLoading {
if (self.task != nil) {
[self.task cancel];
}
}
退出的時候也要注意移除監(jiān)聽
[NSURLProtocol wk_unregisterScheme:@"http"]; [NSURLProtocol unregisterClass:[BZURLProtocol class]];
2.通過第三方庫 GCDWebServer 處理請求
建立 server 要在發(fā)出請求之前
server = [[GCDWebServer alloc] init];
添加監(jiān)控方法,這里提供了很多種選擇,包含了請求方式和異步同步回調等,這里選擇了 GET 方法和異步回調。拿到結果后將其回調給 server ,完成重定向
//異步請求函數(shù)
[server addDefaultHandlerForMethod:@"GET"
requestClass:[GCDWebServerRequest class]
asyncProcessBlock:^(__kindof GCDWebServerRequest * _Nonnull request, GCDWebServerCompletionBlock _Nonnull completionBlock) {
if ([request.URL.absoluteString containsString:@"localhost"]) {
//命中了需要特殊處理的請求,這里進行特定操作
NSURL *url = [NSURL URLWithString:@"http://m.baidu.com/static/search/baiduapp_icon.png"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
//發(fā)出請求
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data && error == nil) {
//接收到正確的數(shù)據(jù),并返回給server
GCDWebServerDataResponse *response = [GCDWebServerDataResponse responseWithData:data contentType:@"image/jpeg"];
completionBlock(response);
} else {
//數(shù)據(jù)請求失敗,返回給server一個空的或者失敗的結果
GCDWebServerDataResponse *response = [GCDWebServerDataResponse response];
completionBlock(response);
}
}];
[task resume];
}
}];
開啟 server [server start];
最后是發(fā)出請求,否則會發(fā)生監(jiān)控不生效的問題

總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
- iOS WKWebView適配實戰(zhàn)篇
- iOs遷至WKWebView跨過的一些坑
- iOS開發(fā)教程之WKWebView與JS的交互
- iOS中WKWebView仿微信加載進度條
- vue 項目 iOS WKWebView 加載
- 簡單說說iOS之WKWebView的用法小結
- iOS使用WKWebView加載HTML5不顯示屏幕寬度的問題解決
- iOS和JS交互教程之WKWebView-協(xié)議攔截詳解
- iOS中wkwebView內存泄漏與循環(huán)引用問題詳解
- iOS中WKWebView白屏問題的分析與解決
- 微信小程序iOS下拉白屏晃動問題解決方案
- iOS WKWebview 白屏檢測實現(xiàn)的示例
相關文章
iOS UICollectionView刷新時閃屏的解決方法
本篇文章主要介紹了iOS UICollectionView刷新時閃屏的解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11

