// // MSRoomGameWebVC.m // YuMi // // Created by duoban on 2024/4/28. // #import "MSRoomGameWebVC.h" #import "LittleGameInfoModel.h" #import "RoomInfoModel.h" #import "XPIAPRechargeViewController.h" @interface MSWeakWebViewScriptMessageDelegate : NSObject //WKScriptMessageHandler 这个协议类专门用来处理JavaScript调用原生OC的方法 @property (nonatomic, weak) id scriptDelegate; - (instancetype)initWithDelegate:(id)scriptDelegate; @end @implementation MSWeakWebViewScriptMessageDelegate - (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 NSString * const kMSGetConfig = @"getConfig"; NSString * const kMSDestroy = @"destroy"; NSString * const kMSGameRecharge = @"gameRecharge"; NSString * const kMSGameLoaded = @"gameLoaded"; @interface MSRoomGameWebVC () @property (strong, nonatomic) WKWebView *webview; @property (strong, nonatomic) UIProgressView *progressView; @property (nonatomic, strong) WKUserContentController *ms_userContentController; @property (nonatomic,weak) id hostDelegate; @property(nonatomic,strong) ActivityInfoModel *gameModel; @property(nonatomic,strong) UIButton *backBtn; @end @implementation MSRoomGameWebVC - (instancetype)initWithDelegate:(id)delegate gameModel:(ActivityInfoModel *)gameModel { self = [super init]; if (self) { self.hostDelegate = delegate; self.gameModel = gameModel; } return self; } - (BOOL)isHiddenNavBar { return YES; } - (void)viewDidLoad { [super viewDidLoad]; [self installUI]; [self setupBackButton]; } - (void)setupBackButton { self.backBtn = [UIButton new]; [self.view addSubview:self.backBtn]; [self.backBtn mas_makeConstraints:^(MASConstraintMaker *make) { make.edges.equalTo(self.view); }]; [self.backBtn addTarget:self action:@selector(backBtnAction) forControlEvents:UIControlEventTouchUpInside]; } -(void)installUI{ self.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.4]; MSWeakWebViewScriptMessageDelegate *weakScriptMessageDelegate = [[MSWeakWebViewScriptMessageDelegate alloc] initWithDelegate:self]; _ms_userContentController = [[WKUserContentController alloc] init]; [_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSGetConfig]; [_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSDestroy]; [_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSGameRecharge]; [_ms_userContentController addScriptMessageHandler:weakScriptMessageDelegate name:kMSGameLoaded]; WKWebViewConfiguration *config = [WKWebViewConfiguration new]; config.allowsInlineMediaPlayback = YES; [config setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"]; //⾳视频的播放不需要⽤⼾⼿势触发, 即为⾃动播放 config.mediaTypesRequiringUserActionForPlayback = NO; config.preferences = [[WKPreferences alloc]init]; WKPreferences *preferences = [WKPreferences new]; preferences.javaScriptCanOpenWindowsAutomatically = YES; config.preferences = preferences; config.preferences.javaScriptEnabled = YES; config.userContentController = _ms_userContentController; //获取当前屏幕的宽⾼ int ScreenHeight = [[UIScreen mainScreen] bounds].size.height; int ScreenWidth = [[UIScreen mainScreen] bounds].size.width; self.webview = [[WKWebView alloc] initWithFrame:CGRectMake(0,0, ScreenWidth, ScreenHeight) configuration:config]; [self.webview.scrollView setBackgroundColor:[UIColor clearColor]]; [self.webview setBackgroundColor:[UIColor clearColor]]; [self.webview setUIDelegate:self]; self.webview.navigationDelegate = self; //设置⽹⻚透明 [self.webview setOpaque:NO]; //设置⽹⻚全屏 if (@available(iOS 11.0, *)) { self.webview.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; } [self.view addSubview:self.webview]; NSString *h5Url = self.gameModel.skipContent; NSURL *url = [NSURL URLWithString:h5Url]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; [self.webview loadRequest:request]; } - (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler{ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { dispatch_async(dispatch_get_main_queue(), ^{ NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust]; completionHandler(NSURLSessionAuthChallengeUseCredential,card); }); } } // 调⽤JS - (void)callJs:(NSString*)method withJavaScriptValue:(nullable id)arguments { if (arguments) { NSData *data = [NSJSONSerialization dataWithJSONObject:arguments options:(NSJSONWritingPrettyPrinted) error:nil]; NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSString *jsMethods = [NSString stringWithFormat:@"%@(%@)", method, jsonStr]; [self.webview evaluateJavaScript:jsMethods completionHandler:^(id _Nullable resp, NSError * _Nullable error) { NSLog(@"error = %@ , response = %@",error, resp); [self.backBtn removeFromSuperview]; }]; } else { NSString *jsMethods = [NSString stringWithFormat:@"%@({})", method]; [self.webview evaluateJavaScript:jsMethods completionHandler:^(id _Nullable resp, NSError * _Nullable error) { NSLog(@"error = %@ , response = %@",error, resp); [self.backBtn removeFromSuperview]; }]; } } - (NSDictionary *)dictionaryWithJsonString:(NSString *)jsonString { if (jsonString == nil && jsonString.length == 0) { return nil; } NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSError *err; NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err]; if(err) { NSLog(@"json解析失败:%@",err); return nil; } return dic; } // 绑定协议⽅法 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message { NSString* method = [NSString stringWithFormat:@"%@:", message.name]; NSDictionary *dicBody = [self dictionaryWithJsonString:message.body]; if ([message.name isEqualToString:kMSGetConfig]) { [self getConfig:dicBody]; } else if ([message.name isEqualToString:kMSDestroy]) { [self destroy:dicBody]; } else if ([message.name isEqualToString:kMSGameLoaded]) { [self gameLoaded:dicBody]; } else if ([message.name isEqualToString:kMSGameRecharge]) { [self gameRecharge:dicBody]; } else { NSLog(@"未实现⽅法 : %@ --> %@", message.name, message.body); } } // 获取信息配置 - (void) getConfig:(NSDictionary*)args { NSLog(@"BSGAME %s","游戏调⽤getConfig"); NSString* method = [args objectForKey:@"jsCallback"]; RoomInfoModel *roomInfo = self.hostDelegate.getRoomInfo; ActivityInfoItemModel *gameModel = self.gameModel.gameModel; NSString *appChannel = gameModel.appChannel ?: @""; int64_t appId = gameModel.appId; NSString *userId = [AccountInfoStorage instance].getUid; NSString *code = gameModel.code ?: @""; NSString *roomId = [NSString stringWithFormat:@"%ld",roomInfo.uid]; NSString *gameMode = gameModel.gameMode ?: @""; NSDictionary *gameConfig = gameModel.gameConfig ?: @{}; int gsp = gameModel.gsp; // 数据只是参考值,需要根据⾃⼰APP进⾏赋值 NSObject* configData = @{ @"appChannel":appChannel, @"appId":@(appId), @"userId":userId, @"code":code, @"roomId":roomId, @"gameMode":gameMode, @"language":[self getlanguage], @"gameConfig":gameConfig, @"gsp":@(gsp), }; [self callJs:method withJavaScriptValue:configData]; } -(NSString *)getlanguage{ NSString *language = [NSBundle getLanguageText]; if ([language hasPrefix:@"zh"]) { if ([language rangeOfString:@"Hans"].location != NSNotFound) { language = @"0"; // 简体中文 } else { language = @"1"; // 繁體中文 } }else if([language hasPrefix:@"ar"]){///阿拉伯语 language = @"7"; }else{///英文 language = @"2"; } return language; } // 销毁游戏 - (void) destroy:(NSDictionary*)args { NSLog(@"BSGAME %s","游戏调⽤destroy"); //关闭游戏 TODO 客⼾端 [self willMoveToParentViewController:nil]; //1 [self.view removeFromSuperview]; //2 [self removeFromParentViewController]; //3 } -(void)backBtnAction{ TTAlertConfig *config = [[TTAlertConfig alloc]init]; config.message = YMLocalizedString(@"MSRoomGameWebVC0"); config.actionStyle = TTAlertActionBothStyle; [TTPopup alertWithConfig:config showBorder:NO confirmHandler:^{ [self willMoveToParentViewController:nil]; //1 [self.view removeFromSuperview]; //2 [self removeFromParentViewController]; //3 } cancelHandler:^{ }]; } // 提⽰余额不⾜ - (void) gameRecharge:(NSDictionary*)args { NSLog(@"BSGAME %s","游戏调⽤gameRecharge"); //拉起充值商城 TODO 客⼾端 TTAlertConfig *config = [[TTAlertConfig alloc]init]; config.message = YMLocalizedString(@"XPNobleCenterViewController3"); config.actionStyle = TTAlertActionBothStyle; [TTPopup alertWithConfig:config showBorder:NO confirmHandler:^{ XPIAPRechargeViewController * webVC =[[XPIAPRechargeViewController alloc] init]; webVC.type = @"4"; [self.navigationController pushViewController:webVC animated:YES]; } cancelHandler:^{ }]; } // 游戏加载完毕 - (void) gameLoaded:(NSDictionary*)args { // 游戏加载完毕 TODO 客⼾端 [self.backBtn removeFromSuperview]; } @end