How to better debug H5 pages in iOS applications

foreword

In the APP, the H5 page can view the log, exception, network loading, device information, storage information, and elements of the page by loading the vConsole script. However, the JS script is loaded after the page Dom is mounted, which will cause the information in this area to be lost, and the Error of vConsole may not be collected.

This article first briefly describes the loading process of WKWebView, and then uses the Safari web page inspector to realize the debugging and problem location of the H5 page.

1. Understand the loading process of the web container

1. Initialization of WKWebView

WKWebViewConfiguration configuration

- (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;
}

Initialization of 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 page loading

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

3. The page loading callback of 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 interaction 

1) Interaction from H5 to iOS

When the page starts loading, inject JSBridge

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

Concrete implementation of 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

Calling JSAPI from the web 

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

2) Interaction from iOS to H5

Web-side method mount, monitor method callback

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

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

webView directly runs JS code calls

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

2. Use Safari to implement H5 debugging in iOS

1. Environment preparation

1) The iOS installation package must be an IPA package with a development certificate

2) Open your phone's Settings > Safari > Advanced > Web Inspector

3) Open Safari for Mac Preferences > Advanced > Show Develop menu in menu bar

4) Connect the mobile phone to the Mac computer > open the web page corresponding to the APP > open the "Development" menu of the Mac version of Safari

5) Find the corresponding page > click to open the web page inspector

2. Practical application 

1) Element layout: Manually modify html and css attributes, and click the refresh button to reset the page. Modify the element layout and style through the web page inspector, which can be directly applied to the web page of the APP.

2) Console: Troubleshoot page exceptions through the error log, and use the console to run JS code. Error logs include js syntax errors, script resource loading exceptions, and page exceptions.

3) Source: Find the JS file that needs to be debugged, set a breakpoint on the specific line, and trigger the breakpoint when the page logic calls to the specified line of code; realize basic linking through variable preview, breakpoint operation, and console operation Tune.

4) Network: Check the loading status of network resources (resource size, url, time consumption, type, exception), including related information of XHR interface (request, response).

5) Storage space: LocalStorage, Cookie, SessionStorage, view the storage information related to the page.

  

Guess you like

Origin blog.csdn.net/z119901214/article/details/123634789