wkwebview开发常见问题(wkwebview加载本地沙盒文件)

wkwebview加载本地沙盒文件是wkwebview开发中一个很常见的问题,今天对该问题进行一个较为详细的记录

1、#pragma mark -https认证

//web项目里面,使用了https认证的问题
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential,card);
    }
}

2、隐藏状态栏:

    NSString *phoneVersion = [[UIDevice currentDevice] systemVersion];
    NSArray *versionarr = [phoneVersion componentsSeparatedByString:@"."];
    if ([[versionarr objectAtIndex:0] integerValue]<11) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }else{
        self.myweb.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;//隐藏顶部状态栏,还要设置空间全屏
    }

3、禁止WKWebView的手势捏拉缩放

//推选这个方法;这个方法在11.3.1和11.2.6都有效
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation {
    // 禁止放大缩小
    NSString *injectionJSString = @"var script = document.createElement('meta');"
    "script.name = 'viewport';"
    "script.content=\"width=device-width, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0, user-scalable=no\";"
    "document.getElementsByTagName('head')[0].appendChild(script);";
    [webView evaluateJavaScript:injectionJSString completionHandler:nil];
}

 //这个方法在11.3.1无效。11.2.6有效
    self.myweb.scrollView.delegate = self;
//禁止手指捏合和放大
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return nil;
}

4、我第一次合作是ionic写的界面。
WKPreferences preferences = [WKPreferences new];
preferences.minimumFontSize = 40.0;
后来另外一个web工程师用vue写的界面。同样的工程加载出来的界面,总是fontSize很大。
我更改 preferences.minimumFontSize = 15.0;解决了这个问题。minimumFontSize大致意思:web的一个px是多大。官网是
/
! @abstract The minimum font size in points.
@discussion The default value is 0.
*/
5、弹出系统提示框:

//web界面中有弹出警告框时调用
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler();
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:([UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(NO);
    }])];
    [alertController addAction:([UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(YES);
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable))completionHandler{
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
    [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        textField.text = defaultText;
    }];
    [alertController addAction:([UIAlertAction actionWithTitle:@"完成" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        completionHandler(alertController.textFields[0].text?:@"");
    }])];
    [self presentViewController:alertController animated:YES completion:nil];
}

6、三种加载html的方式:

  • 1、加载远程网页:
    NSString *urlstr = @"https://junction.dev.havensphere.com/static/086test1/r003/phone/index.html";
    NSURL *url =[NSURL URLWithString:urlstr];
    NSURLRequest *request =[NSURLRequest requestWithURL:url];
    [self.myweb loadRequest:request];
    [self.view addSubview:self.myweb];

  • 2、加载项目工程网页:
    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
    WKPreferences *preferences = [WKPreferences new];
    preferences.javaScriptCanOpenWindowsAutomatically = YES;
    preferences.minimumFontSize = 15.0;
    configuration.preferences = preferences;

    self.myweb = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, Screen_Width, Screen_Height) configuration:configuration];
    self.myweb.navigationDelegate = self;
    self.myweb.UIDelegate = self;
    self.myweb.scrollView.delegate = self;
    self.myweb.scrollView.contentSize= CGSizeMake(Screen_Width, Screen_Height);
    self.myweb.scrollView.bounces = false;

    NSString *bundleFile = [[NSBundle mainBundle] pathForResource:@"HTML" ofType:@"bundle"];
    NSString *path = [bundleFile stringByAppendingString:@"/dist/index.html"];
    NSURL *fileURL = [NSURL fileURLWithPath:path];
    NSURLRequest *request = [NSURLRequest requestWithURL:fileURL];
    [self.myweb loadRequest:request];
    [self.view addSubview:self.myweb];

    NSString *phoneVersion = [[UIDevice currentDevice] systemVersion];
    NSArray *versionarr = [phoneVersion componentsSeparatedByString:@"."];
    if ([[versionarr objectAtIndex:0] integerValue]<11) {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }else{
        self.myweb.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;//隐藏顶部状态栏,还要设置空间全屏
        self.mywebui.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;//隐藏顶部状态栏,还要设置空间全屏
    }    
