亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

ios wkwebview離線化加載h5資源解決方案

2019-10-21 18:41:20
字體:
來源:轉載
供稿:網友

思路: 使用NSURLProtocol攔截請求轉發到本地。

1.確認離線化需求

部門負責的app有一部分使用的線上h5頁,長期以來加載略慢...

于是考慮使用離線化加載。

確保[低速網絡]或[無網絡]可網頁秒開。

2.使用[NSURLProtocol]攔截

區別于uiwebview wkwebview使用如下方法攔截

@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {  [super viewDidLoad];  // 區別于uiwebview wkwebview使用如下方法攔截  Class cls = NSClassFromString(@"WKBrowsingContextController");  SEL sel = NSSelectorFromString(@"registerSchemeForCustomProtocol:");  if ([(id)cls respondsToSelector:sel]) {    [(id)cls performSelector:sel withObject:@"http"];    [(id)cls performSelector:sel withObject:@"https"];  }}
# 注冊NSURLProtocol攔截- (IBAction)regist:(id)sender {  [NSURLProtocol registerClass:[FilteredProtocol class]];}
# 注銷NSURLProtocol攔截- (IBAction)unregist:(id)sender {  [NSURLProtocol unregisterClass:[FilteredProtocol class]];}

3.下載[zip] + 使用[SSZipArchive]解壓

需要先 #import "SSZipArchive.h

- (void)downloadZip {  NSDictionary *_headers;  NSURLSession *_session = [self sessionWithHeaders:_headers];  NSURL *url = [NSURL URLWithString: @"http://10.2.138.225:3238/dist.zip"];  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    // 初始化cachepath  NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];  NSFileManager *fm = [NSFileManager defaultManager];    // 刪除之前已有的文件  [fm removeItemAtPath:[cachePath stringByAppendingPathComponent:@"dist.zip"] error:nil];    NSURLSessionDownloadTask *downloadTask=[_session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {    if (!error) {            NSError *saveError;            NSURL *saveUrl = [NSURL fileURLWithPath: [cachePath stringByAppendingPathComponent:@"dist.zip"]];            // location是下載后的臨時保存路徑,需要將它移動到需要保存的位置      [[NSFileManager defaultManager] copyItemAtURL:location toURL:saveUrl error:&saveError];      if (!saveError) {        NSLog(@"task ok");        if([SSZipArchive unzipFileAtPath:          [cachePath stringByAppendingPathComponent:@"dist.zip"]                  toDestination:cachePath]) {          NSLog(@"unzip ok");// 解壓成功        }        else {          NSLog(@"unzip err");// 解壓失敗        }      }      else {        NSLog(@"task err");      }    }    else {      NSLog(@"error is :%@", error.localizedDescription);    }  }];    [downloadTask resume];}

4.遷移資源至[NSTemporary]

[wkwebview]真機不支持直接加載[NSCache]資源

需要先遷移資源至[NSTemporary]

- (void)migrateDistToTempory {  NSFileManager *fm = [NSFileManager defaultManager];  NSString *cacheFilePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"dist"];  NSString *tmpFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dist"];    // 先刪除tempory已有的dist資源  [fm removeItemAtPath:tmpFilePath error:nil];  NSError *saveError;    // 從caches拷貝dist到tempory臨時文件夾  [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:cacheFilePath] toURL:[NSURL fileURLWithPath:tmpFilePath] error:&saveError];  NSLog(@"Migrate dist to tempory ok");}

5.轉發請求

如果[/static]開頭 => 則轉發[Request]到本地[.css/.js]資源

如果[index.html]結尾 => 就直接[Load]本地[index.html] (否則[index.html]可能會加載失敗)

//// ProtocolCustom.m// proxy-browser//// Created by melo的微博 on 2018/4/8.// Copyright © 2018年 com. All rights reserved.//#import <objc/runtime.h>#import <Foundation/Foundation.h>#import <MobileCoreServices/MobileCoreServices.h>static NSString*const matchingPrefix = @"http://10.2.138.225:3233/static/";static NSString*const regPrefix = @"http://10.2.138.225:3233";static NSString*const FilteredKey = @"FilteredKey";@interface FilteredProtocol : NSURLProtocol@property (nonatomic, strong) NSMutableData  *responseData;@property (nonatomic, strong) NSURLConnection *connection;@end@implementation FilteredProtocol+ (BOOL)canInitWithRequest:(NSURLRequest *)request{  return [NSURLProtocol propertyForKey:FilteredKey inRequest:request]== nil;}+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request{  NSLog(@"Got it request.URL.absoluteString = %@",request.URL.absoluteString);  NSMutableURLRequest *mutableReqeust = [request mutableCopy];  //截取重定向  if ([request.URL.absoluteString hasPrefix:matchingPrefix])  {    NSURL* proxyURL = [NSURL URLWithString:[FilteredProtocol generateProxyPath: request.URL.absoluteString]];    NSLog(@"Proxy to = %@", proxyURL);    mutableReqeust = [NSMutableURLRequest requestWithURL: proxyURL];  }  return mutableReqeust;}+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b{  return [super requestIsCacheEquivalent:a toRequest:b];}# 如果[index.html]結尾 => 就直接[Load]本地[index.html]- (void)startLoading {  NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];  // 標示改request已經處理過了,防止無限循環  [NSURLProtocol setProperty:@YES forKey:FilteredKey inRequest:mutableReqeust];    if ([self.request.URL.absoluteString hasSuffix:@"index.html"]) {    NSURL *url = self.request.URL;     NSString *path = [FilteredProtocol generateDateReadPath: self.request.URL.absoluteString];        NSLog(@"Read data from path = %@", path);    NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];    NSData *data = [file readDataToEndOfFile];    NSLog(@"Got data = %@", data);    [file closeFile];        //3.拼接響應Response    NSInteger dataLength = data.length;    NSString *mimeType = [self getMIMETypeWithCAPIAtFilePath:path];    NSString *httpVersion = @"HTTP/1.1";    NSHTTPURLResponse *response = nil;        if (dataLength > 0) {      response = [self jointResponseWithData:data dataLength:dataLength mimeType:mimeType requestUrl:url statusCode:200 httpVersion:httpVersion];    } else {      response = [self jointResponseWithData:[@"404" dataUsingEncoding:NSUTF8StringEncoding] dataLength:3 mimeType:mimeType requestUrl:url statusCode:404 httpVersion:httpVersion];    }        //4.響應    [[self client] URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];    [[self client] URLProtocol:self didLoadData:data];    [[self client] URLProtocolDidFinishLoading:self];  }  else {    self.connection = [NSURLConnection connectionWithRequest:mutableReqeust delegate:self];  }}- (void)stopLoading{  if (self.connection != nil)  {    [self.connection cancel];    self.connection = nil;  }}- (NSString *)getMIMETypeWithCAPIAtFilePath:(NSString *)path{  if (![[[NSFileManager alloc] init] fileExistsAtPath:path]) {    return nil;  }    CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)[path pathExtension], NULL);  CFStringRef MIMEType = UTTypeCopyPreferredTagWithClass (UTI, kUTTagClassMIMEType);  CFRelease(UTI);  if (!MIMEType) {    return @"application/octet-stream";  }  return (__bridge NSString *)(MIMEType);}#pragma mark - 拼接響應Response- (NSHTTPURLResponse *)jointResponseWithData:(NSData *)data dataLength:(NSInteger)dataLength mimeType:(NSString *)mimeType requestUrl:(NSURL *)requestUrl statusCode:(NSInteger)statusCode httpVersion:(NSString *)httpVersion{  NSDictionary *dict = @{@"Content-type":mimeType,              @"Content-length":[NSString stringWithFormat:@"%ld",dataLength]};  NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:requestUrl statusCode:statusCode HTTPVersion:httpVersion headerFields:dict];  return response;}#pragma mark- NSURLConnectionDelegate- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {  [self.client URLProtocol:self didFailWithError:error];}#pragma mark - NSURLConnectionDataDelegate- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{  self.responseData = [[NSMutableData alloc] init];  [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];}- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {  [self.responseData appendData:data];  [self.client URLProtocol:self didLoadData:data];}- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  [self.client URLProtocolDidFinishLoading:self];}+ (NSString *)generateProxyPath:(NSString *) absoluteURL {  NSString *tmpFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dist"];  NSString *fileAbsoluteURL = [@"file:/" stringByAppendingString:tmpFilePath];  return [absoluteURL stringByReplacingOccurrencesOfString:regPrefix                         withString:fileAbsoluteURL];}+ (NSString *)generateDateReadPath:(NSString *) absoluteURL {  NSString *fileDataReadURL = [NSTemporaryDirectory() stringByAppendingPathComponent:@"dist"];  return [absoluteURL stringByReplacingOccurrencesOfString:regPrefix                         withString:fileDataReadURL];}@end

結語:

完整[DEMO]請參考: https://github.com/meloalright/wk-proxy

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到IOS開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品电影网| 精品二区三区线观看| 久久久天堂国产精品女人| 国产欧美精品一区二区三区介绍| 国产精品高潮粉嫩av| 成人两性免费视频| 欧美色欧美亚洲高清在线视频| 亚洲女在线观看| 成人黄色片网站| 精品伊人久久97| 81精品国产乱码久久久久久| 美女啪啪无遮挡免费久久网站| 日韩av在线免费看| 国自产精品手机在线观看视频| 欧美激情精品久久久久久久变态| 国产成人激情小视频| 91亚洲永久免费精品| 伊人久久精品视频| 欧美午夜性色大片在线观看| 日本亚洲欧洲色α| 色婷婷亚洲mv天堂mv在影片| 韩国三级日本三级少妇99| 成人免费在线视频网站| 国产精品第3页| 色妞一区二区三区| 久久夜色精品国产欧美乱| 国产精品久久一区主播| 热re91久久精品国99热蜜臀| 日本sm极度另类视频| 国产精品69久久久久| 亚洲激情国产精品| 永久555www成人免费| 亚洲精品中文字幕av| 欧美高清视频在线| 在线视频精品一| 国产精品偷伦视频免费观看国产| 中文精品99久久国产香蕉| 正在播放欧美视频| 怡红院精品视频| 狠狠爱在线视频一区| 欧美精品aaa| 国产精品免费一区二区三区都可以| 中文字幕日韩av电影| 97av视频在线| 日韩欧美黄色动漫| 97在线精品国自产拍中文| 91国内精品久久| 92国产精品久久久久首页| 最新亚洲国产精品| 美女视频黄免费的亚洲男人天堂| 韩剧1988免费观看全集| 亚洲精品mp4| 亚洲福利精品在线| 美女av一区二区| 成人av在线天堂| www亚洲精品| 在线日韩av观看| 亚洲自拍偷拍一区| 欧美精品videossex88| 国产精品丝袜白浆摸在线| 最近日韩中文字幕中文| 亚洲成人免费在线视频| 国产精品一区二区久久精品| 欧美激情图片区| 88国产精品欧美一区二区三区| 草民午夜欧美限制a级福利片| 国产在线精品播放| 国产精品久久久久久久久久东京| 久久视频在线看| 91成品人片a无限观看| 国产精品久久久久久久av大片| 欧美日韩国产成人在线观看| 狠狠色狠狠色综合日日小说| 久久精品国产96久久久香蕉| 97国产精品视频| 国产精品白嫩美女在线观看| 97久久精品人人澡人人爽缅北| 亚洲综合一区二区不卡| 欧美片一区二区三区| 欧美日韩国产影院| 久久av红桃一区二区小说| 91精品国产自产在线观看永久| 国产丝袜一区二区三区| 欧美极品少妇全裸体| 永久免费毛片在线播放不卡| 中文字幕亚洲一区二区三区五十路| 岛国av午夜精品| 国产精品嫩草影院久久久| 57pao国产成人免费| 成人乱色短篇合集| 日韩欧美成人区| 久久国内精品一国内精品| 久久国产加勒比精品无码| 青青在线视频一区二区三区| 亚洲欧美国产精品专区久久| 国产精品香蕉av| 欧美一区二区三区精品电影| 欧美一级黑人aaaaaaa做受| 国产精品第二页| 国产精品www色诱视频| 亚洲人成人99网站| 亚洲精品色婷婷福利天堂| 黄色精品一区二区| 欧美综合一区第一页| 欧美精品电影在线| 亚洲精品美女在线观看| 欧美伦理91i| 亚洲国产成人精品久久| 国产欧美日韩丝袜精品一区| 久久久精品999| 欧美乱人伦中文字幕在线| 日本欧美在线视频| 国产91精品在线播放| 欧美国产日韩一区二区在线观看| 欧美国产欧美亚洲国产日韩mv天天看完整| 国产在线一区二区三区| 亚洲激情视频在线播放| 午夜精品一区二区三区在线视| 日韩欧美在线视频| 欧美激情中文字幕乱码免费| 国产精品久久国产精品99gif| 奇米4444一区二区三区| 久久久99久久精品女同性| 国产精品久久久久久久7电影| 亚洲成av人乱码色午夜| 国产精品综合网站| 久久久久久久久91| 欧美高跟鞋交xxxxxhd| 亚洲欧美制服中文字幕| 久久免费精品视频| 日韩欧美亚洲范冰冰与中字| 欧美一区三区三区高中清蜜桃| 久久这里只有精品视频首页| 在线电影中文日韩| 欧美成人精品一区| 免费av一区二区| 成人信息集中地欧美| 亚洲成人性视频| 亚洲欧美日韩久久久久久| 精品国产91久久久久久老师| 欧美—级高清免费播放| 一本色道久久88亚洲综合88| 亚洲a∨日韩av高清在线观看| 久久久999成人| 国产一区二区日韩精品欧美精品| 一区二区在线免费视频| 国产视频观看一区| 91精品国产91久久久久久久久| 美女av一区二区| 国产视频丨精品|在线观看| 亚洲一区中文字幕在线观看| 亚洲级视频在线观看免费1级| 久久久久久久一区二区三区| 欧美日韩一区二区在线| 亚洲人成电影网| 亚洲一品av免费观看| 97国产精品视频| 日韩最新在线视频| 亚洲第一免费播放区| 欧美丝袜一区二区| 丝袜一区二区三区| 91色精品视频在线| 91亚洲va在线va天堂va国| 91香蕉国产在线观看|