【Swift】WKWebView加载HTTPS的链接

WKWebVIew

OC:
HTTPS已经越来越被重视,前面我也写过一系列的HTTPS的相关文章HTTPS从原理到应用(四):iOS中HTTPS实际使用当加载一些HTTPS的页面的时候,如果此网站使用的根证书已经内置到了手机中这些HTTPS的链接可以正常的通过验证并正常加载。但是如果使用的证书(一般为自建证书)的根证书并没有内置到手机中,这时是链接是无法正常加载的,必须要做一个权限认证。开始在UIWebView的时候,是把请求存储下来然后使用NSURLConnection去重新发起请求,然后走NSURLConnection的权限认证通道,认证通过后,在使用UIWebView去加载这个请求。

在WKWebView中,WKNavigationDelegate中提供了一个权限认证的代理方法,这是权限认证更为便捷。代理方法如下:

- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
         
        if ([challenge previousFailureCount] == 0) {
             
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
             
            completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
             
        } else {
             
            completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
             
        }
         
    } else {
         
        completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);   
         
    }
}
// Swift:
func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            if challenge.previousFailureCount == 0 {
                let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
                completionHandler(URLSession.AuthChallengeDisposition.useCredential,credential)
            }else{
                completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge,nil)
            }
        }else{
            completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge,nil)
        }
    }

这个方法比原来UIWebView的认证简单的多。但是使用中却发现了一个很蛋疼的问题,iOS8系统下,自建证书的HTTPS链接,不调用此代理方法。查来查去,原来是一个bug,在iOS9中已经修复,这明显就是不管iOS8的情况了,而且此方法也没有标记在iOS9中使用,这点让我感到有点失望。这样我就又想到了换回原来UIWebView的权限认证方式,但是试来试去,发现也不能使用了。所以关于自建证书的HTTPS链接在iOS8下面使用WKWebView加载,我没有找到很好的办法去解决此问题。这样我不得已有些链接换回了HTTP,或者在iOS8下面在换回UIWebView。如果你有解决办法,也欢迎私信我,感激不尽。

UIWebView

//
//  ViewController.m
//  02-HTTPS
#import "ViewController.h"

@interface ViewController ()<NSURLConnectionDelegate, UIWebViewDelegate>
{
    NSURLRequest *_request;
}
@property (weak, nonatomic) IBOutlet UIWebView *webView;

@end

@implementation ViewController

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

//  NSString *str = [@"http://www.baidu.com" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSString *str = [@"https://kyfw.12306.cn/otn/leftTicket/init" stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url = [NSURL URLWithString:str];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    _request = request;

    if ([str hasPrefix:@"https://"]) { // https请求先发送connection请求,就会安装证书
        NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self];
        [connection start];
        NSLog(@"https请求");
    }else{  // http请求直接加载
        [self.webView loadRequest:request];
    }
}
#pragma mark - NSURLConnectionDelegate 加载https网页,需要实现代理下面两个方法

/**
 *  安装证书
 */
-(void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
    }
    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

/**
 *  安装证书成功之后再加载https网页
 */
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)pResponse {

    self.webView.scalesPageToFit = YES;
    [self.webView loadRequest:_request];
}

/*
 // 另一种方法加载https网页
 - (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace {
 return YES;
 }

  - (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
 [challenge.sender useCredential:[NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust] forAuthenticationChallenge:challenge];
 [self.webView loadRequest:_request];
 }
 */

#pragma mark - UIWebViewDelegate
/*
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{

    NSLog(@"%@", request.URL);
    return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView
{

}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{

}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error
{
}
*/
@end
WKWebView Swift3.0 一款IOS8以后的web加载神器 https://github.com/XFIOSXiaoFeng/SwiftWkWebView 别说了!!!!快上车 WKWebView 支持POST请求 加载本地页面 直接加载网页 JS交互 集成支付宝/微信URL支付功能 仿微信返回按钮 感谢大家的支持 OC版本将不再持续更新 业余爱好 QQ群:384089763 OC版本遗址:https://github.com/XFIOSXiaoFeng/WKWebView NO1 首先得允许访问HTTP链接 HTTPS权限: NSAppTransportSecurity NSAllowsArbitraryLoads API介绍 API属性 //设置navigationBarColor的颜色 var navigationBarColor: UIColor? //是否隐藏进度条 var isProgressHidden = false //注册MessageHandler 需要实现代理方法 var addJavaScriptAry = [String]() //执行JS 需要实现代理方法 var javaScript = String() //设置代理 weak var delegate : WKWebViewDelegate? //右边按钮的值 ItemTag:区分当前按钮 //实现代理方法才能调用点击事件 var rightBarButtonItemTitle : String? var rightBarButtonItemImage : String? var rightBarButtonItemImageH : String? var rightBarButtonItemTag : String? API方法 /// 普通URL加载方式 func load_UrlSting(string:String!) {} /// 加载本地HTML func load_HTMLSting(string:String!) {} /// POST方式请求加载 func load_POSTUrlSting(string:String!,postString:String!) {} /// 添加右侧按钮 func add_rightBarButtonItem(title:String?,image:String?,imageH:String?,itemTag:String?) {} /// 执行JavaScript代码 func run_JavaScript(script:String?) {} API代理方法 //点击右边按钮执行方法 @objc optional func didSelectRightItem(webView:WKWebView,itemTag:String) //注册JS执行代码 @objc optional func didAddScriptMessage(webView:WKWebView,message:WKScriptMessage) //页面执行JS方法 @objc optional func didRunJavaScript(webView:WKWebView,result:Any?,error:Error?)
Swift 中使用 WKWebView 加载绝对路径的 CSS 样式表,可以通过以下步骤来实现: 1. 将 CSS 文件添加到您的项目中。可以拖放 CSS 文件到项目导航器中的适当位置,确保将其添加到正确的目标。 2. 在您的 ViewController 类中,导入 WebKit 框架: ```swift import WebKit ``` 3. 创建一个 WKWebView 的实例,并将其添加到您的视图层次结构中: ```swift let webView = WKWebView(frame: view.bounds) view.addSubview(webView) ``` 4. 使用 `fileURLWithPath` 方法获取 CSS 文件的绝对路径,并通过 `loadFileURL` 方法加载本地 HTML 文件: ```swift if let cssURL = Bundle.main.url(forResource: "style", withExtension: "css") { let htmlPath = Bundle.main.path(forResource: "index", ofType: "html") // index.html 是您的 HTML 文件名 let htmlURL = URL(fileURLWithPath: htmlPath!) webView.loadFileURL(htmlURL, allowingReadAccessTo: cssURL) } ``` 这里假设您的 CSS 文件名为 "style.css",HTML 文件名为 "index.html"。确保将这些文件添加到您的项目中,并指定正确的文件名和扩展名。 5. 在 HTML 文件中,使用 `<link>` 标签将 CSS 样式表链接到页面上。在 `<head>` 标签内,添加以下行: ```html <link rel="stylesheet" type="text/css" href="style.css"> ``` 确保将 "style.css" 替换为您的 CSS 文件名。 这样,当 WKWebView 加载 HTML 文件时,它会自动加载链接的 CSS 样式表并应用于页面。 请注意,确保 CSS 文件和 HTML 文件位于正确的位置,并在项目目标的 Build Phases 中将它们添加到 "Copy Bundle Resources" 列表中,以便在构建时正确复制到应用程序包中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值