//点击web界面跳转时候执行的方法
-(WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures
{
    NSLog(@"createWebViewWithConfiguration");
    if (!navigationAction.targetFrame.isMainFrame) {
        [webView loadRequest:navigationAction.request];
    }
    return nil;
}
// 在发送请求之前,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    decisionHandler(WKNavigationActionPolicyAllow);
    return;
}
// 页面开始加载时调用
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
    //    [MBProgressHUD showInView:self.view message:@"正在加载网页!!"];
    [self.activityIndiactorView  startAnimating];
    NSLog(@"didStartProvisionalNavigation");
}
// 在收到响应后,决定是否跳转
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    decisionHandler(WKNavigationResponsePolicyAllow);
    NSLog(@"decidePolicyForNavigationResponse");
    self.responsecount++;
    if (self.responsecount==7) {//处理加载时间很长的时候的加载问题
        [self.activityIndiactorView  stopAnimating];
    }
    return;
}

// 当内容开始返回时调用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
    self.responsecount = 0;
    NSLog(@"didCommitNavigation");
}
// 页面加载完成之后调用
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
    [self.activityIndiactorView  stopAnimating];
    NSLog(@"didFinishNavigation");
}
// 页面加载失败时调用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation{
    [self.activityIndiactorView  stopAnimating];
    NSLog(@"didFailProvisionalNavigation");
}
// 接收到服务器跳转请求之后调用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
    NSLog(@"didReceiveServerRedirectForProvisionalNavigation");
    NSLog(@"%s", __FUNCTION__);
}

  • 3从接口下载压缩包,解压缩再加载出来。(本地沙盒目录指这几个:Library/Preferences、Library/Caches、Documents
//请求当前项目压缩包版本号。如果版本号比本地版本号大或者本地没有,请求zip压缩包;如果版本号和本地一样,直接加载本地web数据。
-(void)getversion{
    [MBProgressHUD showInView:self.view indicatorMessage:@"正在加载网页版本数据" duration:-1];
    // 1.获得请求管理者
    AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
    // 2.申明返回的结果是text/html类型
    mgr.responseSerializer = [ AFJSONResponseSerializer serializer];
    // 3.发送GET请求
    [mgr GET:@"http://101.132.91.12:8681/iot/app/info?id=1" parameters:nil progress::^(NSProgress * _Nonnull downloadProgress) {
        NSLog(@"%@",downloadProgress);
    }  success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSDictionary *dic = (NSDictionary *)responseObject;
        NSString *version = [[[dic objectForKey:@"content"]objectAtIndex:0]objectForKey:@"versioncode"];
        NSString *defaultsversion = [[NSUserDefaults standardUserDefaults] objectForKey:@"versioncode"];
        self.defaultsversion = version;
        if (defaultsversion==nil) {
            [MBProgressHUD showInView:self.view indicatorMessage:@"请求云端数据,请稍等" duration:-1];
            [self rquestZipArchivePath:@"http://101.132.91.12:8681/iot/file/app/iot.zip"];
            return ;
        }
        if ([version intValue]>[defaultsversion intValue]) {
            [MBProgressHUD showInView:self.view indicatorMessage:@"请求云端数据,请稍等" duration:-1];
            [self rquestZipArchivePath:@"http://101.132.91.12:8681/iot/file/app/iot.zip"];
            return ;
        }
        NSArray *documentArray =  NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
        NSString *path1 = [[documentArray lastObject] stringByAppendingPathComponent:@"Preferences"];
        if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/iot",path1]])
        {
            [self loadWebData];
        }else{
            [MBProgressHUD showInView:self.view indicatorMessage:@"请求云端数据,请稍等" duration:-1];
            [self rquestZipArchivePath:@"http://101.132.91.12:8681/iot/file/app/iot.zip"];
        }
        NSLog(@"responseObject:%@",version);
        return ;
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [MBProgressHUD hideHUDForView:self.view];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"本地网页版本不存在,请重启软件程序!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil];
        [alert show];

        NSLog(@"error:%@",error);
    }];
}
#pragma mark 请求zip地址
//请求到的压缩包数据,进行解压
-(void)rquestZipArchivePath:(NSString *)pathUrl{
    //远程地址
    NSURL *URL = [NSURL URLWithString:pathUrl];
    //默认配置
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
    //请求
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    NSURLSessionDownloadTask * downloadTask= [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) {
        //- block的返回值, 要求返回一个URL, 返回的这个URL就是文件的位置的路径

        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

        //再次之前先删除本地文件夹里面相同的文件夹
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray *contents = [fileManager contentsOfDirectoryAtPath:cachesPath error:NULL];
        NSEnumerator *e = [contents objectEnumerator];
        NSString *filename;
        NSString *extension = @"zip";
        while ((filename = [e nextObject])) {
            if ([[filename pathExtension] isEqualToString:extension]) {
                [fileManager removeItemAtPath:[cachesPath stringByAppendingPathComponent:filename] error:NULL];
            }
        }
        NSString *path = [cachesPath stringByAppendingPathComponent:response.suggestedFilename];
        return [NSURL fileURLWithPath:path];
    } completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) {
        if (error==nil) {
            //设置下载完成操作
            // filePath就是你下载文件的位置,你可以解压,也可以直接拿来使用
            NSString *htmlFilePath = [filePath path];// 将NSURL转成NSString
            NSArray *documentArray =  NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
            NSString *path = [[documentArray lastObject] stringByAppendingPathComponent:@"Preferences/"];
            NSFileManager *fileManager = [NSFileManager defaultManager];
            [fileManager removeItemAtPath:[NSString stringWithFormat:@"%@/iot",path] error:nil];
            [self releaseZipFilesWithUnzipFileAtPath:htmlFilePath Destination:path];
            return ;
        }
        [MBProgressHUD hideHUDForView:self.view];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"网页数据下载失败,请重启软件程序!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil];
        [alert show];
    }];
    [downloadTask resume];
}
#pragma mark 解压
//把压缩包数据解压到本地后,要想加载出来,必须把document数据复制到Preferences文件夹
- (void)releaseZipFilesWithUnzipFileAtPath:(NSString *)zipPath Destination:(NSString *)unzipPath{
    NSError *error;
    if ([SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath overwrite:YES password:nil error:&error delegate:self]) {

        NSString *path = [unzipPath stringByAppendingString:@"/iot"];
        NSFileManager *fileManager1 = [NSFileManager defaultManager];
        NSString *tmpPath2 = NSTemporaryDirectory();
        if ([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@iot",tmpPath2]]){
            [fileManager1 removeItemAtPath:[NSString stringWithFormat:@"%@iot",tmpPath2] error:nil];
        }
        [fileManager1 copyItemAtPath:[NSString stringWithFormat:@"%@/iot",path] toPath:[NSString stringWithFormat:@"%@iot",tmpPath2] error:nil];
        [[NSUserDefaults standardUserDefaults] setObject:self.defaultsversion forKey:@"versioncode"];
        [[NSUserDefaults standardUserDefaults] synchronize];
        [self loadWebData];
//        NSLog(@"解压缩成功!");
    }
    else{
        [MBProgressHUD hideHUDForView:self.view];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"解压数据失败,请重启软件程序!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil];
        [alert show];
    }
}
//加载本地沙盒目录下的index.html(本地沙盒目录指这几个:Library/Preferences、Library/Caches、Documents)
-(void)loadWebData{
    NSArray *documentArray =  NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *path1 = [[documentArray lastObject] stringByAppendingPathComponent:@"Preferences"];
    NSFileManager *fileManager1 = [NSFileManager defaultManager];
    if([[NSFileManager defaultManager] fileExistsAtPath:[NSString stringWithFormat:@"%@/iot",path1]])
    {
    //第一步:找到文件所在目录
        NSArray *LibraryArray =  NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
        NSString *CachesPath = [[LibraryArray lastObject] stringByAppendingPathComponent:@"Caches"];
        NSString *indexPath = [CachesPath stringByAppendingPathComponent:@"/dist/index.html"];
        //第二步:创建加载URL和访问权限URL(加载URL:访问的初始文件一般是index;访问权限URL:所有html、js、资源文件所在的文件夹一般是项目文件名字)。注意如果没有访问权限URL,html没办法加载相关的js和资源文件。
        //创建加载URL方法一:
    //    indexPath=[[NSURL fileURLWithPath:indexPath]absoluteString];
    //    NSURL *loadurl =[NSURL URLWithString:indexPath];//URLWithString后面的path1必须前面有file:///,[[NSURL fileURLWithPath:path1]absoluteString]这个处理可以得到file:///
        //创建加载URL方法二:
        NSURL *loadurl =[NSURL fileURLWithPath:indexPath];//fileURLWithPath后面跟的是文件目录不需要file:///
        //创建访问权限URL
        NSString *accessURLStr = [[[LibraryArray lastObject] stringByAppendingPathComponent:@"Caches"] stringByAppendingPathComponent:@"/dist"];
        NSURL *accessURL = [NSURL fileURLWithPath:accessURLStr];
        //第三步:进行加载
        [self.myweb loadFileURL:loadurl allowingReadAccessToURL:accessURL];
        [MBProgressHUD showInView:self.view successMessage:@"网页加载成功!"];
    }else{
        [MBProgressHUD hideHUDForView:self.view];
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"本地网页配置文件不存在,请重启软件程序!" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK",nil];
        [alert show];
    }
}

注意:
1、解压缩功能要导入SSZipArchive库(包含minizip和aes),导入后出现了20多个错误,解决办法:
选择所有.c文件,将属性的 identity and type 改为Objective-C Source
2、下载功能需要导入AFNetworking库。
3、加载本地沙盒功能主要针对文件夹里面除了html还有js和其它资源文件,如果只有一个html文件,那accessURL就是loadURL。这里沙盒目录主要指:Library/Preferences、Library/Caches、Documents(建议使用Library/Caches)。

7、js和原生交互:
参考文章:iOS下JS与OC互相调用(六)--WKWebView + WebViewJavascriptBridge

1、引入工作:WebViewJavascriptBridge文件夹
@property WKWebViewJavascriptBridge *webViewBridge;
2、创建WebViewJavascriptBridge实例。
    _webViewBridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];
