UIWebview

330 阅读2分钟

常见的问题

  1. 注入的js 方法,h5必须在代理- (void)webViewDidFinishLoad:(UIWebView *)webView之后
  2. 判断页面是否加载成功,根据- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;是不准的,
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"__%s",__func__);
    _superWebView = webView;
    if (request && [GB_ToolUtils isNotBlank:[request.URL host]] && [request.URL.absoluteString hasPrefix:@"http"]) {
        //判断加载是否成功
        NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSHTTPURLResponse *tmpResponse = (NSHTTPURLResponse *)response;
            NSLog(@"加载url=%@ 状态==%li",request.URL,tmpResponse.statusCode);
            dispatch_async(dispatch_get_main_queue(), ^{
                if ((tmpResponse.statusCode == 200 || tmpResponse.statusCode == 304 || tmpResponse.statusCode == 307)) {
                    //加载失败
                }else{
                    if (self.baseH5SuperUrl && [self.baseH5SuperUrl isEqualToString:request.URL.absoluteString]) {
                        加载成功
                    }
                }
            });
        }];
        
        [dataTask resume];
    }
    
    return YES;
}

首先,肯定是从didFailLoadWithError代理方法入手,发现请求到404页面时,并没有调用该方法,这是为什么呢?原来,该方法时加载过程出现问题调用,我们顺利的得到了404页面,就不算加载过程的问题。  通过具体代码分析发现,放在shouldStartLoadWithRequest和webViewDid FinishLoad都可以得到相应的状态码,放在webViewDidStartLoad得到的状态码都是0.经过分析发现,调用webViewDidStartLoad方法时,request请求已经发起正在等待服务器处理结果。

 NSURLSessionDataTask * dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:webView.request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSHTTPURLResponse *tmpresponse = (NSHTTPURLResponse*)response;
    NSLog(@"statusCode:%ld", tmpresponse.statusCode);
  }];
  [dataTask resume];
  1. 动态获取uiwebview 高度问题, A.用 double webViewHeight = [[self.webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight"] floatValue]; 不是很准 B.采用 kvo监听webview.scrollView contentSize 这个准

  2. dataDetectorTypes 检测网页 手机号码、地址、邮箱等 scalesPageToFit 设置后,用户可以手势缩放 点击h5里的链接地址,打开safari去打开

      - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSURL *requestURL = [request URL];
    if (([[requestURL scheme] isEqualToString:@"http"]||[[requestURL scheme] isEqualToString:@"https"]||[[requestURL scheme] isEqualToString: @"mailto"])
        && (navigationType == UIWebViewNavigationTypeLinkClicked)){
        return ![[UIApplication sharedApplication] openURL:requestURL];
    }
}

5.下载后的txt 文件预览乱码
txt有带编码与不带编码两种。 带编码的txt可以使用string的stringWithContentsOfFile读出。 不带编码的txt可以尝试使用GBK和GB18030编码读出。

GBK : 0x80000632 , GB18030 :  0x80000631
NSURL *txtUrl = [[NSBundle mainBundle] URLForResource:@"test1" withExtension:@"txt"];
NSString *body = [NSString stringWithContentsOfURL:txtUrl encoding:0x80000632 error:nil];
if (!body) {
body = [NSString stringWithContentsOfURL:txtUrl encoding:0x80000631 error:nil];
}

if (body) {
    [self.webview loadHTMLString:body baseURL:nil];
  }else{
    [self.webview loadRequest:[NSURLRequest requestWithURL:txtUrl]];
  }

6.请求拦截 NSURLProtocol
www.jianshu.com/p/2ed92d399…

7.读取cookie,原生操作

#### 添加cookie requestURLStr 必须有值
- (void)addCookie:(NSString *)requestURLStr
{
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    [params setValue:@"nantong" forKey:@"appCookieSchool"];
    [params setValue:@"xuzhou" forKey:@"hometown"];
    
    NSURL *url = [NSURL URLWithString:requestURLStr];
    
    [params enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        //设定cookie
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        [dict setValue:[url host] forKey:NSHTTPCookieDomain];
        [dict setValue:[url path] forKey:NSHTTPCookiePath];
        [dict setValue:key forKey:NSHTTPCookieName];
        [dict setValue:obj forKey:NSHTTPCookieValue];
        //设置失效时间
        [dict setObject:[NSDate dateWithTimeIntervalSinceNow:60*3600] forKey:NSHTTPCookieExpires];
        //设置sessionOnly
        [dict setObject:@"0" forKey:NSHTTPCookieDiscard];
        NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:dict];
        if(cookie){
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
        }
    }];
}


#### 清除cookie 会清空所有app + h5写入的cookie
- (void)clearCookie
{
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSArray *cookieArray = [NSArray arrayWithArray:[cookieJar cookies]];
    for (id obj in cookieArray) {
        [cookieJar deleteCookie:obj];
    }
}

h5操作cookie

 function insertNode(){
        var elementnode = document.createElement("li");
        alert(document.cookie)
        var context = document.createTextNode(document.cookie);
        elementnode.appendChild(context);
        var list = document.getElementById("list")
        list.insertBefore(elementnode,list.childNodes[2]);
    }
    
    
    function  setCookie(c_name,value,expiredays) {
        var exdate=new Date()
        exdate.setDate(exdate.getDate()+expiredays)
        document.cookie=c_name+ "=" +escape(value)+
        ((expiredays==null) ? "" : ";expires="+exdate.toGMTString())
    }