如何在iOS应用中更好的调试H5页面

前言

在APP中,H5页面可以通过加载vConsole脚本,来查看页面的日志、异常、网络加载、设备信息、储存信息、元素。但是,JS脚本加载于页面Dom挂载之后,这样就会使得这一区间的信息丢失,而且vConsole的Error也会有采集不到的情况。

本篇先简单讲述WKWebView的加载流程,再通过Safari网页检查器,实现H5页面的调试与问题定位。

一、了解web容器的加载流程

1、WKWebView的初始化

WKWebViewConfiguration配置

- (WKWebViewConfiguration *)configuration {
    if (!_configuration) {
        _configuration = [[WKWebViewConfiguration alloc] init];
        _configuration.allowsInlineMediaPlayback = YES;
        
        if (@available(iOS 10.0, *)) {
            if ([_configuration respondsToSelector:@selector(mediaTypesRequiringUserActionForPlayback)]) {
                _configuration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
            }
        } else if(@available(iOS 9.0, *)){
            if([_configuration respondsToSelector:@selector(setRequiresUserActionForMediaPlayback:)]) {
                _configuration.requiresUserActionForMediaPlayback = NO;
            }
        } else if([_configuration respondsToSelector:@selector(setMediaPlaybackRequiresUserAction:)]){
            _configuration.mediaPlaybackRequiresUserAction = NO;
        }
        WKUserContentController* userContentController = [[WKUserContentController alloc] init];
        _configuration.userContentController = userContentController;
 
        NSString *strDocumentCookie = @"document.cookie='uid=;path=/;domain=.baidu.com';document.cookie='sessionId=;path=/;domain=.baidu.com';document.cookie='tokenId=;path=/;domain=.baidu.com';";
        WKUserScript* cookieScript = [[WKUserScript alloc] initWithSource:strDocumentCookie injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
        [userContentController addUserScript:cookieScript];
    }
    return _configuration;
}

WKWebView的初始化

- (WKWebView *)wkWebView {
    if (!_wkWebView){
    _webViewWK = [[WKWebView alloc] initWithFrame:self.frame configuration:self.configuration];
    _wkWebView.scrollView.showsHorizontalScrollIndicator = NO;
    _wkWebView.scrollView.showsVerticalScrollIndicator = NO;
    _wkWebView.scrollView.bounces = NO;
    _wkWebView.navigationDelegate = self;
    _wkWebView.UIDelegate = self;
    _wkWebView.allowsBackForwardNavigationGestures = YES;
    _wkWebView.configuration.allowsInlineMediaPlayback = YES;
    if (@available(iOS 11.0, *)) {
        _wkWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    }
    return _wkWebView;
}

2、H5页面加载

- (void)loadRequest {
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://m.baidu.com"]];
    [request setValue:@"uid=;sessionId=;tokenId=;" forHTTPHeaderField:@"Cookie"];
    [self.wkWebView loadRequest:request];
}

3、WKWebView的页面加载回调

// 开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(null_unspecified WKNavigation *)navigation;

// 资源加载,可以进行拦截处理
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler WK_SWIFT_ASYNC(3);

// 加载响应,可以进行拦截处理
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler WK_SWIFT_ASYNC(3);

// 加载失败
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(NSError *)error;

// 加载完成
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation;

// web进程终止
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView API_AVAILABLE(macos(10.11), ios(9.0));

4、JSBridge交互 

1)H5到iOS的交互

在页面开始加载时,注入JSBridge

[self.configuration.userContentController addScriptMessageHandler:(MKMessageHandler *)scriptMessageHandler name:@"JSBridge"];

MessageHandler的具体实现 

@interface MKMessageHandler : NSObject <WKScriptMessageHandler>

@end


@implementation MKMessageHandler

- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.body isKindOfClass:[NSDictionary class]]) {
        NSDictionary *messageBody = [NSDictionary getDictionary:message.body];
        
        NSString *moduleName = [messageBody stringForKey:@"moduleName"];
        NSString *methodName = [messageBody stringForKey:@"methodName"];
        NSString *parameter = [messageBody stringForKey:@"parameter"];

        [self performMainThread:^ {
            [self invokeAPI:moduleName methodName:methodName parameter:parameter];
        }];
        
    }
}

- (void)invokeAPI:(NSString *)moduleName methodName:(NSString *)methodName parameter:(NSString *)parameter {
    // API映射
}

@end

web端调用JSAPI 

window.webkit.messageHandlers.JSBridge.postMessage({'moduleName': 'page','methodName':'openURL','parameter':JSON.stringify({'url':''})})

2)iOS到H5的交互

web端方法挂载,监听方法回调

// 页面window挂载方法
window.onCallBack = res => { 
    console.log(res)
}

/* 使用function的方式,this会指向window
window.onCallBack = function(res) {
    console.log(res)
}
*/

webView直接运行JS代码调用

[self.wkWebView evaluateJavaScript:@"window.onCallBack('Hello JS!!!')" completionHandler:^(id result, NSError *error) {
    // 调用结果回调
}];

二、使用Safari实现iOS中的H5调试

1、环境准备

