Detailed Explanation and Example of Interaction between IOS and Web Page JS

  • 2021-09-12 02:30:19
  • OfStack

IOS interacts with Web page JS

With the rapid iterative development trend of mobile APP, html web pages are embedded in more and more APP. However, in some large and medium-sized APP, especially e-commerce APP and html pages, html requires interaction with native languages and mutual value transmission. For example, in the webpage of a popular scenic spot in Ctrip APP, clicking on a scenic spot can jump to the original controller of the scenic spot details page.

For this reason, I have sorted out three most commonly used, convenient and effective ways of interacting between OC and JS for everyone to learn and communicate.

Type 1: JS passes values to OC.

1. Technical solution: using JavaScriptCore. framework framework

2. Usage scenario: A method in the code in the web page, such as the click event method, passes the parameters of the method to OC for OC to use.

For example, there are many popular scenic spots in the webpage of a popular scenic spot in Ctrip APP. Click on the picture or name of a scenic spot to jump to the original controller of the scenic spot details page.

3. The code is implemented as follows:

The code to be implemented in OC:

Drag into the JavaScriptCore. framework static library, complying with the UIWebViewDelegate proxy protocol.

Write the following code in the-webViewDidFinishLoad: method:


- (void)webViewDidFinishLoad:(UIWebView *)webView{

  JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

  context[@"passValue"] = ^{

    NSArray *arg = [JSContext currentArguments];
    for (id obj in arg) {
      NSLog(@"%@", obj);
    }
  };

}

passValue is the function name of JS, and the obtained arg array is the parameter of passValue function of JS, that is, the parameter that JS should pass to OC.

The code to be implemented in JS:


function testClick()
      {
        var str1=document.getElementById("text1").value;
        var str2=document.getElementById("text2").value;

        passValue(str1,str2);
      }

In the function that needs to pass the value to OC (for example, testClick ()), call the passValue () function directly and pass the value in.

Type 2: JS passes values to OC.

1. Technical solution: Using the custom url method, every time you click on the webpage,

2. Usage scenario: A method in the code in the web page, such as the click event method, passes the parameters of the method to OC for OC to use.

For example, there are many popular scenic spots in the webpage of a popular scenic spot in Ctrip APP. Click on the picture or name of a scenic spot to jump to the original controller of the scenic spot details page.

3. The code is implemented as follows:

The code to be implemented in JS:


 function testClick()
      {

        var str1=document.getElementById("text1").value;
        var str2=document.getElementById("text2").value;

        // "objc://" Custom protocol header ;
        // str1&str2 In order to pass it on to OC Value of , With ":/" As a separation 
        window.location.href="objc://"+":/"+str1+":/"+str2;
      }

In functions that need to pass values to OC (for example, testClick ()), write the code in the above format.

Where objc://is the custom protocol header, and str1 and str2 are the values that JS will pass to OC.

The code to be implemented in OC:


// Observance UIWebViewDelegate Agency agreement. 
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
  // Get real-time access to web pages url
  NSString *requestStr = [[request.URL absoluteString] stringByRemovingPercentEncoding];

  // In url Looking for custom protocol headers in "objc://"
  if ([requestStr hasPrefix:@"objc://"]) {

    //  With "://" For the center will url Split into two parts and put them into an array arr
    NSArray *arr = [requestStr componentsSeparatedByString:@"://"];
    NSLog(@"%@",arr);

    // Take the second half of it 
    NSString *paramStr = arr[1];
    NSLog(@"%@",paramStr);

    // With ":/" Set the second half for identification url Divide into several parts and put them into an array arr2 At this time arr2[0] Is empty, arr2[1] Be the first 1 A parameter value, arr2[2] Be the first 2 A pass parameter value, and so on 
    NSArray *arr2 = [paramStr componentsSeparatedByString:@":/"];
    NSLog(@"%@",arr2);

    // Take out the parameters and use them 
    if (arr2.count) {
      NSLog(@" Parametric ");
      [self doSomeThingWithParamA:arr2[1] andParamB:arr2[2]];
    }else{
      NSLog(@" Parametric-free ");
    }
    return NO;
  }

  return YES;
}
// Right JS Call the value from the 
- (void)doSomeThingWithParamA:(id)paramA andParamB:(id)paramB{

  NSLog(@"%@  %@", paramA, paramB);
}

