這篇文章主要給大家介紹了關於iOS中WKWebView的一些特殊使用,文中通過示例代碼介紹的非常詳細,對大家學習或者使用iOS具有一定的參考學習價值,需要的朋友們下面隨着小編來一起學習學習吧
前言
現在大部分的app只支持iOS8以上的系統了,在接入H5時可以只管最新的WKWebView了。
WKWebView的優勢
- 性能高,穩定性好,佔用的內存比較小,
- 支持JS交互
- 支持HTML5 新特性
- 可以添加進度條(然並卵,不好用,還是習慣第三方的)。
- 支持內建手勢,
- 據說高達60fps的刷新頻率(不卡)
本文將給大家總結下iOS中WKWebView的一些特殊使用,下面話不多說了,來一起看看詳細的介紹吧
WKWebView 加載本地網頁的方式
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 的特殊性,這裏需要新建類別,並註冊需要監聽的請求頭 [NSURLProtocol wk_registerScheme:@"http"];
註冊監聽 [NSURLProtocol registerClass:[BZURLProtocol class]];
過濾需要進行處理的請求,同時也要過濾那些已經處理過的請求。
+ (BOOL)canInitWithRequest:(NSURLRequest *)request { if ([request.URL.absoluteString containsString:@"localhost"]) { //看看是否已經處理過了,防止無限循環 if ([NSURLProtocol propertyForKey:kBZURLProtocolKey inRequest:request]) { return NO; } return YES; } return NO; }
將請求通過下面的方法,進行重新組裝,設置成我們自己的請求
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
將上面組裝好的請求,通過下面的方法發出。並在這裏將發出的請求,進行標記,因爲會重走流程,避免循環處理
- (void)startLoading { NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy]; //給我們處理過的請求設置一個標識符, 防止無限循環, [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 來進行網絡請求發送,也可以在這裏進行請求的緩存處理,加快訪問
最後需要設置代理方法,保證請求被允許和接收到數據後的加載
- (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 { //加載數據 [[self client] URLProtocol:self didLoadData:data]; }
停止請求的時候注意銷燬對象
- (void)stopLoading { if (self.task != nil) { [self.task cancel]; } }
退出的時候也要注意移除監聽
[NSURLProtocol wk_unregisterScheme:@"http"]; [NSURLProtocol unregisterClass:[BZURLProtocol class]];
2.通過第三方庫 GCDWebServer 處理請求
建立 server 要在發出請求之前
server = [[GCDWebServer alloc] init];
添加監控方法,這裏提供了很多種選擇,包含了請求方式和異步同步回調等,這裏選擇了 GET 方法和異步回調。拿到結果後將其回調給 server ,完成重定向
//異步請求函數 [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]; //發出請求 NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (data && error == nil) { //接收到正確的數據,並返回給server GCDWebServerDataResponse *response = [GCDWebServerDataResponse responseWithData:data contentType:@"image/jpeg"]; completionBlock(response); } else { //數據請求失敗,返回給server一個空的或者失敗的結果 GCDWebServerDataResponse *response = [GCDWebServerDataResponse response]; completionBlock(response); } }]; [task resume]; } }];
開啓 server [server start];
最後是發出請求,否則會發生監控不生效的問題
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對神馬文庫的支持。