1)iOS安装包必须是开发证书打的IPA包

2)打开手机的设置 > Safari > 高级 > 网页检查器

3)打开Mac版Safari偏好设置 > 高级 > 在菜单栏中显示“开发”菜单

4)手机连接Mac电脑 > 打开APP对应的web页 > 打开Mac版Safari的“开发”菜单

5)找到对应的页面 > 点击打开网页检查器

2、实际应用 

1)元素布局:手动修改html以及css属性,点击刷新按钮可以重置页面。通过网页检查器修改元素布局与样式,可以直接应用在APP的web页面。

2)控制台:通过错误日志排查页面异常,使用控制台运行JS代码。错误日志包括js语法错误、脚本资源加载异常、页面Exception。

3)来源:找到需要调试的JS文件,在具体的行打上断点,当页面逻辑调用到指定行代码时,触发断点;在通过变量预览、断点操作、控制台操作来实现基本的联调。

4)网络:查看网络资源的加载情况(资源大小、url、时耗、类型、异常),包括XHR接口的相关信息(请求、响应)。

5)储存空间:LocalStorage、Cookie、SessionStorage,查看页面相关的存储信息。

  

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java开发的安卓应用和Uniapp开发的安卓应用有以下几个主要的区别: 1. 开发语言和框架:Java开发的安卓应用使用Java语言和Android SDK开发,而Uniapp开发的安卓应用使用Vue.js、HTML5、CSS等前端开发语言,并使用Uniapp框架进行跨平台开发。 2. 性能:由于Java开发的安卓应用是原生应用,可以充分利用设备的硬件资源,因此在性能上相对更好。而Uniapp开发的安卓应用使用了一层间件,性能相对较差。 3. 跨平台支持:Uniapp开发的应用可以在多个平台上运行,包括iOS、Android、H5等,而Java开发的安卓应用仅可以在安卓平台上运行。 4. 开发难度和成本:相对而言,Uniapp开发的应用可以更快速地开发和部署,因为Uniapp可以通过一套代码同时生成多个平台的应用。而Java开发的应用需要更多的开发时间和成本,因为需要分别开发iOS和Android两个平台的应用。 5. 功能和定制化:Java开发的应用可以更好地满足特定的需求和定制化需求,因为可以直接使用Android SDK提供的功能。而Uniapp开发的应用虽然提供了一些跨平台的功能,但可能无法满足特定的定制化需求。 ### 回答2: Java开发的安卓应用和Uniapp开发的安卓应用在开发工具、跨平台能力和性能方面有较大的区别。 首先,Java开发的安卓应用主要使用Android Studio这样的专用开发工具,利用Java语言进行编码。相对而言,Uniapp开发的安卓应用则可以使用多种开发工具,例如HBuilderX,同时兼容运行于不同平台的多种开发语言,如Vue.js、JavaScript等。 其次,Uniapp是一个开发一次,多平台运行的前端框架,它可以将开发的应用一键打包成安卓、iOS等多个平台的应用。相比之下,Java开发的安卓应用只能运行于安卓平台。 再者,由于Uniapp是通过WebView来实现跨平台的能力,其性能较Java开发的安卓应用略有差异。尽管Uniapp通过Vue.js等框架进行性能优化,但由于WebView的底层机制限制,性能方面仍然不如原生的Java开发应用。 此外,Java开发的安卓应用在各大应用商店的推广和发布相对较为简单,因为Android平台支持Java应用程序的直接安装和调试。而Uniapp开发的安卓应用需要通过将项目打包成apk文件的方式进行发布和安装,相比之下稍显复杂。 总结来说,Java开发的安卓应用和Uniapp开发的安卓应用在开发工具、跨平台能力和性能方面存在较大差异。开发者可以根据自己的需求和项目特点来选择适合的开发方式。 ### 回答3: Java开发的安卓应用和uniapp开发的安卓应用在技术特点、开发方式和适用场景上有一些区别。 首先,Java开发的安卓应用是使用Android SDK和Java语言进行开发的。开发者需要使用Android Studio等开发工具,编写Java代码,使用Android SDK提供的API进行应用程序的开发。Java开发的安卓应用可以充分利用Android系统的底层资源和功能,具有更高的性能和更好的稳定性。Java开发的应用可以使用广泛的Android框架和库,拥有更大的开发和定制能力。 而uniapp开发的安卓应用是使用HBuilderX开发工具和Vue.js等技术进行开发的。uniapp是一套基于Vue.js的跨平台开发框架,可以同时开发多个平台的应用,包括安卓、iOSWeb。uniapp开发的安卓应用可以通过编写一次代码,同时生成安卓和其他平台的应用。虽然uniapp的性能相对较低,但具有开发快速、跨平台等优势。对于简单的应用程序或者需要快速迭代开发的项目,使用uniapp可以提高开发效率。 总的来说,Java开发的安卓应用适合对性能和稳定性要求较高的应用,可以充分利用Android系统的功能和特性。而uniapp开发的安卓应用适合对开发速度和多平台适配要求较高的应用。开发者需要根据项目需求和考虑因素选择适合的开发方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值