import "JspWebViewController.h"
import "LoginViewController.h"
import "AppDelegate.h"
import "IdleWindow.h"
import "UIDevice+TFDevice.h"
import <WebKit/WebKit.h>
@interface JspWebViewController ()<WKScriptMessageHandler,WKUIDelegate,WKNavigationDelegate> //(遵守的協(xié)議)
@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
- (void)viewDidLoad {
[super viewDidLoad];
[self configWKWebView];
}
-
(void)configWKWebView{
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
//獲取cookie
NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
NSMutableString *cookieValue = [NSMutableString string];
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for(NSHTTPCookie *cookie in [cookieStorage cookies]) {
[cookieDic setObject:cookie.value forKey:cookie.name];
}
//cookie去重復(fù)凉馆,先放到字典中再去重
for(NSString *key in cookieDic.allKeys){
NSString *appendingStr = [NSString stringWithFormat:@"%@=%@",key,[cookieDic valueForKey:key]];
[cookieValue appendString:appendingStr];
}//js注入cookie甫男,防止從請求頁面返回后再次請求頁面失敗价涝,ios 11以前系統(tǒng)
NSString *cookieSource = [[@"document.cookie = '" stringByAppendingString:cookieValue] stringByAppendingString:@"'"];
WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:cookieSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];//測試將參數(shù)保存到緩存localStorage里,方便后臺調(diào)用女蜈。
NSString *sendTocen = [NSString stringWithFormat:@"localStorage.setItem("accessToken",'%@');localStorage.setItem("testItem",'%@');",[self getUserName],[self getUserSP]];
//設(shè)置js和oc交互§海可以設(shè)置多個
WKUserScript *script = [[WKUserScript alloc] initWithSource:sendTocen injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addScriptMessageHandler:[WeakScriptMessageDelegate alloc] name:@"iOS"];
[userContentController addUserScript:script];//WkwebView 配置協(xié)議
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];
//設(shè)置代理
_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];
//設(shè)置請求頭
[request setValue:cookieValue forHTTPHeaderField:@"Cookie"];
//設(shè)置cookie
// NSDictionary *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
// request.allHTTPHeaderFields = requestHeaderFields;
//設(shè)置post請求
// [request setHTTPMethod:@"POST"];
//加載后臺頁面
[_webView loadRequest:request];
//將導(dǎo)航欄設(shè)置為透明
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;
}
-(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;//關(guān)閉橫屏僅允許豎屏
//切換到豎屏
[UIDevice switchNewOrientation:UIInterfaceOrientationPortrait];
[self.webView goBack];
}else{
AppDelegate * appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
appDelegate.allowRotation = NO;//關(guān)閉橫屏僅允許豎屏
//切換到豎屏
[UIDevice switchNewOrientation:UIInterfaceOrientationPortrait];
[self.view resignFirstResponder];
//返回主菜單原生頁面的時候?qū)Ш綑谠O(shè)置為不透明
self.navigationController.navigationBar.translucent = NO;
[self.navigationController popViewControllerAnimated:YES];
}
}
//解決頁面第一訪問后cookie丟失問題
-
(void)webView:(WKWebView)webView decidePolicyForNavigationResponse:(WKNavigationResponse)navigationResponse decisionHandler:(void(^)(WKNavigationResponsePolicy))decisionHandler{
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
// 頁面開始加載時調(diào)用
-
(void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
if (self.loadingAlert==nil){
self.loadingAlert = [[UIAlertView alloc] initWithTitle:nil
message: @"正在加載數(shù)據(jù),請稍候....."
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];
}
}
// 當內(nèi)容開始返回時調(diào)用
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation{
}
// 頁面加載完成之后調(diào)用
-
(void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
[self.loadingAlert dismissWithClickedButtonIndex:0 animated:YES];
}
//頁面加載失敗時調(diào)用
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
NSLog(@"加載失敗%@", error.userInfo);
}
// 接收到服務(wù)器跳轉(zhuǎn)請求之后調(diào)用
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation{
}
/**
*自建證書沒有得到認證泞遗,訪問https時需要強制信任證書,不知道我理解的有沒有錯
*/
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *_Nullable))completionHandler
{
// 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);
}
}
}
/**
- 將用戶名和密碼放到瀏覽器緩存里席覆,這個是不需要的史辙,懶得該
*/
-
(NSString *)getUserName {
return uname;
} (NSString *)getUserSP {
return usersp01;
}
/**
- web界面中有彈出警告框時調(diào)用
- @param webView 實現(xiàn)該代理的webview
- @param message 警告框中的內(nèi)容
- @param completionHandler 警告框消失調(diào)用
*/
-
(void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler {
//將本地加載等待彈框清除
[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 alloc] init] removeAllCachedResponses]; //清除NSURLCache的緩存
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[loginVC clearCookiesForWkWebView];
[idleWindow setRootViewController:loginVC];
}
completionHandler();
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
/**
-
清除WKWebView 的cookie
*/
-(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調(diào)用confirm方法后回調(diào)的方法 confirm是js中的確定框,需要在block中把用戶選擇的情況傳遞進去
- (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:@"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調(diào)用prompt方法后回調(diào)的方法 prompt是js中的輸入框 需要在block中把用戶輸入的信息傳入
- (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:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
completionHandler(alertController.textFields[0].text?:@"");
}])];
[self presentViewController:alertController animated:YES completion:nil];
}
// 頁面是彈出窗口 _blank 處理
- (WKWebView *)webView:(WKWebView *)webView createWebViewWithConfiguration:(WKWebViewConfiguration *)configuration forNavigationAction:(WKNavigationAction *)navigationAction windowFeatures:(WKWindowFeatures *)windowFeatures {
if (!navigationAction.targetFrame.isMainFrame) {
[webView loadRequest:navigationAction.request];
}
return nil;
}
@end
@implementation WeakScriptMessageDelegate
(instancetype)initWithDelegate:(id<WKScriptMessageHandler>)delegate {
self = [super init];
if (self) {
_delegate = delegate;
}
return self;
}-
(void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if (self.delegate && [self.delegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) {
[self.delegate userContentController:userContentController didReceiveScriptMessage:message];
}
}
@end