WKWebView
//
// WebViewController.m
// XiaoYan
//
// Created by liyu on 16/7/31.
// Copyright © 2016年 Baienda Technology. All rights reserved.
//
#import "WebViewController.h"
#import "UserInfoViewController.h"
#import "CDCacheManager.h"
#import "XiaoYuanNetworkService.h"
#import <WebKit/WebKit.h>
#import "ConfirmPaymentViewController.h"
#import "CourseOrderDetailViewController.h"
#import "OrderDetailViewController.h"
@interface WebViewController () <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler>
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) UIProgressView *progressView;
@property (nonatomic, assign) BOOL previousNavigationControllerNavigationBarHidden;
@property (nonatomic, strong) UIBarButtonItem *closeItem;
@property (nonatomic, strong) UIBarButtonItem *backItem;
@end
@implementation WebViewController
- (UIBarButtonItem *)closeItem {
if (!_closeItem) {
_closeItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop
target:self
action:@selector(close:)];
}
return _closeItem;
}
- (UIBarButtonItem *)backItem {
if (!_backItem) {
_backItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"BrowserNavBack"]
style:UIBarButtonItemStylePlain
target:self
action:@selector(goBack:)];
}
return _backItem;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
self.previousNavigationControllerNavigationBarHidden = self.navigationController.navigationBarHidden;
[self setupViews];
[_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:NULL];
[_webView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)setupViews {
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.preferences = [[WKPreferences alloc] init];
// config.preferences.minimumFontSize = 40;
config.preferences.javaScriptEnabled = YES;
config.preferences.javaScriptCanOpenWindowsAutomatically = YES;
config.userContentController = [[WKUserContentController alloc] init];
// config.allowsInlineMediaPlayback = YES;
// config.requiresUserActionForMediaPlayback = YES;
// config.mediaPlaybackRequiresUserAction = YES;
[config.userContentController addScriptMessageHandler:self name:@"UserProfile"];
[config.userContentController addScriptMessageHandler:self name:@"OrderDetail"];
_webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];
_webView.multipleTouchEnabled = YES;
_webView.allowsBackForwardNavigationGestures = !self.backForwardNavigationGesturesDisabled;
_webView.navigationDelegate = self;
_webView.UIDelegate = self;
[self.view addSubview:_webView];
_progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
_progressView.trackTintColor = [UIColor clearColor];
_progressView.progressTintColor = [UIColor colorWithRGB:0x1ecab7];
_progressView.hidden = _progressBarHidden;
[self.view addSubview:_progressView];
[_webView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.bottom.right.equalTo(self.view);
}];
[_progressView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.right.equalTo(self.view);
make.height.mas_equalTo(@2);
}];
if (self.closeButtonHidden) {
self.navigationItem.leftBarButtonItem = self.backItem;
} else {
self.navigationItem.leftBarButtonItems = @[self.backItem, self.closeItem];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(exitFullScreen) name:UIWindowDidBecomeHiddenNotification object:nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)dealloc {
[self.webView removeObserver:self forKeyPath:@"estimatedProgress"];
[self.webView removeObserver:self forKeyPath:@"title"];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidBecomeVisibleNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIWindowDidBecomeHiddenNotification object:nil];
}
- (void)exitFullScreen {
[UIApplication sharedApplication].statusBarHidden = NO;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
if (self.navigationControllerInteractivePopGestureRecognizerDisabled) {
// 禁止返回手势
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:self.previousNavigationControllerNavigationBarHidden animated:YES];
if (self.navigationControllerInteractivePopGestureRecognizerDisabled) {
// 恢复返回手势
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
}
- (void)loadRequest:(NSURLRequest *)request {
[self loadViewIfNeeded];
[self.webView loadRequest:request];
}
- (void)loadURL:(NSURL *)URL {
[self loadRequest:[NSURLRequest requestWithURL:URL]];
}
- (void)loadURLString:(NSString *)URLString {
NSURL *URL = [NSURL URLWithString:URLString];
[self loadURL:URL];
}
- (void)goBack:(id)sender {
if (!self.backForwardNavigationGesturesDisabled && [self.webView canGoBack]) {
[self.webView goBack];
} else {
[self removeScriptMessageHandler];
[self.navigationController popViewControllerAnimated:YES];
}
}
- (void)close:(id)sender {
[self removeScriptMessageHandler];
[self.navigationController popViewControllerAnimated:YES];
}
- (void)removeScriptMessageHandler {
WKUserContentController *controller = self.webView.configuration.userContentController;
[controller removeScriptMessageHandlerForName:@"UserProfile"];
[controller removeScriptMessageHandlerForName:@"OrderDetail"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"estimatedProgress"] && object == self.webView) {
self.progressView.alpha = 1.0f;
BOOL animated = self.webView.estimatedProgress > self.progressView.progress;
[self.progressView setProgress:self.webView.estimatedProgress animated:animated];
if (self.webView.estimatedProgress >= 1.0f) {
[UIView animateWithDuration:0.3f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{
self.progressView.alpha = 0.0f;
} completion:^(BOOL finished) {
[self.progressView setProgress:0.0f animated:NO];
}];
}
} else if ([keyPath isEqualToString:@"title"] && object == self.webView) {
self.title = self.webView.title;
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
[self handleError:error];
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSURL *URL = navigationAction.request.URL;
if (![self externalAppRequiredToOpenURL:URL]) {
if (!navigationAction.targetFrame) {
[self loadURL:URL];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
} else if ([[UIApplication sharedApplication] canOpenURL:URL]) {
[[UIApplication sharedApplication] openURL:URL];
decisionHandler(WKNavigationActionPolicyCancel);
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
- (BOOL)externalAppRequiredToOpenURL:(NSURL *)URL {
NSSet *validSchemes = [NSSet setWithArray:@[@"http", @"https"]];
return ![validSchemes containsObject:URL.scheme];
}
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
if ([self.webView.URL.absoluteString hasPrefix:XIAOYUAN_HOST]) {
if ([message.name isEqualToString:@"UserProfile"]) {
NSString *userId = message.body;
AVUser *user = [[CDCacheManager manager] lookupUser:userId];
if (user) {
[self.navigationController pushViewController:[[UserInfoViewController alloc] initWithUser:user] animated:YES];
} else {
user = [AVUser objectWithObjectId:userId];
[user fetchInBackgroundWithBlock:^(AVObject *object, NSError *error) {
if (!error) {
[[CDCacheManager manager] registerUser:user];
[self.navigationController pushViewController:[[UserInfoViewController alloc] initWithUser:user] animated:YES];
}
}];
}
} else if ([message.name isEqualToString:@"OrderDetail"]) {
NSString *orderId = message.body;
MBProgressHUD *hud = [MBProgressHelper showProgressAddedTo:self.navigationController.view];
[[XiaoYuanNetworkService manager] getOrderWithOrderId:orderId block:^(XYOrder *order, NSError *error) {
if (!error) {
if ([order.status isEqualToNumber:@0]) {
[MBProgressHelper hideProgress:hud];
ConfirmPaymentViewController *confirmPaymentVC = [[ConfirmPaymentViewController alloc]init];
confirmPaymentVC.order = order;
confirmPaymentVC.pushFromWallet = YES;
[self.navigationController pushViewController:confirmPaymentVC animated:YES];
} else if ([order.status isEqualToNumber:@1]){
if ([order.orderType isEqualToString:@"course"]) {
[MBProgressHelper hideProgress:hud];
CourseOrderDetailViewController *courseOrderDetailVC = [[CourseOrderDetailViewController alloc]init];
courseOrderDetailVC.courseOrder = order;
courseOrderDetailVC.pushFromWallet = YES;
[self.navigationController pushViewController:courseOrderDetailVC animated:YES];
} else if ([order.orderType isEqualToString:@"product"]){
[MBProgressHelper hideProgress:hud];
OrderDetailViewController *orderDetailVC = [[OrderDetailViewController alloc]init];
orderDetailVC.productOrder = order;
orderDetailVC.pushFromWallet = YES;
[self.navigationController pushViewController:orderDetailVC animated:YES];
}
} else if ([order.status isEqualToNumber:@4]){
[MBProgressHelper hideProgress:hud];
[MBProgressHelper showTextAddedTo:self.view labelText:@"订单已过期"];
}
}
}];
}
}
}
@end