// 如果控制器里需要监听WKWebView 的`navigationDelegate`方法,就需要添加下面这行。
[_webViewBridge setWebViewDelegate:self];
3、iOS语法:web调用iOS的方法:
    [_webViewBridge registerHandler:@"locationClick" handler:^(id data, WVJBResponseCallback responseCallback) {
        NSDictionary *tempDic = data;
        NSLog(@"%@",tempDic);
        // 获取位置信息
        NSString *location = @"广东省深圳市南山区学府路XXXX号";
        // 将结果返回给js        
        responseCallback(location);//responseCallback(nil);
    }];
注意:
(1)、js可以传数字给iOS,iOS通过[data isKindOfClass:[NSNumber class]]判断是不是数字类型
(2)、iOS返回可以是数字类型如@1。
(3)、无返回的情况
js方法:
 WebViewJavascriptBridge.callHandler('colorClick',params);
iOS方法:
 [_webViewBridge registerHandler:@"colorClick" handler:^(id data, WVJBResponseCallback responseCallback) {
 // data 的类型与 JS中传的参数有关
 NSDictionary *tempDic = data;

 CGFloat r = [[tempDic objectForKey:@"r"] floatValue];
 CGFloat g = [[tempDic objectForKey:@"g"] floatValue];
 CGFloat b = [[tempDic objectForKey:@"b"] floatValue];
 CGFloat a = [[tempDic objectForKey:@"a"] floatValue];

 weakSelf.webView.backgroundColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a];
 }];
