// // XPWebViewController.m // YuMi // // Created by zu on 2021/9/16. // #import "XPWebViewController.h" #import "AccountInfoStorage.h" #import "DJDKMIMOMColor.h" #import "YUMIMacroUitls.h" #import "YYUtility.h" #import "HttpRequestHelper.h" #import "XPShareView.h" #import "TTPopup.h" #import #import #import "XCCurrentVCStackManager.h" #import "XPMineUserInfoViewController.h" #import "ShareHelder.h" #import "Api+Mine.h" #import "YuMi-swift.h" #import "RechargeStorage.h" ///vc #import "MyDressingViewController.h" #import "ShoppingMallViewController.h" #import "XPRoomViewController.h" #import "RoomHostDelegate.h" #import "WalletInfoModel.h" #import "Api+Mine.h" #import "XPSkillCardPlayerManager.h" #import "XPWebViewNavView.h" #import "XPIAPRechargeViewController.h" #import "SessionViewController.h" #import "XPMomentTopicContainerViewController.h" #import "XPIncomeRecordVC.h" #import "PIWebViewSavePhotoView.h" #import "IAPManager.h" typedef NS_ENUM(NSUInteger, RightNavigationPushType){ ///跳转h5页面 RightNavigationPushType_Web = 1, ///分享 RightNavigationPushType_Share = 2, ///跳转原生页面 RightNavigationPushType_AppPage = 3, ///分享图片 RightNavigationPushType_SharePicture = 5 }; @interface WeakWebViewScriptMessageDelegate : NSObject //WKScriptMessageHandler 这个协议类专门用来处理JavaScript调用原生OC的方法 @property (nonatomic, weak) id scriptDelegate; - (instancetype)initWithDelegate:(id)scriptDelegate; @end @implementation WeakWebViewScriptMessageDelegate - (instancetype)initWithDelegate:(id)scriptDelegate { self = [super init]; if (self) { _scriptDelegate = scriptDelegate; } return self; } //遵循WKScriptMessageHandler协议,必须实现如下方法,然后把方法向外传递 //通过接收JS传出消息的name进行捕捉的回调方法 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { if ([self.scriptDelegate respondsToSelector:@selector(userContentController:didReceiveScriptMessage:)]) { [self.scriptDelegate userContentController:userContentController didReceiveScriptMessage:message]; } } @end @interface XPWebViewController () @property (nonatomic,strong) WalletInfoModel *model ; //@property (strong, nonatomic) WKWebView *webview; @property (strong, nonatomic) UIProgressView *progressView; @property (nonatomic, strong) WKUserContentController *pi_userContentController; ///分享的内容 @property (nonatomic,copy) NSDictionary *shareDic; ///分享的内容 @property (nonatomic,copy) NSDictionary *savePhotoDic; /// @property (nonatomic,strong) XPWebViewNavView *navView; /// @property (nonatomic,assign) BOOL isCustom; @property(nonatomic,strong) PIWebViewSavePhotoView *saveView; /// 订单编号 @property (nonatomic,copy) NSString *orderId; @property (nonatomic, assign) BOOL isHideNavBar; @end NSString * const kJSOpenPurse = @"openPurse"; NSString * const kJSOpenChargePage = @"openChargePage"; NSString * const kJSChargePayPage = @"chargePayPage"; NSString * const kJSChargePayClickPage = @"chargePayClickPage"; NSString * const kJSOpenSharePage = @"openSharePage"; NSString * const kJSGetUid = @"getUid"; NSString * const kJSGetDeviceId = @"getDeviceId"; NSString * const kJSGetTicket = @"getTicket"; NSString * const kJSGetDeviceInfo = @"getDeviceInfo"; NSString * const kJSOpenFaceLiveness = @"openFaceLiveness"; NSString * const kJSInitNav = @"initNav"; NSString * const kJSGetRoomUid = @"getRoomUid"; NSString * const kOpenPersonPage = @"openPersonPage"; NSString * const kInitShowNav = @"initShowNav"; NSString * const kCloseWebView = @"closeWebView"; NSString * const kJumpAppointPage = @"jumpAppointPage"; NSString * const kJSOpenRoom = @"openRoom"; NSString * const kJSOpenRoomForGiftId = @"openRoomForGiftId"; NSString * const kJSOpenChatPage = @"geToChatPage"; NSString * const kJSOpenAppConcernedChat = @"openAppConcernedChat"; NSString * const kJSSavePictureShare = @"savePictureShare"; NSString * const kJSGoToExchangeGold = @"goToExchangeGold"; NSString * const kJSOpenPayment = @"openPayment"; NSString * const kJSOpenPaymentCallback = @"openPaymentCallback"; NSString * const kJSVerifyCaptchaCallBack = @"closeToVerify"; NSString * const kJSShowShareCallBack = @"showShareAction"; @implementation XPWebViewController - (instancetype)initWithCustomizeNav:(BOOL)isCustom { self = [super init]; if (self) { self.isCustom = isCustom; } return self; } - (instancetype)initWithRoomUID:(NSString * _Nullable)roomUid { self = [super init]; if (self) { self.roomUid = roomUid; self.isLoginStatus = YES; } return self; } -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:animated]; if([XPSkillCardPlayerManager shareInstance].isInRoom == YES && self.isProperty == NO && [XPSkillCardPlayerManager shareInstance].isInRoomFirstRecharge == NO){ [XPSkillCardPlayerManager shareInstance].isInRoomFirstRecharge = YES; } if (self.isHideNavBar) { if (self.navigationController) { [self.navigationController setNavigationBarHidden:YES]; } } } - (void)viewDidLoad { [super viewDidLoad]; [self.view addSubview:self.saveView]; self.saveView.hidden = YES; [self initView]; } - (void)saveImageToPhotoAlbum:(NSDictionary *)data{ if (data.allKeys.count == 0){ [self showSuccessToast:YMLocalizedString(@"PIWebViewSavePhotoView3")]; return; } NSString *qrCodeUrl = data[@"qrCodeUrl"]; if (qrCodeUrl.length == 0){ [self showSuccessToast:YMLocalizedString(@"PIWebViewSavePhotoView3")]; return; } [self showLoading]; NetImageView *imageView = [NetImageView new]; @kWeakify(self); [imageView loadImageWithUrl:qrCodeUrl completion:^(UIImage * _Nonnull image, NSURL * _Nonnull url) { @kStrongify(self); [self hideHUD]; if (image != nil){ self.saveView.hidden = NO; NSString *text = data[@"text"]; NSString *invitationCode = data[@"invitationCode"]; self.saveView.text = text; self.saveView.image = image; self.saveView.code = invitationCode; UIImage *saveImage = [UIImage getImageFromView:self.saveView]; UIImageWriteToSavedPhotosAlbum(saveImage, self, @selector(image:didFinishSavingWithError:contextInfo:), NULL); return; } [self showSuccessToast:YMLocalizedString(@"PIWebViewSavePhotoView3")]; }]; } //指定回调方法 - (void)image: (UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo{ self.saveView.hidden = YES; NSString *msg = YMLocalizedString(@"PIWebViewSavePhotoView2"); if(error != NULL){ msg = YMLocalizedString(@"PIWebViewSavePhotoView3"); } [self showSuccessToast:msg]; } - (void)initView { if (self.navigationController.viewControllers.count > 1){ UIBarButtonItem *leftBarButtonItem = [[UIBarButtonItem alloc]initWithImage:[[UIImage imageNamed:@"common_nav_back"]ms_SetImageForRTL] style:UIBarButtonItemStylePlain target:self action:@selector(backButtonClick)]; leftBarButtonItem.tintColor = [DJDKMIMOMColor mainTextColor]; self.navigationItem.leftBarButtonItem = leftBarButtonItem; } self.webview.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; if(self.isCustom == YES){ [self.view addSubview:self.navView]; [self.view addSubview:self.webview]; [self.view addSubview:self.progressView]; [self.navView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.top.equalTo(self.view); make.height.mas_equalTo(kNavigationHeight); }]; [self.webview mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.bottom.equalTo(self.view); make.top.equalTo(self.navView.mas_bottom); }]; [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.equalTo(self.view); make.height.mas_equalTo(1); make.top.equalTo(self.navView.mas_bottom); }]; }else{ [self.view addSubview:self.webview]; [self.view addSubview:self.progressView]; [self.webview mas_makeConstraints:^(MASConstraintMaker *make) { make.leading.trailing.top.bottom.mas_equalTo(self.view); }]; } if (self.isLoginStatus) { NSString * uid = [AccountInfoStorage instance].getUid; NSString * ticket = [AccountInfoStorage instance].getTicket; @kWeakify(self); [Api getUserWalletInfo:^(BaseModel * _Nullable data, NSInteger code, NSString * _Nullable msg) { @kStrongify(self); if(code == 200){ WalletInfoModel * model = [WalletInfoModel modelWithDictionary:data.data]; self.model = model; } } uid:uid ticket:ticket]; } } - (void)xPWebViewNavView:(XPWebViewNavView *)view didClickBack:(UIButton *)sender{ if(self.is_Pi_FairyPay){ [self willMoveToParentViewController:nil]; //1 [self.view removeFromSuperview]; //2 [self removeFromParentViewController]; //3 return; } if(self.isFairyPay){ if(self.CloseWebViewBlock){ self.CloseWebViewBlock(YES); } return; } [self dismissViewControllerAnimated:YES completion:nil]; } //加载完成 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { //加载完成后隐藏progressView self.progressView.hidden = YES; if (self.urlLoadCompleted) { self.urlLoadCompleted(YES, nil); } #if DEBUG NSString *fileName = @"vconsole.min.js"; // 你要查找的文件名 NSString *directory = [[NSBundle mainBundle] resourcePath]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSDirectoryEnumerator *enumerator = [fileManager enumeratorAtPath:directory]; NSString *filePath; for (NSString *path in enumerator) { if ([[path lastPathComponent] containsString:fileName]) { filePath = [directory stringByAppendingPathComponent:path]; break; } } if (filePath.length > 0) { NSString *vConsoleScript = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; [webView evaluateJavaScript:vConsoleScript completionHandler:nil]; // 初始化 vConsole NSString *initVConsoleScript = @"var vConsole = new VConsole();"; [webView evaluateJavaScript:initVConsoleScript completionHandler:nil]; } #endif } #if DEBUG - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response; NSDictionary *headers = response.allHeaderFields; // NSLog(@"Response Headers: %@", headers); NSString *contentEncoding = headers[@"Content-Encoding"]; if ([contentEncoding isEqualToString:@"gzip"]) { // NSLog(@"✅ Gzip 响应已启用"); } else { // NSLog(@"❌ Gzip 响应未启用"); } decisionHandler(WKNavigationResponsePolicyAllow); } #endif //加载失败 - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error { //加载失败同样需要隐藏progressView self.progressView.hidden = YES; if (self.urlLoadCompleted) { self.urlLoadCompleted(NO, error); } } //捕抓打电话事件 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { NSURL *URL = navigationAction.request.URL; NSString *scheme = [URL scheme]; NSURLRequest *request = navigationAction.request; // Judge is whether to jump to other app. if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) { BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:request.URL]; if (canOpen) { [[UIApplication sharedApplication] openURL:request.URL options:@{} completionHandler:^(BOOL success) { }]; } decisionHandler(WKNavigationActionPolicyCancel); return; } decisionHandler(WKNavigationActionPolicyAllow); } - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential,card); }); } } - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { [self.webview evaluateJavaScript:@"document.location.href" completionHandler:^(id _Nullable response, NSError * _Nullable error) { NSString *currentUrl = [NSString stringWithFormat:@"%@", response]; ///测试环境只要有host就执行,方便h5连接本地调试 BOOL condition = currentUrl != nil && [currentUrl containsString:API_HOST_URL]; NSLog(@"-- -- - -- - - | -- -- - -- - -%@", response); NSLog(@"-- -- - -- - -%@: %@", message.name, message.body); #ifdef DEBUG condition = currentUrl != nil; #endif if(condition) { if ([message.name isEqualToString:kJSOpenSharePage]) { if (message.body && message.body != [NSNull null]) { NSDictionary *body; //不知道是哪个蓝精灵弄的,变成了个dic,所以我们要判断类型 if ([message.body isKindOfClass:[NSDictionary class]]) { body = message.body; } else if ([message.body isKindOfClass:[NSString class]]) { body = [message.body toJSONObject]; } self.shareDic = body[@"data"]; [self showSharePanel]; } } else if ([message.name isEqualToString:kJSGetUid]) { NSString *uid = [[AccountInfoStorage instance] getUid]; NSString *js = [NSString stringWithFormat:@"getMessage(\"uid\",%@)", uid]; [self.webview evaluateJavaScript:js completionHandler:^(id _Nullable other, NSError * _Nullable error) { // NSLog(@"%@",error); }]; } else if ([message.name isEqualToString:kJSGetTicket]) { NSString *ticket = [[AccountInfoStorage instance] getTicket]; NSString *js = [NSString stringWithFormat:@"getMessage(\"ticket\",\"%@\")",ticket]; [self.webview evaluateJavaScript:js completionHandler:^(id _Nullable other, NSError * _Nullable error) { // NSLog(@"%@",error); }]; } else if ([message.name isEqualToString:kJSGetDeviceId]) { NSString *js = [NSString stringWithFormat:@"getMessage(\"deviceId\",\"%@\")",[YYUtility deviceUniqueIdentification]]; [self.webview evaluateJavaScript:js completionHandler:^(id _Nullable other, NSError * _Nullable error) { // NSLog(@"%@",error); }]; } else if ([message.name isEqualToString:kJSGetDeviceInfo]) { NSDictionary *basicParmars = [HttpRequestHelper configBaseParmars:[[NSDictionary alloc] init]]; NSString *json = [basicParmars mj_JSONString]; NSString *js = [NSString stringWithFormat:@"getMessage(\"deviceInfo\",%@)", json]; [self.webview evaluateJavaScript:js completionHandler:^(id _Nullable ohter, NSError * _Nullable error) { // NSLog(@"%@", error); }]; } else if ([message.name isEqualToString:kJSOpenPurse]) { }else if([message.name isEqualToString:kJSChargePayPage]){ // NSString *money = [NSString stringWithFormat:@"%@",message.body] ; }else if([message.name isEqualToString:kJSChargePayClickPage]){ if(message.body != nil && self.model.diamonds != nil){ // NSString *type = [NSString stringWithFormat:@"%@",message.body]; } }else if ([message.name isEqualToString:kJSOpenChargePage]) { if(self.delegate && [self.delegate respondsToSelector:@selector(payHandler)]){ [self.delegate payHandler]; return; } [TTPopup dismiss]; if(self.isPush){ XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init]; webVC.type = @"4"; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:webVC animated:YES]; return; } UIViewController *controller = [XCCurrentVCStackManager shareManager].getCurrentVC; if (controller.presentingViewController) { [controller dismissViewControllerAnimated:NO completion:nil]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init]; webVC.type = @"4"; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:webVC animated:YES]; }); }else { XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init]; webVC.type = @"4"; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:webVC animated:YES]; } if (self.didTapCharge) { self.didTapCharge(); } } else if ([message.name isEqualToString:kOpenPersonPage]) { NSString *uid = [NSString stringWithFormat:@"%@",message.body]; if (uid.integerValue > 0) { [TTPopup dismiss]; XPMineUserInfoViewController * userInfoVC = [[XPMineUserInfoViewController alloc] init]; userInfoVC.uid = uid.integerValue; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:userInfoVC animated:YES]; } } else if([message.name isEqualToString:kJSInitNav]) { [self initNav:message.body]; } else if([message.name isEqualToString:kJSGetRoomUid]) { NSString *js = [NSString stringWithFormat:@"getMessage(\"roomUid\",\"%@\")",self.roomUid]; [self.webview evaluateJavaScript:js completionHandler:^(id _Nullable other, NSError * _Nullable error) { // NSLog(@"%@",error); }]; } else if([message.name isEqualToString:kInitShowNav]) { if (((NSNumber *)message.body).intValue == 0) { if (self.InitShowNavBlock) { self.InitShowNavBlock(YES); return; } self.isHideNavBar = YES; if (self.navigationController) { [self.navigationController setNavigationBarHidden:YES]; } } } else if([message.name isEqualToString:kCloseWebView]) { if (self.CloseWebViewBlock) { self.CloseWebViewBlock(YES); return; } if (self.navigationController) { [self.navigationController popViewControllerAnimated:YES]; } } else if ([message.name isEqualToString:kJumpAppointPage]) { // h5与原生交互新协议 NSDictionary *bodyDict; if ([message.body isKindOfClass:[NSDictionary class]]) { bodyDict = message.body; } else if ([message.body isKindOfClass:[NSString class]]) { NSString *str = (NSString *)message.body; bodyDict = [str toJSONObject]; } NSInteger skyType = [bodyDict[@"routerType"] integerValue]; [self handleRouterType:skyType message:message]; }else if ([message.name isEqualToString:kJSOpenChatPage]){ NSString *uid = [NSString stringWithFormat:@"%@",message.body]; if (uid.length > 0) { NIMSession * session = [NIMSession session:uid type:NIMSessionTypeP2P]; SessionViewController * sessionVC = [[SessionViewController alloc] initWithSession:session]; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:sessionVC animated:YES]; } }else if([message.name isEqualToString:kJSOpenAppConcernedChat]){ NSString *uid = [NSString stringWithFormat:@"%@",message.body]; if (uid.length > 0) { NIMSession * session = [NIMSession session:uid type:NIMSessionTypeP2P]; SessionViewController * sessionVC = [[SessionViewController alloc] initWithSession:session]; sessionVC.isAttention = YES; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:sessionVC animated:YES]; } }else if ([message.name isEqualToString:kJSOpenRoom]) { NSString *uid = [NSString stringWithFormat:@"%@",message.body]; if (uid.length > 0) { [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[XPRoomViewController class]]) { [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController popToRootViewControllerAnimated:NO]; XPRoomViewController * rooomVC = obj; [rooomVC exitRoom]; *stop = YES; } }]; if(self.view.superview){ [TTPopup dismiss]; } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:uid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } } else if([message.name isEqualToString:kJSOpenRoomForGiftId]) { // NSLog(@"%@", message.body); NSDictionary *bodyDict; if ([message.body isKindOfClass:[NSDictionary class]]) { bodyDict = message.body; } else if ([message.body isKindOfClass:[NSString class]]) { NSString *str = (NSString *)message.body; bodyDict = [str toJSONObject]; } //房间页 传参:uid NSString *uid = [NSString stringWithFormat:@"%@", bodyDict[@"uid"]]; NSString *giftId = [NSString stringWithFormat:@"%@", bodyDict[@"giftId"]]; if (uid.length) { [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController.viewControllers enumerateObjectsUsingBlock:^(__kindof UIViewController * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if ([obj isKindOfClass:[XPRoomViewController class]]) { [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController popToRootViewControllerAnimated:NO]; XPRoomViewController * roomVC = obj; [roomVC exitRoom]; *stop = YES; } }]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [XPRoomViewController openRoom:uid giftId:giftId viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; }); } }else if ([message.name isEqualToString:kJSSavePictureShare]){ NSDictionary *bodyDic; if ([message.body isKindOfClass:[NSDictionary class]]) { bodyDic = message.body; } else if ([message.body isKindOfClass:[NSString class]]) { bodyDic = [message.body toJSONObject]; } NSString *type = [NSString stringWithFormat:@"%@",bodyDic[@"type"]]; if ([type isEqualToString:@"2"]){ [self saveImageToPhotoAlbum:bodyDic]; }else if ([type isEqualToString:@"1"]){ self.savePhotoDic = bodyDic; [self showShareSavePhote]; } } else if([message.name isEqualToString:kJSGoToExchangeGold]){ XPIncomeRecordVC *incomeRecordVC = [XPIncomeRecordVC new]; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:incomeRecordVC animated:YES]; } else if([message.name isEqualToString:kJSOpenPayment]) { [self handleOpenPayment:message.body]; } else if([message.name isEqualToString:kJSVerifyCaptchaCallBack]) { [self handleCaptchaResult:[message.body integerValue] == 1]; } else if([message.name isEqualToString:kJSShowShareCallBack]) { [self handleShareActioin:message.body]; } } }]; } #pragma mark - - (void)handleShareActioin:(NSString *)content { [ShareHelder shareImage:kImage(@"share_icon") url:[NSString isEmpty:content] ? self.url : content fromController:[XCCurrentVCStackManager shareManager].getCurrentVC]; } - (void)handleCaptchaResult:(BOOL)reuslt { if (_verifyCaptcha) { self.verifyCaptcha(reuslt); } } #pragma mark - Payment Method - (void)handleOpenPayment:(NSString *)chargeProdId { if (chargeProdId.length == 0) { [self showErrorToast:@"no charge ID"]; return; } [self showLoading]; @kWeakify(self); [[IAPManager sharedManager] purchase:chargeProdId success:^(NSString *transactionID, NSString *orderID){ @kStrongify(self); [self hideHUD]; [self triggerOpenPaymentCallback:200 orderID:self.orderId productID:transactionID]; } failure:^(NSError * _Nonnull error) { @kStrongify(self); [self hideHUD]; if (error) { [self showErrorToast:error.domain]; } } contactCS:^(NSString * _Nonnull uid) { @kStrongify(self); [self hideHUD]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NIMSession * session = [NIMSession session:uid type:NIMSessionTypeP2P]; SessionViewController * sessionVC = [[SessionViewController alloc] initWithSession:session]; [self.navigationController pushViewController:sessionVC animated:YES]; }); }]; } - (void)triggerOpenPaymentCallback:(NSInteger)code orderID:(NSString *)orderID productID:(NSString *)productID { NSDictionary *dic = @{@"code":@(code), @"orderId":orderID, @"productId":productID}; NSString *js = [NSString stringWithFormat:@"openPaymentCallback(%@)", dic.toJSONString]; @kWeakify(self); [self.webview evaluateJavaScript:js completionHandler:^(id _Nullable result, NSError * _Nullable error) { @kStrongify(self); [self hideHUD]; }]; } #pragma mark - private method - (void)handleRouterType:(NSInteger)skyType message:(WKScriptMessage *)message { NSDictionary *bodyDict = (NSDictionary *)message.body; switch (skyType) { case 1: { //房间页 传参:uid NSString *uid = [NSString stringWithFormat:@"%@", bodyDict[@"routerVal"]]; if (uid.length) { [XPRoomViewController openRoom:uid viewController:[XCCurrentVCStackManager shareManager].getCurrentVC]; } } break; case 7: { //座驾 MyDressingViewController *vc = [[MyDressingViewController alloc] init]; // vc.currentIndex = 1; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:vc animated:YES]; } break; case 8: { //头饰 MyDressingViewController *vc = [[MyDressingViewController alloc] init]; // vc.currentIndex = 0; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:vc animated:YES]; } break; case 75: {//跳转对应的话题 bodyDict = [bodyDict toJSONObject]; NSString *topicId = bodyDict[@"routerVal"]; XPMomentTopicContainerViewController * topicVC = [[XPMomentTopicContainerViewController alloc] init]; topicVC.worldId = topicId; [[XCCurrentVCStackManager shareManager].getCurrentVC.navigationController pushViewController:topicVC animated:YES]; } break; default: break; } } - (void)setUrl:(NSString *)urlString{ _url = urlString; if (_url == nil) { return; } if (![_url hasPrefix:@"http"] && ![_url hasPrefix:@"https"]){ _url = [NSString stringWithFormat:@"%@/%@", [HttpRequestHelper getHostUrl], _url]; } if (![_url containsString:@"?"]) { _url = [NSString stringWithFormat:@"%@", _url]; } else { _url = [NSString stringWithFormat:@"%@", _url]; } // 去掉 urlString 中的空格。 NSString *noSpaceTextUrl = [_url stringByReplacingOccurrencesOfString:@" " withString:@""]; NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:noSpaceTextUrl]]; [self.webview loadRequest:request]; } - (void)backButtonClick { BOOL canGoBack = YES; if (self.webview.backForwardList.backList.count <= 1) { canGoBack = NO; } if ([self.webview canGoBack]) { [self.webview goBack]; } else { [self.navigationController popViewControllerAnimated:YES]; [self.pi_userContentController removeAllUserScripts]; } } #pragma mark - 分享 - (void)initNav:(NSDictionary *)response{ if(!response || ![response isKindOfClass:[NSDictionary class]])return; self.shareDic = response[@"data"]; if ([response[@"type"] intValue]== RightNavigationPushType_Web) { [self addNavigationItemWithTitles:@[response[@"data"][@"title"]] titleColor:[DJDKMIMOMColor alertTitleColor] isLeft:NO target:self action:@selector(gotoWebView) tags:nil]; }else if ([response[@"type"] intValue]== RightNavigationPushType_Share || [response[@"type"] intValue]== RightNavigationPushType_SharePicture){ [self addNavigationItemWithImageNames:@[@"family_person_share"] isLeft:NO target:self action:@selector(showSharePanel) tags:nil]; } } - (void)gotoWebView { if (self.shareDic[@"link"]) { XPWebViewController * webVC = [[XPWebViewController alloc] init]; webVC.url = self.shareDic[@"link"]; [self.navigationController pushViewController:webVC animated:YES]; } } -(void)showShareSavePhote{ if (self.savePhotoDic.allKeys.count <= 0) { return; } NSDictionary * dic = self.savePhotoDic; XPShareInfoModel * shareInfo = [[XPShareInfoModel alloc] init]; shareInfo.shareContent = dic[@"shareText"]; shareInfo.type = ShareType_H5; shareInfo.uid = [AccountInfoStorage instance].getUid; NSString *urlStr = ((NSString *)dic[@"toUrl"]).length > 0 ? dic[@"toUrl"] : @""; NSString *title = ((NSString *)dic[@"shareTitle"]).length > 0 ? dic[@"shareTitle"] : @""; NSString *shareText = ((NSString *)dic[@"shareText"]).length > 0 ? dic[@"shareText"] : @""; NSString *shareImg = ((NSString *)dic[@"shareImg"]).length > 0 ? dic[@"shareImg"] : @""; shareInfo.shareUrl = [NSString stringWithFormat:@"%@&image=%@&title=%@&subTitle=%@",urlStr,shareImg,title,shareText]; XPShareItem *cycle = [XPShareItem itemWitTag:XPShareItemTagFaceBook title:@"FaceBook" imageName:@"share_fb" disableImageName:@"share_fb"]; XPShareItem *wechat = [XPShareItem itemWitTag:XPShareItemTagLine title:@"Line" imageName:@"share_line" disableImageName:@"share_line"]; wechat.isShareInvite = YES; wechat.inviteTitle = title; XPShareItem *qq = [XPShareItem itemWitTag:XPShareItemTagCopyLink title:YMLocalizedString(@"XPWebViewNavView1") imageName:@"share_copy_link" disableImageName:@"share_copy_link"]; XPShareItem *save = [XPShareItem itemWitTag:XPShareItemTagAppSaveAlbum title:YMLocalizedString(@"PIWebViewSavePhotoView4") imageName:@"share_save_icon" disableImageName:@"share_save_icon"]; NSArray * items = @[wechat,cycle, qq,save]; CGFloat margin = 15; CGSize itemSize = CGSizeMake((KScreenWidth-2*margin)/4, 65); XPShareView *shareView = [[XPShareView alloc] initWithItems:items itemSize:itemSize shareInfo:shareInfo]; shareView.delegate = self; [TTPopup popupView:shareView style:TTPopupStyleActionSheet]; } - (void)showSharePanel { if (self.shareDic.allKeys.count <= 0) { return; } NSDictionary * dic = self.shareDic; XPShareInfoModel * shareInfo = [[XPShareInfoModel alloc] init]; shareInfo.shareTitle = self.shareDic[@"title"]; shareInfo.shareContent = dic[@"desc"]; shareInfo.shareImageUrl = dic[@"imgUrl"]; shareInfo.type = ShareType_H5; shareInfo.uid = [AccountInfoStorage instance].getUid; NSString *urlStr = ((NSString *)dic[@"url"]).length > 0 ? dic[@"url"] : dic[@"showUrl"]; if (urlStr.length) { if ([urlStr containsString:@"?"]) { urlStr = [NSString stringWithFormat:@"%@&shareUid=%@",urlStr,[AccountInfoStorage instance].getUid]; } else { urlStr = [NSString stringWithFormat:@"%@?shareUid=%@",urlStr,[AccountInfoStorage instance].getUid]; } } shareInfo.shareUrl = urlStr; XPShareItem *cycle = [XPShareItem itemWitTag:XPShareItemTagFaceBook title:@"FaceBook" imageName:@"share_fb" disableImageName:@"share_fb"]; XPShareItem *wechat = [XPShareItem itemWitTag:XPShareItemTagLine title:@"Line" imageName:@"share_line" disableImageName:@"share_line"]; XPShareItem *qq = [XPShareItem itemWitTag:XPShareItemTagCopyLink title:YMLocalizedString(@"XPWebViewNavView1") imageName:@"share_copy_link" disableImageName:@"share_copy_link"]; XPShareItem *save = [XPShareItem itemWitTag:XPShareItemTagAppSaveAlbum title:YMLocalizedString(@"PIWebViewSavePhotoView4") imageName:@"share_save_icon" disableImageName:@"share_save_icon"]; NSArray * items = @[wechat,cycle, qq,save]; CGFloat margin = 15; CGSize itemSize = CGSizeMake((KScreenWidth-2*margin)/4, 65); XPShareView *shareView = [[XPShareView alloc] initWithItems:items itemSize:itemSize shareInfo:shareInfo]; shareView.delegate = self; [TTPopup popupView:shareView style:TTPopupStyleActionSheet]; } #pragma mark - XCShareViewDelegate - (void)shareView:(XPShareView *)shareView savePhoto:(XPShareInfoModel *)shareInfo{ [self saveImageToPhotoAlbum:self.savePhotoDic]; } - (void)shareViewDidClickCancle:(XPShareView *)shareView { [TTPopup dismiss]; } - (void)shareView:(XPShareView *)shareView didSuccess:(XPShareInfoModel *)shareInfo { [TTPopup dismiss]; NSMutableDictionary *params = [NSMutableDictionary dictionary]; NSString *uid = [AccountInfoStorage instance].getUid; NSString *ticket = [AccountInfoStorage instance].getTicket; [params setObject:uid forKey:@"uid"]; // 添加类型安全检查,防止NSTaggedPointerString错误 if ([shareInfo isKindOfClass:[XPShareInfoModel class]]) { [params setObject:@(shareInfo.shareType) forKey:@"shareType"]; } else { // 如果不是预期类型,提供默认值 [params setObject:@(0) forKey:@"shareType"]; NSLog(@"警告:shareInfo不是XPShareInfoModel类型,而是%@类型", NSStringFromClass([shareInfo class])); } [params setObject:ticket forKey:@"ticket"]; if ([shareInfo isKindOfClass:[XPShareInfoModel class]]) { [params setObject:@(shareInfo.type) forKey:@"sharePageId"]; if (shareInfo.shareUrl.length > 0) { [params setObject:shareInfo.shareUrl forKey:@"shareUrl"]; } if (shareInfo.roomUid > 0) { [params setObject:@(shareInfo.roomUid) forKey:@"targetUid"]; } } [HttpRequestHelper POST:@"usershare/save" params:params success:^(BaseModel * _Nonnull data) { } failure:^(NSInteger resCode, NSString * _Nonnull message) { }]; } - (void)shareView:(XPShareView *)shareView shareFail:(NSString *)message { [TTPopup dismiss]; [self showErrorToast:message]; } - (void)shareViewDidClickCancel:(XPShareView *)shareView { [TTPopup dismiss]; } - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqualToString:@"estimatedProgress"]) { self.progressView.progress = self.webview.estimatedProgress; if (self.progressView.progress == 1) { __weak typeof (self)weakSelf = self; [UIView animateWithDuration:0.25f delay:0.3f options:UIViewAnimationOptionCurveEaseOut animations:^{ weakSelf.progressView.transform = CGAffineTransformMakeScale(1.0f, 1.0f); } completion:^(BOOL finished) { weakSelf.progressView.hidden = YES; }]; } } else if ([keyPath isEqualToString:@"title"]) { if (object == self.webview) { self.navigationItem.title = self.webview.title; if (self.urlLoadCompleted) {//半屏webview如果在加载完成回调后标题还会改变,在此处重新设置一遍 self.urlLoadCompleted(YES, nil); } }else{ [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } else { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; } } - (void)dealloc { [self.webview removeObserver:self forKeyPath:@"estimatedProgress"]; [self.webview removeObserver:self forKeyPath:@"title"]; } - (WKWebView *)webview { if (_webview == nil) { WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init]; if (@available(iOS 10.0, *)) { configuration.mediaTypesRequiringUserActionForPlayback = NO; } else { // Fallback on earlier versions } configuration.allowsInlineMediaPlayback = YES; NSString *uid = [[AccountInfoStorage instance] getUid]; NSString *realCookie = [NSString stringWithFormat:@"%@=%@",@"uid",uid]; WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource: [NSString stringWithFormat:@"document.cookie = '%@';", realCookie] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]; [self.pi_userContentController addUserScript:cookieScript]; ///禁止缩放 NSString *scaleJs = @"$('meta[name=description]').remove(); $('head').append( '' );"; WKUserScript *scaleScript = [[WKUserScript alloc] initWithSource:scaleJs injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:NO]; [self.pi_userContentController addUserScript:scaleScript]; //根据生成的WKUserScript对象,初始化WKWebViewConfiguration configuration.preferences.javaScriptEnabled = YES; configuration.preferences.javaScriptCanOpenWindowsAutomatically = YES; configuration.preferences.minimumFontSize = 10; configuration.selectionGranularity = WKSelectionGranularityCharacter; configuration.userContentController = self.pi_userContentController; CGSize size = [UIScreen mainScreen].bounds.size; _webview = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, size.width,size.height) configuration:configuration]; _webview.navigationDelegate = self; //添加KVO,WKWebView有一个属性estimatedProgress,就是当前网页加载的进度,所以监听这个属性 [_webview addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil]; //添加KVO,监听title属性 [_webview addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL]; UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(backButtonClick)]; [_webview addGestureRecognizer:swipeGesture]; [_webview.scrollView setShowsVerticalScrollIndicator:NO]; [_webview.scrollView setShowsHorizontalScrollIndicator:NO]; //set useragent __weak typeof(self) weakSelf = self; [_webview evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id result, NSError *error) { NSString *userAgent = result; if (![userAgent containsString:@"epartiAppIos erbanAppIos"]){ NSString *newUserAgent = [userAgent stringByAppendingString:@" epartiAppIos erbanAppIos"]; NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:newUserAgent, @"UserAgent", nil]; [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary]; [[NSUserDefaults standardUserDefaults] synchronize]; [weakSelf.webview setCustomUserAgent:newUserAgent]; } }]; _webview.scrollView.bounces = NO; } return _webview; } - (UIProgressView *)progressView{ if (!_progressView) { _progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 1)]; _progressView.progressTintColor = [DJDKMIMOMColor appMainColor]; _progressView.trackTintColor = [UIColor clearColor]; _progressView.transform = CGAffineTransformMakeScale(1.0f, 1.0f); } return _progressView; } - (WKUserContentController *)pi_userContentController{ if (!_pi_userContentController) { //自定义的WKScriptMessageHandler 是为了解决内存不释放的问题 WeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[WeakWebViewScriptMessageDelegate alloc] initWithDelegate:self]; _pi_userContentController = [[WKUserContentController alloc] init]; // 分享面板 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenSharePage]; // 钱包页面 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenPurse]; // 充值页面 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenChargePage]; [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSChargePayPage]; [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSChargePayClickPage]; // 获取uid [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSGetUid]; // 获取设备id [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSGetDeviceId]; // 获取Ticket [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSGetTicket]; // 获取设备info [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSGetDeviceInfo]; // 实人认证: 打开原生人脸认证 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenFaceLiveness]; // 分享按钮 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSInitNav]; // 获取房间uid [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSGetRoomUid]; // 进入个人主页 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kOpenPersonPage]; // 隐藏导航栏 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kInitShowNav]; // 隐藏导航栏 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kCloseWebView]; //装扮及其他活动页面 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJumpAppointPage]; //进入房间 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenRoom]; //进房并弹出礼物面板 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenRoomForGiftId]; ///进入聊天 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenChatPage]; ///进入聊天并关注 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenAppConcernedChat]; ///分享及保存 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSSavePictureShare]; ///兑换金币 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSGoToExchangeGold]; ///周卡内购 [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenPayment]; [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSOpenPaymentCallback]; [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSVerifyCaptchaCallBack]; [_pi_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kJSShowShareCallBack]; } return _pi_userContentController; } -(XPWebViewNavView *)navView{ if (!_navView){ _navView = [[XPWebViewNavView alloc]initWithFrame:CGRectZero]; _navView.delegate = self; } return _navView; } - (PIWebViewSavePhotoView *)saveView{ if(!_saveView){ _saveView = [[PIWebViewSavePhotoView alloc]initWithFrame:CGRectMake(0, 0, KScreenWidth, KScreenHeight)]; } return _saveView; } @end