IOS和JS交互那點(diǎn)事

很早之前有個(gè)項(xiàng)目牽扯到這塊就很想寫篇博客記錄下這篇文章了,這陣子有個(gè)項(xiàng)目又剛好遇到,正好有空,記錄記錄。

跟web的同鞋打過(guò)交道的肯定都知道,只要是涉及雙端交互就兩種方案啦。

  • 截取鏈接,一般也就通過(guò)UIWebView回調(diào)代理shouldStartLoadWithRequest截取固定鏈接然后在原生里面做相應(yīng)的業(yè)務(wù)操作,實(shí)現(xiàn)也比較簡(jiǎn)單,當(dāng)然這個(gè)方案也是一般涉及業(yè)務(wù)簡(jiǎn)單時(shí)候可以用,比如給個(gè)固定鏈接跳轉(zhuǎn)原生界面,如果業(yè)務(wù)復(fù)雜點(diǎn)web要給原生傳遞參數(shù)或者多個(gè)參數(shù)再或者原生要操作web里面的相關(guān)業(yè)務(wù),那就得考慮下面的方案二了。

  • JS交互,iOS7以前我們對(duì)JS的操作只有webview里面一個(gè)函數(shù) stringByEvaluatingJavaScriptFromString,當(dāng)然也有很多人是用的這個(gè)第三方JavascriptBridge,IOS7之后,蘋果可能也考慮到了這方面的需求,也很給力推出了JavaScriptCore這個(gè)框架。

通過(guò)stringByEvaluatingJavaScriptFromString 實(shí)現(xiàn)OC執(zhí)行JS代碼

stringByEvaluatingJavaScriptFromString 這個(gè)方法是UIWebView里面的方法,也是最為簡(jiǎn)單的和JS交互的方式。

-(nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;

用法比較簡(jiǎn)單,一般在代理方法- (void)webViewDidFinishLoad:(UIWebView*)webView中使用。

- (void)webViewDidFinishLoad:(UIWebView*)webView
{
    // 獲取當(dāng)前頁(yè)面的title
    NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    // 獲取當(dāng)前頁(yè)面的url
    NSString *url = [webView stringByEvaluatingJavaScriptFromString:@"document.location.href"];
}

JavaScriptCore

這是IOS7后蘋果推出了JavaScriptCore這個(gè)框架,讓原生和web界面交互非常方便了。代碼是開源的JavaScriptCore 可以下載下來(lái)看看。

我們先了解下里面常見(jiàn)的屬性和協(xié)議

  • JSContext:給JavaScript提供運(yùn)行的上下文環(huán)境,通過(guò)-evaluateScript:方法就可以執(zhí)行一JS代碼。
  • JSValue:JavaScript和Objective-C數(shù)據(jù)和方法的橋梁,封裝了JS與ObjC中的對(duì)應(yīng)的類型,以及調(diào)用JS的API等。
  • JSManagedValue:管理數(shù)據(jù)和方法的類JSVirtualMachine:處理線程相關(guān),使用較少。
  • JSExport:這是一個(gè)協(xié)議,如果JS對(duì)象想直接調(diào)用OC對(duì)象里面的方法和屬性,那么這個(gè)OC對(duì)象只要實(shí)現(xiàn)這個(gè)JSExport協(xié)議就可以了。

OC調(diào)JS


    self.context = [[JSContext alloc] init];

    [self.context evaluateScript:@"function reduce(a,b) {return a-b}"];

    JSValue *value = [self.context[@"reduce"] callWithArguments:@[@10, @3]];

    NSLog(@"---%@", @([value toInt32]));    //---7

JS調(diào)OC

JS調(diào)用OC有兩個(gè)方法:block和JSExport protocol。

html實(shí)現(xiàn)代碼

<input type="button" value="JS調(diào)用原生block實(shí)現(xiàn)" onclick="alert('alert');" />
<input type="button" value="JS調(diào)用原生JSExport protocol實(shí)現(xiàn)" onclick="native.alert('alert');" />

oc實(shí)現(xiàn)代碼

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];

    // 打印JS異常
    self.context.exceptionHandler =
    ^(JSContext *context, JSValue *exceptionValue)
    {
        context.exception = exceptionValue;
        NSLog(@"%@", exceptionValue);
    };

    // 以 block 形式關(guān)聯(lián) JavaScript function
    self.context[@"alert"] =
    ^(NSString *alertText)
    {
        UIAlertView *alert = [[UIAlertView alloc]initWithTitle:alertText message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
        [alert show];
    };
    
    // 以 JSExport 協(xié)議關(guān)聯(lián) native 的方法
    self.context[@"native"] = self;
}

當(dāng)前類需要聲明和實(shí)現(xiàn)JSExport協(xié)議

@protocol TestJSExport <JSExport>
-(void)alert:(NSString *)alertText;
@end

@interface JSCallOCViewController : UIViewController<TestJSExport>
@property (strong, nonatomic) JSContext *context;
@end

#pragma mark - JSExport Methods
-(void)alert:(NSString *)alertText
{
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:alertText message:nil delegate:nil cancelButtonTitle:@"ok" otherButtonTitles:nil, nil];
    [alert show];
}

好啦,關(guān)于JavaScriptCore的基本介紹就是這樣了。
參考http://www.itdecent.cn/p/a329cd4a67ee

最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 跟原生開發(fā)相比,H5的開發(fā)相對(duì)來(lái)一個(gè)成熟的框架和團(tuán)隊(duì)來(lái)講在開發(fā)速度和開發(fā)效率上有著比原生很大的優(yōu)勢(shì),至少不用等待審...
    大沖哥閱讀 1,903評(píng)論 0 7
  • 隨著H5技術(shù)的興起,在iOS開發(fā)過(guò)程中,難免會(huì)遇到原生應(yīng)用需要和H5頁(yè)面交互的問(wèn)題。其中會(huì)涉及方法調(diào)用及參數(shù)傳值等...
    Chris_js閱讀 3,237評(píng)論 1 8
  • 昨晚因走錯(cuò)了路差點(diǎn)沒(méi)趕上最后一班地鐵??諘绲鸟R路除了偶爾飛馳而過(guò)的貨車就是路邊草叢中的蟲鳴聲。 昏黃的燈光下是我快...
    紅鶯蘿閱讀 640評(píng)論 4 6
  • 文/無(wú)可救藥的文藝青年 BGM:Say you won't let go 我來(lái)到你的生命里,陪你度過(guò)黑夜,天亮后我...
    無(wú)可救藥的文藝青年閱讀 582評(píng)論 0 6
  • 大地在慢慢的恢復(fù)著生機(jī) 幸存者并不被地震所征服 看,倒塌的房子重新矗立起來(lái) 聽(tīng),教室里又響起了浪浪讀書聲 美好的生...
    情話總是那么美閱讀 539評(píng)論 0 1

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