Js與OC交互

源碼請(qǐng)點(diǎn)擊github地址下載。

下面講述實(shí)現(xiàn)OC和JS的交互,它們相互調(diào)用,其中需要寫(xiě)一個(gè)靜態(tài)的HTML文件用于提供JS方法。

效果圖如下:

screen.png



一.OC調(diào)用JS:

不說(shuō)閑話,看代碼如下

  • 需要先在js文件定義方法postStr供oc調(diào)用
  function postStr(string) {
        return 'I am the return parameter JS, and param ' + string;
    }
  • oc代碼只需一句即可調(diào)用
  NSString *str = [self.webView stringByEvaluatingJavaScriptFromString:@"postStr('ocToJs')"];
  //輸出str為I am the return parameter JS, and param ocToJs,正式j(luò)s中postStr方法的返回值。
需注意的是正確書(shū)寫(xiě)@"postStr('ocToJs')"的格式,postStr為js方法,ocToJs是OC傳遞給JS的參數(shù)。

二.JS調(diào)用OC:

  • 在h5頁(yè)面添加了了button元素,用于觸發(fā)js方法jsCallOCClicked
  <button onclick="jsCallOCClicked()">
    <h1>jsCallOC</h1>
  </button>
  • 在js文件的jsCallOCClicked()方法中去調(diào)用OC的jsCallToOC()方法
  function jsCallOCClicked() {
        window.location.href = "objc://jsCallToOC#param#github地址#param#https://github.com/SoftProgramLX/OcAndJs";
    }
說(shuō)明:<br>
1.“objc://”為自定義的OC識(shí)別JS調(diào)用的標(biāo)識(shí)<br>
2.“jsCallToOC”為需調(diào)用的OC方法<br>
3.“#param#”為自定義的方法與參數(shù)或參數(shù)與參數(shù)的分隔符<br>
4.“github地址”為js傳遞給OC的第一個(gè)參數(shù)<br>
5.“https://github.com/SoftProgramLX/OcAndJs”為js傳遞給OC的第二個(gè)參數(shù)<br>
  • 實(shí)現(xiàn)OC的jsCallToOC()方法
- (void)jsCallToOC:(NSArray *)params
{
    dataArr = params;
    alertV = [[UIAlertView alloc] initWithTitle:@"js已經(jīng)調(diào)用了OC方法" message:@"查看控制臺(tái)的信息,點(diǎn)擊取消會(huì)再觸發(fā)OC調(diào)用js" delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"確定", nil];
    alertV.tag = 9666;
    [alertV show];
    
    NSLog(@"js調(diào)用OC返回值:%@", params);
}
這里params[0]輸出是github地址,params[1]輸出是https://github.com/SoftProgramLX/OcAndJs
  • 關(guān)鍵所在

    目前JS調(diào)用OC的jsCallToOC()方法還不會(huì)觸發(fā),當(dāng)點(diǎn)擊h5頁(yè)面的按鈕時(shí)只會(huì)觸發(fā)OC的- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;這個(gè)方法。

    需在這個(gè)方法里解析request參數(shù)的URL值,解析后path的值就是"objc://jsCallToOC#param#github地址#param#https://github.com/SoftProgramLX/OcAndJs",再繼續(xù)分解出里面的方法與參數(shù),然后執(zhí)行[self performSelector:todoM withObject:params afterDelay:0];代碼才能觸發(fā)OC的jsCallToOC()方法。

    代碼如下:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    NSString *path =  [[request URL] absoluteString];
    if ([[UIDevice currentDevice].systemVersion doubleValue] >= 7.0) {
        path = [path stringByRemovingPercentEncoding];
    }else{
        path = [path stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    
    if ([path hasPrefix:@"ios"]||[path hasPrefix:@"objc"]) {
        NSString *method = [path substringFromIndex:@"objc://".length];
        NSArray *sels = [method componentsSeparatedByString:@"#param#"];
        SEL todoM;
        if (sels.count>1) {
            todoM = NSSelectorFromString([NSString stringWithFormat:@"%@:",sels[0]]);
            NSMutableArray *params = [NSMutableArray array];
            for (int i=1; i<sels.count; i++) {
                [params addObject:sels[i]];
            }
            if ([self respondsToSelector:todoM]) {
                [self performSelector:todoM withObject:params afterDelay:0];
            }
        }else if(sels.count==1){
            todoM = NSSelectorFromString([NSString stringWithString:sels[0]]);
            if ([self respondsToSelector:todoM]) {
                [self performSelector:todoM withObject:nil afterDelay:0];
            }
        }
        return NO;
    }
    
    return YES;
}
說(shuō)明:<br>
這里判斷sels.count>1的目的是判斷有無(wú)傳參<br>
若無(wú)參數(shù)則定義方法- (void)jsCallToOC;<br>
若有參數(shù)則定義方法- (void)jsCallToOC:(NSArray *)params。

三.額外方法

  • 禁止復(fù)制網(wǎng)頁(yè)文字
- (void)deletePrompt
{
    [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitUserSelect='none';"];
    [self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.style.webkitTouchCallout='none';"];
}
  • 用于js統(tǒng)計(jì)
- (void)jsStatistics
{
    NSString *systemUserAgent = [self.webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
    
    if (!([systemUserAgent rangeOfString:@"****-app-iphone Version/"].length > 0)) {
        NSString *currentVersion = [NSBundle mainBundle].infoDictionary[(__bridge NSString *)kCFBundleVersionKey];
        systemUserAgent = [systemUserAgent stringByAppendingFormat:@" ***-app-iphone Version/%@", currentVersion];
    }
    
    NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:systemUserAgent, @"UserAgent", nil];
    [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容