| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- //
- // MOWebBaseView.m
- // MiMoLive
- //
- // Created by SuperC on 2025/9/11.
- //
- #import "MOWebBaseView.h"
- #import "POWeakWKWebViewScriptMessageHandler.h"
- #import "MOWebViewController.h"
- #import "MOUploadDeviceTool.h"
- // 用于标记webView序号
- static int webViewTag = 0;
- @interface MOWebBaseView ()<WKNavigationDelegate,WKUIDelegate>
- /** 标记WebView序号 */
- @property (nonatomic, assign) int webViewTag;
- /**记录是否添加了观察者,避免dealloc时释放观察者崩溃*/
- @property (nonatomic, assign) BOOL hasAddedObserver;
- @end
- @implementation MOWebBaseView
- - (instancetype)init {
- if (self = [super init] ) {
- [self setupUI];
- }
- return self;
- }
- - (instancetype)initWithFrame:(CGRect)frame{
- self = [super initWithFrame:frame];
- if (self){
- [self setupUI];
- }
- return self;
- }
- - (void)setupUI{
- [self addSubview:self.poWebView];
- [self.poWebView mas_makeConstraints:^(MASConstraintMaker *make) {
- make.edges.equalTo(self);
- }];
- }
- - (void)toLoadTheUrl{
-
- //FIXME: 默认缓存策略是NSURLRequestUseProtocolCachePolicy
- #if kAPP_Environment == 1
- NSURLRequestCachePolicy policy = NSURLRequestUseProtocolCachePolicy;
- #elif kAPP_Environment == 2
- NSURLRequestCachePolicy policy = NSURLRequestUseProtocolCachePolicy;
- // NSURLRequestCachePolicy policy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
- if (@available(iOS 16.4,*)) {
- [self.poWebView setInspectable:YES];
- }
- #endif
- self.request = [NSURLRequest requestWithURL:self.webUrl cachePolicy:policy timeoutInterval:40];
- MOLogV(@"[WebView] init poWebView(%d) url:%@",self.webViewTag,self.webUrl);
- [self.poWebView loadRequest:self.request];
- }
- #pragma mark ========= JS-->OC ===============
- - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message{
- //#define kWebCallBack_GetUserInfo @"getUserInfo" //传用户信息
- if ([message.name isEqualToString:kWebCallBack_GetUserInfo])
- {
- MOMeDataInfo *userInfoData = (MOMeDataInfo *)[[MODataCache sharedYYCache] objectForKey:kMineUserInfo];
- if(userInfoData){
- // ADJAttribution *adjInfo = [Adjust attribution];
- userInfoData.token = GetToken;
- userInfoData.adid = [MOUploadDeviceTool shareTool].adid;
- NSString *versionString = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
- userInfoData.appVersion = versionString;
- NSDictionary *userDict = [userInfoData dictionaryRepresentation];
- NSString *jsonString = [userDict modelToJSONString];
- NSString *jsString = [NSString stringWithFormat:@"%@(%@)",@"getUserInfoResponse",jsonString];
- [self.poWebView evaluateJavaScript:jsString completionHandler:nil];
- }
- else{
- NSString *jsonString = @"{\"follows\":3,\"vip\":{\"giveGiftBag\":false,\"type\":0,\"expireTime\":0,\"giveGaily\":false},\"profile\":{\"id\":\"65d4ba9f097a721b1ef0a8c5\",\"intro\":\"\",\"medals\":[],\"userNo\":\"43999352\",\"bks\":[],\"agoraId\":43999352,\"adornment\":{\"headdressAnno\":false,\"bubbleCode\":0,\"enterBar\":0},\"avatar\":\"https:\\/\\/mimo-live.s3.ap-southeast-3.amazonaws.com\\/av\\/2024\\/52\\/b78\\/fa5f8c804caae17d1635afa724149118.jpg\",\"birthday\":\"1990-01-01\",\"nickname\":\"SuperY\",\"country\":\"ID\",\"gender\":1},\"mobile\":{},\"family\":{\"memberMax\":0,\"totalPower\":0,\"level\":0,\"memberNum\":0,\"weekPower\":0,\"dailyPower\":0},\"wallet\":{\"diamond\":22,\"consumeDiamond\":0,\"goldenBean\":0},\"fansClub\":{\"show\":false,\"level\":0,\"rank\":0,\"members\":0},\"currExp\":49,\"guild\":{\"anchor\":0},\"level\":3,\"friends\":1,\"fans\":1,\"nextExp\":113,\"liveBadge\":{\"type\":0},\"status\":{\"anchor\":true,\"guild\":true,\"mobile\":false,\"fansClub\":false,\"liveDiscount\":true,\"anchorType\":1,\"joinFansClub\":true}}";
- NSString *jsString = [NSString stringWithFormat:@"%@(%@)",@"getUserInfoResponse",jsonString];
- [self.poWebView evaluateJavaScript:jsString completionHandler:nil];
- }
- }
- //#define kWebCallBack_GetLanguage @"getLanguage" //语言
- else if ([message.name isEqualToString:kWebCallBack_GetLanguage]){
- NSString *currentLanguage = [NSBundle currentLanguage];
- if(currentLanguage.length == 0){
- currentLanguage = @"en-us";
- }
- NSDictionary *userDict = @{@"language":currentLanguage};
- NSString *jsonString = [userDict modelToJSONString];
- NSString *jsString = [NSString stringWithFormat:@"%@(%@)",@"getLanguageResponse",jsonString];
- [self.poWebView evaluateJavaScript:jsString completionHandler:nil];
- }
- //#define kWebCallBack_GetStatusHeight @"getStatusHeight" //状态栏高度
- else if ([message.name isEqualToString:kWebCallBack_GetStatusHeight]){
- CGFloat statusHeght = STATUS_BAR_HEIGHT + 44;
- NSDictionary *userDict = @{@"statusHeight":@(statusHeght)};
- NSString *jsonString = [userDict modelToJSONString];
- NSString *jsString = [NSString stringWithFormat:@"%@(%@)",@"getStatusHeightResponse",jsonString];
- [self.poWebView evaluateJavaScript:jsString completionHandler:nil];
- }
- else if ([message.name isEqualToString:@"destroy"]){
-
- }
- //#define kWebCallBack_Close @"closeActivity" //关闭界面
- else if ([message.name isEqualToString:kWebCallBack_Close]){
-
- }
- //#define kWebCallBack_ExportUrl @"exportUrl" //导出链接
- else if ([message.name isEqualToString:kWebCallBack_ExportUrl]){
- [self toExportUrlWith:message.body];
- return;
- }
- }
- /* 页面开始加载 */
- - (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
- NSString *urlString = webView.URL.absoluteString;
- MOLogV(@"Navigated to URL: %@", urlString);
- }
- - (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(null_unspecified WKNavigation *)navigation{
- NSString *urlString = webView.URL.absoluteString;
- MOLogV(@"Navigated to URL: %@", urlString);
- }
- - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler{
- // 在收到响应开始加载后,决定是否跳转
- NSString *urlString = webView.URL.absoluteString;
- MOLogV(@"Navigated to URL: %@", urlString);
- decisionHandler(WKNavigationResponsePolicyAllow);
- }
- /// 页面加载失败,指初始化第一个页面
- - (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error
- {
- [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(reloadWebViewData) object:nil];
- [self performSelector:@selector(reloadWebViewData) withObject:nil afterDelay:2.0];
- }
- - (void)reloadWebViewData{
- #if kAPP_Environment == 1
- NSURLRequestCachePolicy policy = NSURLRequestUseProtocolCachePolicy;
- #elif kAPP_Environment == 2
- NSURLRequestCachePolicy policy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
- #endif
- self.request = [NSURLRequest requestWithURL:self.webUrl cachePolicy:policy timeoutInterval:40];
- MOLogV(@"[WebView] init poWebView(%d) url:%@",self.webViewTag,self.webUrl);
- [self.poWebView loadRequest:self.request];
- }
- -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
- {
- if ([keyPath isEqualToString:@"title"])
- {
- if (object == self.poWebView)
- {
- }
- else
- {
- [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
- }
- }
- else
- {
- [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
-
- }
- }
- /* 在发送请求之前,决定是否跳转 */
- - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
-
- NSString *urlString = navigationAction.request.URL.absoluteString;
- MOLogV(@"mimo-urlString-%@",urlString);
-
- if([urlString containsString:@"mimo://"]){
-
- NSURL *url = [NSURL URLWithString:urlString];
-
- MOLogV(@"mimo-urlString-%@",urlString);
-
- if ([[UIApplication sharedApplication]respondsToSelector:@selector(openURL:options:completionHandler:)])
- {
- [[UIApplication sharedApplication] openURL:url options:@{UIApplicationOpenURLOptionUniversalLinksOnly:@NO} completionHandler:^(BOOL success) {}];
- }
- else
- {
- [[UIApplication sharedApplication]openURL:webView.URL];
- }
-
- decisionHandler(WKNavigationActionPolicyCancel);
- return;
- }
-
- MOLogV(@"12313");
- decisionHandler(WKNavigationActionPolicyAllow);
- }
- - (void)toExportUrlWith:(NSString *)jsonStr{
- NSDictionary *dict = [self dictionaryWithJsonString:jsonStr];
- NSString *theUrl = [MODataManager objectOrNilForKey:@"url" fromDictionary:dict[@"data"]];
- NSURL *url = [NSURL URLWithString:theUrl];
- if ([[UIApplication sharedApplication] canOpenURL:url]) {
- [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
- }
- }
- - (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){
- MOLogV(@"json解析失败:%@",err);
- return nil;
- }
- return dic;
- }
- #pragma mark - Lazy
- - (WKWebView *)poWebView
- {
- if (!_poWebView)
- {
- WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
- config.selectionGranularity = WKSelectionGranularityDynamic;
- config.allowsInlineMediaPlayback = YES;
- config.mediaTypesRequiringUserActionForPlayback = NO;
- WKPreferences *preferences = [WKPreferences new];
- //是否支持JavaScript
- preferences.javaScriptEnabled = YES;
- //不通过用户交互,是否可以打开窗口
- preferences.javaScriptCanOpenWindowsAutomatically = YES;
- config.preferences = preferences;
- [config.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
- [config setValue:@YES forKey:@"allowUniversalAccessFromFileURLs"];
- //新建一个弱引用代理,防止循环引用
- POWeakWKWebViewScriptMessageHandler *weakHandler = [[POWeakWKWebViewScriptMessageHandler alloc] initWithSriptMessageHandler:self];
-
- config.userContentController = [self userControllerWithMessageHandler:weakHandler];
-
- _poWebView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH, SCREENHEIGHT) configuration:config];
- [_poWebView setBackgroundColor:[UIColor whiteColor]];
- [_poWebView setOpaque:NO];
- WEAKSELF;
- [_poWebView evaluateJavaScript:@"navigator.userAgent" completionHandler:^(id _Nullable result, NSError * _Nullable error)
- {
- NSString *oldUA = result;
- NSString *newUA = [NSString stringWithFormat:@"%@/xiaohui",oldUA];
- weakSelf.poWebView.customUserAgent = newUA;
- }];
-
- _poWebView.navigationDelegate = self;
- _poWebView.UIDelegate = self;
- [_poWebView addObserver:self forKeyPath:@"title" options:NSKeyValueObservingOptionNew context:NULL];
- self.webViewTag = webViewTag;
- webViewTag++;
- self.hasAddedObserver = YES;
- _poWebView.scrollView.bounces = NO;//禁用弹性效果
- }
- return _poWebView;
- }
- - (WKUserContentController *)userControllerWithMessageHandler:(POWeakWKWebViewScriptMessageHandler *)weakHandler{
- WKUserContentController *userController = [[WKUserContentController alloc] init];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_Close];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_GetUserInfo];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_GetStatusHeight];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_GetLanguage];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_GetDiamond];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_ToGetRain];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_ToSubmitShareLink];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_TokenExpired];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_ExportUrl];
-
- //
- [userController addScriptMessageHandler:weakHandler name:@"recharge"];
- [userController addScriptMessageHandler:weakHandler name:@"clickRecharge"];
- [userController addScriptMessageHandler:weakHandler name:@"newTppClose"];
-
- // 2
- [userController addScriptMessageHandler:weakHandler name:@"getConfig"];
- [userController addScriptMessageHandler:weakHandler name:@"destroy"];
- [userController addScriptMessageHandler:weakHandler name:[MOTextAESTools toGetHameRecharge]];
- [userController addScriptMessageHandler:weakHandler name:[MOTextAESTools toGetHameLoaded]];
-
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_ShareToPlatAgency];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_BindAgencySuccess];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_ChagneMysteriousStatus];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_GetBlindBoxScreenParams];
- [userController addScriptMessageHandler:weakHandler name:kWebCallBack_SetBlindBoxResult];
- return userController;
- }
- - (void)removeHandler{
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_Close];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_GetUserInfo];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_GetStatusHeight];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_GetLanguage];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_GetDiamond];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_ToGetRain];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_ToSubmitShareLink];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_TokenExpired];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_ExportUrl];
-
- //
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:@"recharge"];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:@"clickRecharge"];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:@"newTppClose"];
-
- // 2
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:@"getConfig"];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:@"destroy"];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:[MOTextAESTools toGetHameRecharge]];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:[MOTextAESTools toGetHameLoaded]];
-
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_ShareToPlatAgency];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_BindAgencySuccess];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_ChagneMysteriousStatus];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_GetBlindBoxScreenParams];
- [_poWebView.configuration.userContentController removeScriptMessageHandlerForName:kWebCallBack_SetBlindBoxResult];
- }
- - (void)dealloc{
- [self removeHandler];
- }
- @end
|