iOS WKWebView与JS交互
#import "DCWKViewController.h"
#import <WebKit/WebKit.h>
#define URL_define @"URL"
@interface DCWKViewController ()<WKUIDelegate,WKNavigationDelegate,WKScriptMessageHandler,UIGestureRecognizerDelegate>
@property (nonatomic, retain) WKWebView* wkWebView;
@property (nonatomic, strong) NSArray *dataArray;
@end
@implementation DCWKViewController
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
//监听当前网页链接
[self addwebViewKVOUrl];
}
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self removeWebViewKVOUrl];
}
- (void)viewDidLoad {
[super viewDidLoad];
//头部安全距离
UIView *headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, [self vg_statusBarHeight])];
headView.backgroundColor = [UIColor cz_ToUIColorByStr:@"#ffffff"];
[self.view addSubview:headView];
//底部安全距离
UIView* bottomView = [[UIView alloc]initWithFrame:CGRectMake(0, SCREEN_HEIGHT - kBottomSafeHeight, SCREEN_WIDTH, kBottomSafeHeight)];
bottomView.backgroundColor = [UIColor cz_ToUIColorByStr:@"#ffffff"];
[self.view addSubview:bottomView];
self.view.backgroundColor = UIColor.redColor;
self.dataArray = @[@"weixin://", @"wechat://", @"alipay://",@"alipays://", @"mqqapi://", @"mqq://", @"mqqwpa://",@"itms-"];
[self setUI];
}
//初始化WKWebView
- (void)setUI{
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.selectionGranularity = WKSelectionGranularityDynamic;
config.allowsInlineMediaPlayback = YES;
WKPreferences *preferences = [WKPreferences new];
preferences.javaScriptEnabled = YES;
preferences.javaScriptCanOpenWindowsAutomatically = YES;
config.preferences = preferences;
self.wkWebView = [[WKWebView alloc]initWithFrame:CGRectMake(0, [self vg_statusBarHeight], SCREEN_WIDTH, SCREEN_HEIGHT - [self vg_statusBarHeight] - kBottomSafeHeight) configuration:config];
// self.wkWebView.frame = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT - kBottomSafeHeight);
[self.view addSubview:self.wkWebView];
self.wkWebView.allowsBackForwardNavigationGestures = YES;
self.wkWebView.navigationDelegate = self;
self.wkWebView.UIDelegate = self;
[self.wkWebView goBack];
[self.wkWebView goForward];
[self.wkWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"www.baidu.com"]]];
// [self.wkWebView reload];
//添加长按手势
UILongPressGestureRecognizer *lp = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
lp.minimumPressDuration = 1;
lp.delegate = self;
[self.wkWebView addGestureRecognizer:lp];
}
- (void)addwebViewKVOUrl{
[self.wkWebView addObserver:self forKeyPath:URL_define options:NSKeyValueObservingOptionNew context:nil];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
if ([keyPath isEqualToString:@"URL"]){
NSString *urlStr = KString(self.wkWebView.URL.absoluteString);
NSLog(@"urlStr == %@",urlStr);
}
}
- (void)removeWebViewKVOUrl{
[self.wkWebView removeObserver:self forKeyPath:URL_define];
}
#pragma mark - 结束
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
[SVProgressHUD show];
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error {
[SVProgressHUD dismiss];
}
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
//ios与js交互
//保存token到web localStorage
// BOOL isSaveToken = [KUserDefaults boolForKey:@"isSaveToken"];
// if (isSaveToken == NO) {
// NSString *jsString = [NSString stringWithFormat:@"localStorage.setItem('token', '%@')", _token];
// [self.wkWebView evaluateJavaScript:jsString completionHandler:nil];
// [KUserDefaults setBool:YES forKey:@"isSaveToken"];
// [self.wkWebView reload];
// }
// 获取localStorage
// NSString *getWishMajorjsString = @"localStorage.getItem('token')";
// [self.wkWebView evaluateJavaScript:getWishMajorjsString completionHandler:^(id data, NSError * _Nullable error) {
//
// if (![data isKindOfClass:[NSNull class]]) {
// NSData *nowData = [data dataUsingEncoding:NSUTF8StringEncoding];
// NSArray *dataArray = [NSJSONSerialization JSONObjectWithData:nowData options:0 error:nil];
//
// // debugLog(@"%@", dataArray);
// KLog(@"%@", dataArray);
// }
// }];
[self.wkWebView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none'" completionHandler:nil];
[self.wkWebView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none'" completionHandler:nil];
[SVProgressHUD dismiss];
}
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error{
[SVProgressHUD dismiss];
}
- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
// NSURLRequest *request = navigationAction.request;
// NSString *scheme = [request.URL scheme];
NSString *absoluteString = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
// NSLog(@"Current URL is %@",absoluteString);
//跳转支付宝,微信,qq,safari
for (NSString* str in self.dataArray) {
if ([absoluteString containsString:str]) {
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:navigationAction.request.URL options:@{} completionHandler:^(BOOL success) {}];
} else {
[[UIApplication sharedApplication] openURL:navigationAction.request.URL];
}
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
}
decisionHandler(WKNavigationActionPolicyAllow);
}
#pragma mark - 保存图片
- (void)handleLongPress:(UILongPressGestureRecognizer *)sender{
if (sender.state != UIGestureRecognizerStateBegan) {
return;
}
CGPoint touchPoint = [sender locationInView:self.wkWebView];
CGFloat ptX, ptY;
ptX = touchPoint.x;
ptY = touchPoint.y;
[self.wkWebView evaluateJavaScript:[NSString stringWithFormat:@"document.elementFromPoint(%f, %f).tagName", ptX, ptY] completionHandler:^(id _Nullable response, NSError * _Nullable error) {
NSString * tagName = response;
if ([tagName isEqualToString:@"IMG"]) {
[self->_wkWebView evaluateJavaScript:[NSString stringWithFormat:@"document.elementFromPoint(%f, %f).src", ptX, ptY] completionHandler:^(id _Nullable response, NSError * _Nullable error) {
NSString * imgUrl = response;
if (imgUrl) {
UIImage *img = [self downloadImage:imgUrl];
if (!img) {
NSLog(@"读取图片失败");
return;
}
UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction* cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * action) {
}];
UIAlertAction* saveAction = [UIAlertAction actionWithTitle:@"保存图片" style:UIAlertActionStyleDefault handler:^(UIAlertAction * action) {
UIImageWriteToSavedPhotosAlbum(img,self, @selector(image:didFinishSavingWithError:contextInfo:),nil);
}];
[alert addAction:cancelAction];
[alert addAction:saveAction];
[self presentViewController:alert animated:YES completion:nil];
}
}];
}
}];
}
- (UIImage *)downloadImage:(NSString *)urlString {
NSURL *url = [NSURL URLWithString: urlString];
UIImage *img;
NSData *data = [NSData dataWithContentsOfURL:url];
img = [UIImage imageWithData:data];
if (!img) {
MBPSHOW(@"读取图片失败");
return nil;
}
return img;
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo {
if (error != NULL) {
MBPSHOW(@"图片保存失败");
}else
{
MBPSHOW(@"图片保存成功");
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}
- (CGFloat)vg_statusBarHeight {
if (@available(iOS 13.0, *)) {
NSSet *set = [UIApplication sharedApplication].connectedScenes;
UIWindowScene *windowScene = [set anyObject];
UIStatusBarManager *statusBarManager = windowScene.statusBarManager;
return statusBarManager.statusBarFrame.size.height;
} else {
return [UIApplication sharedApplication].statusBarFrame.size.height;
}
}
@end