Files

502 lines
18 KiB
Mathematica
Raw Permalink Normal View History

2025-08-11 10:43:19 +08:00
//
// BJWebVC.m
// buymore
//
// Created by yuebin on 2020/12/28.
// Copyright © 2020 JLC. All rights reserved.
//
#import "BJWebVC.h"
#import <WebKit/WebKit.h>
//#import <JavaScriptCore/JavaScriptCore.h>
//#import "WKWebViewJavascriptBridge.h"
//#import <Contacts/Contacts.h>
//#import <ContactsUI/ContactsUI.h>
@interface BJWebVC () <WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate>
@property (strong, nonatomic) WKWebView *webView;
@property (nonatomic, strong) UIView *progressView;
@property (nonatomic,strong) UIActivityIndicatorView *indicatorView;
@property (nonatomic, assign) BOOL havePushLogin;
@property (nonatomic, assign) BOOL canAddJs;
//@property (strong, nonatomic) WKWebViewJavascriptBridge *webViewBridge;
@property (copy, nonatomic) NSString *fixWebUrl; //
@property (strong, nonatomic) NSDictionary *jsPassDict; //使js
@end
@implementation BJWebVC
#pragma mark - view
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationController.navigationBar.hidden = YES;
BlackContentStatusBar
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// self.isUseWebPageTitle = YES;
[self addJsMethod];
[self addObserver];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self removeJsMethod];
[self removeObserve];
}
- (void)viewDidLoad {
[super viewDidLoad];
_canAddJs = YES;
[self initNavBar];
[self initSpecialNavBtn];
[self initWebView];
[self addProgressView];
[self loadRequest];
[self registerNativeFunctions];
// [self performSelector:@selector(callJsAfterUUpay) afterDelay:6];
}
- (void)initNavBar {
self.view.backgroundColor = UIColor.whiteColor;
__weak typeof(self) weakSelf = self;
self.bm_navView = [[CustomNavigationView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, yb_NavigationBar_H)];
[self.bm_navView cus_setNavShow:0];
[self.bm_navView cus_setNavTitle:C_string(_webName)];
UIButton *closeBtn = self.bm_navView.left1Btn;
[closeBtn setTitle:@"" forState:UIControlStateNormal];
[closeBtn setImage:ImageNamed(@"BM_host_nav_btn_close") forState:UIControlStateNormal];
self.bm_navView.handleGuanBiBlock = ^{
[weakSelf closeWeb:nil];
};
self.bm_navView.handleBackBlock = ^{
[weakSelf backWeb:nil];
};
self.bm_navView.hidden = _useH5NavBar>0;
}
// 使
- (void)initSpecialNavBtn {
if (_useH5NavBar != 0) {
return;
}
__weak typeof(self) weakSelf = self;
if ([_webUrl containsString:@"/help_center"] || [_webUrl containsString:@"index/task/task_bank"]) {
//
UIButton *shareBtn = self.bm_navView.right0Btn;
shareBtn.hidden = NO;
[shareBtn setTitle:@"" forState:UIControlStateNormal];
[shareBtn setImage:ImageNamed(@"BM_Tools_nav_btn_share") forState:UIControlStateNormal];
self.bm_navView.handleRight0Block = ^{
[weakSelf shareBtnClick];
};
}
}
- (void)initWebView {
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = [[WKUserContentController alloc] init];
configuration.preferences = [[WKPreferences alloc] init];
configuration.preferences.minimumFontSize = 10;
configuration.preferences.javaScriptEnabled = YES;
configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES;
configuration.allowsInlineMediaPlayback = YES; //线
configuration.selectionGranularity = YES; //
configuration.suppressesIncrementalRendering = YES; //
// if (GVUSER.isLogin) {
// WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:[NSString stringWithFormat:@"document.cookie=\'%@=%@;domain=%@\';",@"uid", GVUSER.uid,@"http://www.eqidian.net"] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
// [configuration.userContentController addUserScript:cookieScript];
//
// WKUserScript *cookieScript1 = [[WKUserScript alloc] initWithSource:[NSString stringWithFormat:@"document.cookie=\'%@=%@;domain=%@\';",@"sign", GVUSER.sign,@"http://www.eqidian.net"] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
// [configuration.userContentController addUserScript:cookieScript1];
// }
CGRect rect = CGRectMake(15, yb_NavigationBar_H, APPW-15*2, APPH-yb_NavigationBar_H); //
if (_useH5NavBar == 1) {
rect = CGRectMake(15, yb_StatusBar_H, APPW-15*2, APPH-yb_StatusBar_H);
}else if (_useH5NavBar == 2) {
rect = CGRectMake(15, 0, APPW-15*2, APPH);
}
_webView = [[WKWebView alloc] initWithFrame:rect configuration:configuration];
_webView.navigationDelegate = self;
_webView.UIDelegate = self;
[self.view addSubview:_webView];
//
if (@available(iOS 11.0, *)) {
self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
_webView.allowsBackForwardNavigationGestures = YES;
_webView.opaque = NO;
}
- (void)addProgressView {
//progress
_progressView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1, 1)];
_progressView.backgroundColor = mainDeepColor;
[_webView addSubview:self.progressView];
//fenghuolun
_indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[self.view addSubview:self.indicatorView];
self.indicatorView.center = self.view.center;
}
- (void)loadRequest {
if (_webUrl.length == 0) {
return;
}
//
if ([_webUrl containsString:@"?"]) {
_fixWebUrl = [_webUrl stringByAppendingString:@"&iosShow=2&platform=2"];
}else {
_fixWebUrl = [_webUrl stringByAppendingString:@"?iosShow=2&platform=2"];
}
//user_id
// if (UserID.length>0 && ![_fixWebUrl containsString:@"user_id"]) {
// _fixWebUrl = [_fixWebUrl stringByAppendingFormat:@"&user_id=%@", UserID];
// }
if ([_fixWebUrl containsString:@"??"]) {
_fixWebUrl = [_fixWebUrl stringByReplacingOccurrencesOfString:@"??" withString:@"?"]; //
}
//url
_fixWebUrl = [_fixWebUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//使
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:_fixWebUrl] cachePolicy:NSURLRequestReloadRevalidatingCacheData timeoutInterval:1];
[request addValue:@"ios" forHTTPHeaderField:@"app-type"];
[request addValue:@"2" forHTTPHeaderField:@"platform"];
if (_httpHeadDict.allKeys.count > 0) {
for (NSString *key in _httpHeadDict.allKeys) {
[request addValue:_httpHeadDict[key] forHTTPHeaderField:key];
}
}
[_webView loadRequest:request];
}
#pragma mark - WKNavigationDelegate
//
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[self.indicatorView startAnimating];
_progressView.hidden = NO;
_progressView.width = 1;
}
//
- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
[self.indicatorView startAnimating];
}
//
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
_progressView.hidden = YES;
//JS
//
[webView evaluateJavaScript:@"document.documentElement.style.webkitTouchCallout='none';" completionHandler:^(id _Nullable result, NSError * _Nullable error) {}];
//
[webView evaluateJavaScript:@"document.documentElement.style.webkitUserSelect='none';" completionHandler:^(id _Nullable result, NSError * _Nullable error) {}];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self.indicatorView stopAnimating];
if (!_useH5NavBar) {
NSUInteger pageCount = self.webView.backForwardList.backList.count;
self.bm_navView.left1Btn.hidden = pageCount==0;
}
//使 使h5
if (!_useH5NavBar && (!_useSelfTitle)) {
if (webView.title.length > 0) {
self.bm_navView.titleLab.text = webView.title;
}
}
}
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
NSLog(@"%@====URL",navigationResponse.response.URL);
decisionHandler(WKNavigationResponsePolicyAllow);
}
/**
API
*/
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
CFDataRef exceptions = SecTrustCopyExceptions(serverTrust);
SecTrustSetExceptions(serverTrust, exceptions);
CFRelease(exceptions);
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]);
}
//
- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self.indicatorView stopAnimating];
}
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self.indicatorView stopAnimating];
//
if ([_webUrl containsString:@"yangkeduo"]) {
NSLog(@"是拼多多网址报错,不显示框");
return;
}
if (_useH5NavBar == 0) {
//
[SVProgressHUD showInfoWithStatus:@"网络错误"];
}else {
//
}
}
#pragma mark - js
- (void)registerNativeFunctions {
/*
__weak typeof(self) weakSelf = self;
_webViewBridge = [WKWebViewJavascriptBridge bridgeForWebView:_webView];
[_webViewBridge setWebViewDelegate:self];
[_webViewBridge registerHandler:@"jsGetNativeData" handler:^(id data, WVJBResponseCallback responseCallback) {
NSDictionary *passDict;
if ([data isKindOfClass:NSString.class]) {
passDict = ((NSString *)data).mj_JSONObject;
}
if ([data isKindOfClass:NSDictionary.class]) {
passDict = data;
}
if (passDict) {
BaseJumpModel *model = [[BaseJumpModel alloc] init];
model.md_event_type = [passDict safeStringForKey:@"md_event_type"];
model.md_event_content = [passDict valueForKey:@"md_event_content"];
model.md_event_need_login = [passDict safeBoolForKey:@"md_event_need_login"];
[model doModelEvent];
id result = model.jsNeedThing.mj_JSONString;
if (result) {
NSLog(@"返回给js的值 %@", result);
#if DEBUG
// dispatch_async(dispatch_get_main_queue(), ^{
// [QMUITips showInfo:[NSString stringWithFormat:@"返回给js的值 %@", result]];
// });
#endif
responseCallback(result);
}
}
}];
*/
}
#pragma mark - WKScriptMessageHandler js
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
NSLog(@"JS 调用了 %@ 方法",message.name);
NSString *jsonString = message.body;
NSString *methodName = message.name;
if ([methodName isEqualToString:@"jsCallNative"]) {
NSDictionary *info;
if ([jsonString isKindOfClass:NSString.class]) {
info = jsonString.mj_JSONObject;
}
if ([jsonString isKindOfClass:NSDictionary.class]) {
info = (NSDictionary *)jsonString; //H5
}
if ([info isKindOfClass:NSDictionary.class]) {
// BaseJumpModel *model = [[BaseJumpModel alloc] init];
// model.md_event_type = [info safeStringForKey:@"md_event_type"];
// model.md_event_content = [info valueForKey:@"md_event_content"];
// model.md_event_need_login = [info safeBoolForKey:@"md_event_need_login"];
// [model doModelEvent];
// if (model.md_event_type.integerValue != 1017) {
// NSLog(@"JS 调用了 %@ 方法,传回参数 %@",message.name,message.body);
// }
}
return;
}
NSLog(@"JS 调用了 %@ 方法,传回参数 %@",message.name,message.body);
}
#pragma mark - WKUIDelegate
- (void)webView:(WKWebView *)webView runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(void))completionHandler{
NSLog(@"message - %@",message);
completionHandler();
}
//JS
- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * __nullable result))completionHandler{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:prompt message:defaultText preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *a1 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
//
completionHandler(@"");
}];
UIAlertAction *a2 = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSLog(@"%@", [alert.textFields firstObject].text);
completionHandler([alert.textFields firstObject].text);
}];
[alert addAction:a1];
[alert addAction:a2];
[alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
NSLog(@"%@",textField.text);
}];
[self presentViewController:alert animated:YES completion:nil];
}
//JS
- (void)webView:(WKWebView *)webView runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(BOOL result))completionHandler{
// [AlertShowTool showAlertWithTitle:message message:nil sureBlock:^{
// completionHandler(YES);
// } cancleBlock:^{
// completionHandler(NO);
// } fromViewController:self];
}
#pragma mark - btn action
- (void)backWeb:(id)sender {
NSInteger pageCount = self.webView.backForwardList.backList.count;
if (pageCount > 0) {
[self.webView goBack];
}else {
[self.navigationController popViewControllerAnimated:YES];
}
}
- (void)closeWeb:(id)sender {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)shareBtnClick {
}
- (void)reloadWebAfterLogin {
//
[self loadRequest];
}
#pragma mark - js
- (void)callJsAfterUUpay {
NSDictionary *para = @{@"md_event_type":@"1400", @"md_event_content":@{}};
NSString *jsString = [NSString stringWithFormat:@"nativeCallJs('%@')", para.mj_JSONString];
// NSString *jsString = @"nativeCallJs(1400)";
[_webView evaluateJavaScript:jsString completionHandler:^(id _Nullable result, NSError * _Nullable error) {
}];
}
- (void)callJsAfterGetPhone:(NSString *)phone withName:(NSString *)name {
NSDictionary *para = @{@"md_event_type":@"1202", @"md_event_content":@{@"phone":C_string(phone), @"name":C_string(name)}};
NSString *jsString = [NSString stringWithFormat:@"nativeCallJs('%@')", para.mj_JSONString];
// NSString *jsString = @"nativeCallJs(1400)";
[_webView evaluateJavaScript:jsString completionHandler:^(id _Nullable result, NSError * _Nullable error) {
}];
}
- (void)callJsAfterVideoShow {
NSDictionary *para = @{@"md_event_type":@"1205", @"md_event_content":@{}};
NSString *jsString = [NSString stringWithFormat:@"nativeCallJs('%@')", para.mj_JSONString];
[_webView evaluateJavaScript:jsString completionHandler:^(id _Nullable result, NSError * _Nullable error) {
}];
}
#pragma mark - KVO
- (void)addJsMethod {
if (_canAddJs) { //
[_webView.configuration.userContentController addScriptMessageHandler:self name:@"jsCallNative"];
_canAddJs = NO;
}
}
- (void)removeJsMethod {
//,
if (_canAddJs == NO) {
[_webView.configuration.userContentController removeScriptMessageHandlerForName:@"jsCallNative"];
_canAddJs = YES;
}
}
- (void)addObserver {
[_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)removeObserve {
@try {
[_webView removeObserver:self forKeyPath:@"estimatedProgress"];
} @catch (NSException *exception) {
NSLog(@"移除观察者出错");
} @finally {
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
if ([keyPath isEqualToString:@"estimatedProgress"]) {
[UIView animateWithDuration:0.1 animations:^{
_progressView.width = self.webView.estimatedProgress * APPW;
}];
_progressView.hidden = _webView.estimatedProgress >= 0.97;
}else{
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
- (void)dealloc {
NSLog(@"%@", [NSString stringWithFormat:@"销毁%@页面", NSStringFromClass(self.class)]);
[NSNotificationCenter.defaultCenter removeObserver:self];
}
@end