如何在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 

@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包

如何在iOS应用中更好的调试H5页面_第1张图片

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

如何在iOS应用中更好的调试H5页面_第2张图片

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

如何在iOS应用中更好的调试H5页面_第3张图片

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

如何在iOS应用中更好的调试H5页面_第4张图片

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

如何在iOS应用中更好的调试H5页面_第5张图片

2、实际应用 

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

如何在iOS应用中更好的调试H5页面_第6张图片

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

如何在iOS应用中更好的调试H5页面_第7张图片

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

如何在iOS应用中更好的调试H5页面_第8张图片

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

如何在iOS应用中更好的调试H5页面_第9张图片

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

如何在iOS应用中更好的调试H5页面_第10张图片  

你可能感兴趣的:(Objective-C,JavaScript,safari,ios调试,h5调试,web页面调试)