The third is to realize the mutual value transfer between JS and OC by using the third square library.

1. Technical scheme: use WebViewJavascriptBridge3 square library

2. Usage scenario: A method in the code in the web page, such as the click event method, passes the parameters of the method to OC for OC to use.

For example, there are many popular scenic spots in the webpage of a popular scenic spot in Ctrip APP. Click on the picture or name of a scenic spot to jump to the original controller of the scenic spot details page.
Or pass the native user information to the web page for its personalized display

3. The code is implemented as follows:

OC to JS

JS needs to implement the code:


function setupWebViewJavascriptBridge(callback) {
    if (window.WebViewJavascriptBridge) { return callback(WebViewJavascriptBridge); }
    if (window.WVJBCallbacks) { return window.WVJBCallbacks.push(callback); }
    window.WVJBCallbacks = [callback];
    var WVJBIframe = document.createElement('iframe');
    WVJBIframe.style.display = 'none';
    WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
    document.documentElement.appendChild(WVJBIframe);
    setTimeout(function() { document.documentElement.removeChild(WVJBIframe) }, 0)
  }

  // Call the function defined above 
  setupWebViewJavascriptBridge(function (bridge){

    //OC Pass value to JS 'testJavascriptHandler' Customize the system for both parties 1 Method name; 'data' Yes OC The value passed in; 'responseCallback' Yes JS Give it after receiving it OC Callback of 
    bridge.registerHandler('testJavascriptHandler', function(data, responseCallback) {
        // Print OC Pass-in value 
        log('ObjC called testJavascriptHandler with', data)

        var responseData = { 'Javascript Says':'Right back atcha!' }

        log('JS responding with', responseData)

        // To OC Callback of 
        responseCallback(responseData)

      })

OC needs to implement the code:

Import the third library WebViewJavascriptBridge;; Comply with UIWebViewDelegate;


 // Set the 3 Square Bridge Available 
  [WebViewJavascriptBridge enableLogging];

  // Association webView And bridge
  _bridge = [WebViewJavascriptBridge bridgeForWebView:web];

  [_bridge setWebViewDelegate:self];

  //OC To JS Value transfer, user-defined by both parties 1 Individual system 1 Method name of 'testJavascriptHandler' ; data Is the value to be passed in 
  [_bridge callHandler:@"testJavascriptHandler" data:@{@" Age ":@"20"}];

JS to OC

JS needs to implement the code:


 // Click on the web page 1 Buttons 
   callbackBt.onclick = function()
   { 
   var str1=document.getElementById("text1").value;
   var str2=document.getElementById("text2").value;

   //JS To OC Pass value. 'passValue' Custom system for both parties 1 Method name; 'str1'&'str2' Is the value to pass;  response For OC Give on receipt JS Callback of 
   bridge.callHandler('passValue', {str1,str2}, function(response) {
                })

   }

Code to be implemented in OC:

Import the third library WebViewJavascriptBridge;; Comply with UIWebViewDelegate;


 // Set the 3 Square Bridge Available 
  [WebViewJavascriptBridge enableLogging];

  // Association webView And bridge
  _bridge = [WebViewJavascriptBridge bridgeForWebView:web];

  [_bridge setWebViewDelegate:self];

  //js To oc Value transfer .'passValue' Custom system for both parties 1 Method name; 'data' For JS The value passed in; 'responseCallback' For OC Give the value after receiving it JS Callback returned 
  [_bridge registerHandler:@"passValue" handler:^(id data, WVJBResponseCallback responseCallback) {

    // Print js Pass-in value 
    NSLog(@"%@", data);

    // Return to js Value of 
    responseCallback(@" Got it ");
  }];

It should be noted that no matter which party passes the value to which party, the name of the method passing the value and the name of the method corresponding to the receiving value should be kept 1.

Thank you for reading, hope to help everyone, thank you for your support to this site!


Related articles: