iOS開(kāi)發(fā)-基于原生JS與OC方法互相調(diào)用并傳值(附HTML代碼)

最近項(xiàng)目里面有有個(gè)商品活動(dòng)界面,要與web端傳值,將用戶在網(wǎng)頁(yè)點(diǎn)擊的商品id 傳給客戶端,也就是js交互,其實(shí)再說(shuō)明白一點(diǎn)就是方法的互相調(diào)用而已。

本文敘述下如何進(jìn)行原生的JavaScript交互

本文包括JS調(diào)用OC方法并傳值,OC調(diào)用JS方法并傳值

本來(lái)想把html放進(jìn)服務(wù)器里面,然后訪問(wèn),但是覺(jué)得如果html在本地加載更有助于理解,特把html放進(jìn)項(xiàng)目里

HTML代碼

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<div style="margin-top: 20px">
<h2>JS與OC交互</h2>
<input type="button" value="喚起本地方法(call)" onclick="tianbai.call()">
</div>
<div>
<input type="button" value="喚起getCall:(NSString *)callString傳值" onclick="call()">
</div>

<script>
    
    
    
var call = function()
{
    var callInfo = JSON.stringify({"jianshu": "http://www.lxweimin.com/users/55c8fdc3c6e7/latest_articles"});
        tianbai.getCall(callInfo);
}

var Callback = function(str)
{
    alert(str);
}
var alerCallback = function()
{
    alert('成功');
}
</script>
</body>
</html>

上面html的代碼:建立了兩個(gè)button

第一個(gè)button綁定了 tianbai.call() 方法,這里 tianbai 是一個(gè)對(duì)象,這個(gè)對(duì)象的作用下面OC代碼中會(huì)說(shuō)明, tianbai.call() 代表 tianbai 對(duì)象調(diào)用 call() 方法

第二個(gè)button綁定了 call() 的方法,調(diào)用的是下面JavaScript中的 call() 方法,在 JavaScript 的 call() 里面,定義一個(gè) callInfo 參數(shù),方法中 tianbai.getCall(callInfo) 代表 tianbai 對(duì)象調(diào)用 getCall 方法并傳參數(shù) callInfo ,下面兩個(gè)方法是OC調(diào)用JavaScript方法,其中Callback傳回str,alerCallback為OC僅調(diào)用JavaScript方法!

OC代碼

demo采用原生的JavaScriptCore類(lèi)

引入三個(gè)名詞:

  1. JSContext:給JavaScript提供運(yùn)行的上下文環(huán)境
  2. JSValue:JavaScript和Objective-C數(shù)據(jù)和方法的橋梁
  3. JSExport:這是一個(gè)協(xié)議,如果采用協(xié)議的方法交互,自己定義的協(xié)議必須遵守此協(xié)議

ViewController.h中的代碼(代碼過(guò)長(zhǎng),方法說(shuō)明都在注釋里)

#import <UIKit/UIKit.h>
//導(dǎo)入頭文件
#import <JavaScriptCore/JavaScriptCore.h>

@protocol JSObjcDelegate <JSExport>
//tianbai對(duì)象調(diào)用的JavaScript方法,必須聲明?。。?- (void)call;
- (void)getCall:(NSString *)callString;

@end
@interface ViewController : UIViewController<UIWebViewDelegate,JSObjcDelegate>
@property (nonatomic, strong) JSContext *jsContext;
@property (strong, nonatomic)  UIWebView *webView;

@end

ViewController.m中的代碼(代碼過(guò)長(zhǎng),方法說(shuō)明都在注釋里)

JavaScriptCore中web頁(yè)面調(diào)用原生應(yīng)用的方法可以用Delegate或Block兩種方法,此文以按Delegate講解。

設(shè)置webView

self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(0, 20, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
    self.webView.delegate = self;
    //從本地加載html文件
    NSString* path = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];
    NSURL* url = [NSURL fileURLWithPath:path];
    NSURLRequest* request = [NSURLRequest requestWithURL:url] ;
    [self.webView loadRequest:request];
    
    [self.view addSubview:self.webView];

JavaScript的tianbai是一個(gè)對(duì)象,充當(dāng)原生應(yīng)用和web頁(yè)面之間的一個(gè)橋梁。用來(lái)調(diào)用方法

webview加載完成調(diào)用代理

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

      // 設(shè)置javaScriptContext上下文
    self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //將tianbai對(duì)象指向自身
    self.jsContext[@"tianbai"] = self;
    self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
        context.exception = exceptionValue;
        NSLog(@"異常信息:%@", exceptionValue);
    };
}

將對(duì)象指向自身后,如果調(diào)用 tianbai.call() 會(huì)響應(yīng)下面的方法,OC方法中調(diào)用js中的Callback方法,并傳值

- (void)call{
    NSLog(@"call");
    // 之后在回調(diào)JavaScript的方法Callback把內(nèi)容傳出去
    JSValue *Callback = self.jsContext[@"Callback"];
    //傳值給web端
    [Callback callWithArguments:@[@"喚起本地OC回調(diào)完成"]];
}

將對(duì)象指向自身后,如果調(diào)用 tianbai.getCall(callInfo) 會(huì)響應(yīng)下面的方法,OC方法中僅調(diào)用JavaScript中的alerCallback方法

- (void)getCall:(NSString *)callString{
    NSLog(@"Get:%@", callString);
    // 成功回調(diào)JavaScript的方法Callback
    JSValue *Callback = self.jsContext[@"alerCallback"];
    [Callback callWithArguments:nil];
}

將對(duì)象指向自身后,還可以向html注入js

- (void)alert{

    // 直接添加提示框
    NSString *str = @"alert('OC添加JS提示成功')";
    [self.jsContext evaluateScript:str];

}

Demo地址:點(diǎn)擊下載

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容