(4)、传入数字类型时候,如果用数字类型作为key去找[[NSUserDefaults standardUserDefaults] objectForKey:key],会导致崩溃。
4、iOS语法:iOS调用web方法:
* (1)、传字符串给js,所以如果是json或者array都需要转换成字符串传递。
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    NSData *jsonData= [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
    NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    NSString *jsStr = [NSString stringWithFormat:@"backMQTTData('%@')",jsonString];
    [self.myweb evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {}];//wkwebview执行方法
* (2)、传数字给js。(传bool类型时候数字为0或者1就可以)
        NSString *jsStr = [NSString stringWithFormat:@"iOSCallJS(%@)",@0];
        [self.myweb evaluateJavaScript:jsStr completionHandler:^(id _Nullable result, NSError * _Nullable error) {}];//wkwebview执行方法
                alert(typeof(istrue));//number
                alert(istrue);
5、js语法:
 if (window.AndroidWebView) {

  }else if(window.WebViewJavascriptBridge){
         WebViewJavascriptBridge.callHandler(funName,iosKey,function(response) {
            if(methodType==APPCONFIG.METHOD_GET){
                callback(response);
            }
         });
    }
注意:调用安卓方法时候是顺序执行的,而调用iOS的时候顺序执行完成后,在回调到callHandler里面的。

8、iOS11后web输入框键盘升起不回落问题

@interface BaseWebViewVC ()<WKUIDelegate,WKNavigationDelegate>
/** 键盘谈起屏幕偏移量 */
@property (nonatomic, assign) CGPoint keyBoardPoint;
@end
- (void)viewDidLoad {
    [super viewDidLoad];
    //增加键盘升起和降落监听通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}
#pragma mark - 键盘升起和降落通知监听方法,原生调用js方法放回给js
- (void) keyboardWillShow : (NSNotification*)notification {
    NSLog(@"keyboardWillShow");
    CGPoint point = self.myweb.scrollView.contentOffset;
    self.keyBoardPoint = point;
}
- (void) keyboardWillHide : (NSNotification*)notification {
    NSLog(@"keyboardWillHide");
    self.myweb.scrollView.contentOffset = self.keyBoardPoint;    
}

9、加载远程地址,地址网页内容更新iOS不更新问题

-(void)initRemoteWebViewWithUrl:(NSString *)urlStr{
    __block NSString *urlblock = urlStr;
    NSURL *url =[NSURL URLWithString:urlStr];
    NSURLRequest *request;
    NSArray *usercache = [[NSUserDefaults standardUserDefaults] objectForKey:urlblock];
    NSLog(@"web:获取缓存更新日期:%@",usercache);
    if (usercache==nil) {
        NSLog(@"web:没有缓存更新日期");
        request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
    }else if ([usercache[0] isEqualToString:usercache[1]]){
        NSLog(@"web:缓存更新日期一致");
        request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5];
    }else{
        NSLog(@"web:缓存更新日期不一致");
        request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
    }
    [self.myweb loadRequest:request];
    request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:5];
    [[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
        NSLog(@"httpResponse == %@", httpResponse);
        if (httpResponse==nil) {
            NSLog(@"web:httpResponse为空");
        }else{
            NSString *lastModified = [httpResponse.allHeaderFields objectForKey:@"Last-Modified"];
            if (!(lastModified==nil||lastModified.length==0)) {
                NSArray *usercacheblock = [[NSUserDefaults standardUserDefaults] objectForKey:urlblock];
                NSArray *userobject;
                if (usercacheblock==nil||usercacheblock.count==0) {
                    userobject = [[NSArray alloc] initWithObjects:lastModified,lastModified, nil];
                }else{
                    userobject = [[NSArray alloc] initWithObjects:usercacheblock[1],lastModified, nil];
                }
                NSLog(@"web:存储缓存更新日期:%@",userobject);
                [[NSUserDefaults standardUserDefaults] setObject:userobject forKey:urlblock];
            }
        }
    }] resume];
}

作为一个开发者,有一个学习的氛围和一个交流圈子特别重要,这是我的交流群(123),大家有兴趣可以进群里一起交流学习

原文地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345