WKWebView|WKWebView 使用
import "JspWebViewController.h"
import "LoginViewController.h"
import "AppDelegate.h"
import "IdleWindow.h"
import "UIDevice+TFDevice.h"
import
@property (nonatomic, strong) WKWebView *webView;
@property (strong, nonatomic) UIBarButtonItem *backItem0;
@property (strong, nonatomic) UIButton *btn;
@property(nonatomic,strong)UIAlertView *loadingAlert;
//@property (strong,nonatomic) UIAlertController *loadingAlert;
@end
@implementation JspWebViewController
}
[super viewDidLoad];
[self configWKWebView];
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
//获取cookie
NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
NSMutableString *cookieValue = https://www.it610.com/article/[NSMutableString string];
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for(NSHTTPCookie *cookie in [cookieStorage cookies]) {
[cookieDic setObject:cookie.value forKey:cookie.name];
}
//cookie去重复,先放到字典中再去重
for(NSString *key in cookieDic.allKeys){
NSString *appendingStr = [NSString stringWithFormat:@"%@=%@",key,[cookieDic valueForKey:key]];
[cookieValue appendString:appendingStr];
}
//js注入cookie,防止从请求页面返回后再次请求页面失败,ios 11以前系统
NSString *cookieSource = [[@"document.cookie = '" stringByAppendingString:cookieValue] stringByAppendingString:@"'"];
WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:cookieSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];
//测试将参数保存到缓存localStorage里,方便后台调用。
NSString *sendTocen = [NSString stringWithFormat:@"localStorage.setItem("accessToken",'%@');
localStorage.setItem("testItem",'%@');
",[self getUserName],[self getUserSP]];
//设置js和oc交互。可以设置多个
WKUserScript *script = [[WKUserScript alloc] initWithSource:sendTocen injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addScriptMessageHandler:[WeakScriptMessageDelegate alloc] name:@"iOS"];
[userContentController addUserScript:script];
//WkwebView 配置协议
WKWebViewConfiguration *config = [WKWebViewConfiguration new];
config.userContentController = userContentController;
config.preferences.javaScriptEnabled = YES;
config.preferences.javaScriptCanOpenWindowsAutomatically = YES;
config.suppressesIncrementalRendering = YES;
// 是否支持记忆读取
[config.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
if (@available(iOS 10.0, *)) {
[config setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
}
//定义WKWebView
_webView = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
//设置代理
_webView.UIDelegate = self;
_webView.navigationDelegate = self;
//拼接访问地址
NSString *urlString = "自己的url";
// NSString *urlString = [baseUrl stringByAppendingString:@"JIRA/test.jsp"];
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url];
//设置请求头
[request setValue:cookieValue forHTTPHeaderField:@"Cookie"];
//设置cookie
// NSDictionary *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
// request.allHTTPHeaderFields = requestHeaderFields;
//设置post请求
// [request setHTTPMethod:@"POST"];
//加载后台页面
[_webView loadRequest:request];
//将导航栏设置为透明
self.navigationController.navigationBar.translucent = YES;
[self.view addSubview:_webView];
//重写返回按钮
self.navigationItem.leftBarButtonItem = self.backItem;
}
/**
*重写返回按钮,可以是页面返回上一页
*/
-(UIBarButtonItem *)backItem{
if (!self.backItem0) {
UIButton *back = [UIButton buttonWithType:UIButtonTypeSystem];
[back setImage:[UIImage imageNamed:@"backIcon"] forState:UIControlStateNormal];
//[back setTitle:@"Back" forState:UIControlStateNormal];
back.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
back.titleLabel.font = [UIFont systemFontOfSize:17];
back.frame = CGRectMake(0, 0, 44, 32);
[back addTarget:self action:@selector(back) forControlEvents:UIControlEventAllEvents];
self.backItem0 = [[UIBarButtonItem alloc] initWithCustomView:back];
}return self.backItem0;
}
【WKWebView|WKWebView 使用】-(void)back{
[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(toDoSomeThing: ) object:self.btn];
[self performSelector:@selector(toDoSomeThing:) withObject:self.btn afterDelay:0.8f];
}
-(void)toDoSomeThing:(UIViewController *)vc{
if ([self.webView canGoBack]) {AppDelegate * appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDelegate.allowRotation = NO;
//关闭横屏仅允许竖屏
//切换到竖屏
[UIDevice switchNewOrientation:UIInterfaceOrientationPortrait];
[self.webView goBack];
}else{AppDelegate * appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDelegate.allowRotation = NO;
//关闭横屏仅允许竖屏
//切换到竖屏
[UIDevice switchNewOrientation:UIInterfaceOrientationPortrait];
[self.view resignFirstResponder];
//返回主菜单原生页面的时候导航栏设置为不透明
self.navigationController.navigationBar.translucent = NO;
[self.navigationController popViewControllerAnimated:YES];
}
}
//解决页面第一访问后cookie丢失问题
}
NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
if (@available(iOS 11.0, *)) {
WKHTTPCookieStore *cookieStroe = webView.configuration.websiteDataStore.httpCookieStore;
for(NSHTTPCookie *cookie in cookies) {
[cookieStroe setCookie:cookie completionHandler:nil];
}
}
decisionHandler(WKNavigationResponsePolicyAllow);
pragma mark - WKNavigationDelegate
// 页面开始加载时调用
}
if (self.loadingAlert==nil){
self.loadingAlert = [[UIAlertView alloc] initWithTitle:nil
message: @"正在加载数据,请稍候....."
delegate: self
cancelButtonTitle: nil
otherButtonTitles: nil];
UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
activityView.frame = CGRectMake(120.f, 48.0f, 37.0f, 37.0f);
[self.loadingAlert addSubview:activityView];
[activityView startAnimating];
[self.loadingAlert show];
}
// 当内容开始返回时调用
}
// 页面加载完成之后调用
}
[self.loadingAlert dismissWithClickedButtonIndex:0 animated:YES];
//页面加载失败时调用
// 接收到服务器跳转请求之后调用
{
NSLog(@"加载失败%@", error.userInfo);
}
}
/**
*自建证书没有得到认证,访问https时需要强制信任证书,不知道我理解的有没有错
*/
/**
{
// NSLog(@"=====证书pppp=======");
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
if (challenge.previousFailureCount == 0) {
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
} else {
completionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
}
}
*/
return uname;
}
return usersp01;
}
/**
*/
// [[[NSURLCache alloc] init] removeAllCachedResponses];
//清除NSURLCache的缓存
//将本地加载等待弹框清除
[self.loadingAlert dismissWithClickedButtonIndex:0 animated:YES];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
if([message isEqualToString:@"用户信息过期,请重新登录!"]){
LogInViewController *loginVC = [[LogInViewController alloc] init];
AppDelegate *delegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
IdleWindow *idleWindow = (IdleWindow *)delegate.window;
//这个是我写的记录手机时间超时的
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[loginVC clearCookiesForWkWebView];
[idleWindow setRootViewController:loginVC];
}
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
/**
// 确认框
*/
-(void)clearCookiesForWkWebView{
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0 ){
NSArray *types = @[WKWebsiteDataTypeCookies,WKWebsiteDataTypeSessionStorage];
NSSet *websiteDataTypes = [NSSet setWithArray:types];
NSDate *dateformter = [NSDate dateWithTimeIntervalSince1970:0];
[[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateformter completionHandler:^{
}];
}else{
NSString *libaryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *cookieFolderPath = [libaryPath stringByAppendingString:@"/Cookies"];
NSError *errors;
[[NSFileManager defaultManager] removeItemAtPath:cookieFolderPath error:&errors];
}
}
//JavaScript调用confirm方法后回调的方法 confirm是js中的确定框,需要在block中把用户选择的情况传递进去
// 输入框
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"" message:message?:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addAction:([UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
completionHandler(NO);
}])];
[alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(YES);
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
//JavaScript调用prompt方法后回调的方法 prompt是js中的输入框 需要在block中把用户输入的信息传入
// 页面是弹出窗口 _blank 处理
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:prompt message:@"" preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.text = defaultText;
}];
[alertController addAction:([UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
@end
if (!navigationAction.targetFrame.isMainFrame) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
@implementation WeakScriptMessageDelegate
@end
self = [super init];
if (self) {
_delegate = delegate;
}
return self;
}
if (self.delegate && [self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
[self.delegate userContentController:userContentController didReceiveScriptMessage:message];
}
}
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用
- 使用协程爬取网页,计算网页数据大小