Summary of the problem of JS and native OC calling each other in iOS

Recently, due to work and personal idleness, I have not updated the blog in a timely manner. I apologize to all students for this, so I will not talk about nonsense. Today we will talk about the mutual calls between JS and native OC in iOS, and directly upload the code information~

#pragma mark - some details in JS

1> When a custom URL in JS is intercepted, the url scheme will all be converted to lowercase!

2> The encoding needs to be set in html, otherwise there may be encoding problems in Chinese parameters!

3> JS opens an iFrame instead of directly using document.location to avoid the problem of multiple requests and being overwritten by replacement!


#warning - stringByEvaluatingJavaScriptFromString方法注意

stringByEvaluatingJavaScriptFromString is a synchronous method. When using it to execute JS methods, if the JS methods are time-consuming, it will cause the interface to freeze! Especially when js pops up an alert. Alert will also block the interface, waiting for the user to respond, and stringByEvaluatingJavaScriptFromString will wait for js to return after execution. This creates a deadlock. It is officially recommended to use WKWebView's evaluateJavaScript:completionHandler: instead of this method.

In fact, we also have another way to customize a method to delay the execution of alert to prevent blocking, and then we call the custom alert method. Similarly, js methods that take a long time can also be placed in setTimeout.

function asyncAlert(content){    

     setTimeout(function(){         
          alert(content);         
     },1);
}


#pragma mark -UIWebView拦截URL总结

1> Why customize a loadURLmethod instead of using it directly window.location.href?
Answer: Because if the current web page is using the window.location.hrefloading web page at the same time, calling window.location.hrefto call the OC native method will result in the operation of loading the web page.
operation was canceled. Similarly, if two consecutive window.location.hrefOC native calls are executed, the first operation may also be cancelled. So we use custom
loadURL, to avoid this problem.
loadURLThe implementation can refer to the article about UIWebView and PhoneGap .

2> Why should the links in loadURL use a unified scheme?
Answer: It is convenient to do interception processing in OC, and reduce the jump phenomenon of webView caused by calling some methods not implemented by OC in JS. Because when we intercept URLs in OC, according to the scheme 
(ie a ctionType ) to distinguish whether to call a native method or a normal web page jump. Then according to the host (ie the part after // getLocation ) to distinguish what to do.

3> Why customize a asyncAlertmethod?
Answer: Because some JS calls require OC to return results to JS. stringByEvaluatingJavaScriptFromStringIt is a synchronous method that will wait for the js method to complete, and then pop up
Alerts also block the interface waiting for the user to respond, so they may cause deadlocks. Cause the alert to freeze the interface. If the callback JS is a time-consuming operation, it is recommended to put the time-consuming operation into
setTimeoutHitfunction .

4> How does UIWebView intercept URLs?
Answer: UIWebView has a proxy method that can intercept every linked Request. return YES, webView will load the link; return NO, webView will not add
Download this link. We handle our own URL in this intercepted proxy method.

#pragma mark - code example

#pragma mark - UIWebViewDelegate

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:

(UIWebViewNavigationType)navigationType {

NSURL *URL = request.URL;NSString *scheme = [URL scheme]; 

if ([schemeisEqualToString:@"haleyaction"]) {

        [self handleCustomAction:URL];

        returnNO;

    }

    returnYES;

}


It is very easy to intercept custom URLs by scheme here. If different methods use different schemes, it is very troublesome to judge. Then the direct code example:

#pragma mark - Intercept URL to call OC native method

- (void)handleCustomAction:(NSURL *)URL {

    NSString *host = [URLhost];

    if ([hostisEqualToString:@"scan"]) {

        

    } elseif ([hostisEqualToString:@"share"]) {

        [self share:URL];

    } elseif ([hostisEqualToString:@"getLocation"]) {

        [self getLocation];

    } elseif ([hostisEqualToString:@"pay"]) {

        [self payAction:URL];

    } elseif ([hostisEqualToString:@"shake"]) {

        [self shakeAction];

    } elseif ([hostisEqualToString:@"back"]) {

        [self goBack];

    }

}


#pragma mark - 如何将结果回调到JS

- (void)getLocation

{

    // 获取位置信息

    

    // 将结果返回给js

    NSString *jsStr = [NSStringstringWithFormat:@"setLocation('%@')",@"广东省深圳市宝安区西乡街道XXXX"];

    [self.webView stringByEvaluatingJavaScriptFromString:jsStr];

}


当然有时候我们在JS中调用OC方法的时候,也需要传参数到OC中,怎么传呢?就像一个get请求一样,把参数拼接在后面就行:

function share() {

    loadURL("haleyAction://shareClick?title=测试标题&content=测试内容&url=http://www.baidu.com");

}


那么如何获取到这些参数呢?所有的参数都在URL的query中,先通过&将字符串拆分,在通过=把参数拆分成key和value示例代码:

- (void)share:(NSURL *)URL

{

    NSArray *params =[URL.query componentsSeparatedByString:@"&"];

    

    NSMutableDictionary *tempDic = [NSMutableDictionary dictionary];

    for (NSString *paramStrin params) {

        NSArray *dicArray = [paramStr componentsSeparatedByString:@"="];

        if (dicArray.count >1) {   

     NSString *decodeValue = [dicArray[1]

stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

            [tempDic setObject:decodeValue forKey:dicArray[0]];

        }

    }

    

    NSString *title = [tempDic objectForKey:@"title"];

    NSString *content = [tempDic objectForKey:@"content"];

    NSString *url = [tempDic objectForKey:@"url"];

    // 在这里执行分享的操作

    

    // 将分享结果返回给js

    NSString *jsStr = [NSString stringWithFormat:@"shareResult('%@','%@','%@')",title,content,url];

    [self.webView stringByEvaluatingJavaScriptFromString:jsStr];

}


#pragma mark - OC调用JS方法

如果回调执行的JS方法带参数,而参数不是字符串时,不要加单引号,否则可能导致调用JS方法失败。



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325810796&siteId=291194637