1. 程式人生 > >iOS JS傳值給OC方法(附HTML程式碼)

iOS JS傳值給OC方法(附HTML程式碼)

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.jianshu.com/users/55c8fdc3c6e7/latest_articles"});
        tianbai.getCall(callInfo);
}

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


上面html的程式碼:建立了兩個button

第一個button綁定了 tianbai.call() 方法,這裡 tianbai 是一個物件,這個物件的作用下面OC程式碼中會說明, tianbai.call() 代表 tianbai 物件呼叫 call() 方法

第二個button綁定了 call() 的方法,呼叫的是下面JavaScript中的 call() 方法,在 JavaScript 的 call() 裡面,定義一個 callInfo 引數,方法中 tianbai.getCall(callInfo) 代表 tianbai 物件呼叫 getCall 方法並傳引數 callInfo ,下面兩個方法是OC呼叫JavaScript方法,其中Callback傳回str,alerCallback為OC僅呼叫JavaScript方法!

OC程式碼

demo採用原生的JavaScriptCore類

引入三個名詞:

  1. JSContext:給JavaScript提供執行的上下文環境
  2. JSValue:JavaScript和Objective-C資料和方法的橋樑
  3. JSExport:這是一個協議,如果採用協議的方法互動,自己定義的協議必須遵守此協議

ViewController.h中的程式碼(程式碼過長,方法說明都在註釋裡)

#import <UIKit/UIKit.h>
//匯入標頭檔案
#import <JavaScriptCore/JavaScriptCore.h>

@protocol JSObjcDelegate <JSExport>
//tianbai物件呼叫的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中的程式碼(程式碼過長,方法說明都在註釋裡)

JavaScriptCore中web頁面呼叫原生應用的方法可以用Delegate或Block兩種方法,此文以按Delegate講解。

設定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是一個物件,充當原生應用和web頁面之間的一個橋樑。用來呼叫方法

webview載入完成呼叫代理

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

      // 設定javaScriptContext上下文
    self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    //將tianbai物件指向自身
    self.jsContext[@"tianbai"] = self;
    self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
        context.exception = exceptionValue;
        NSLog(@"異常資訊:%@", exceptionValue);
    };
}


將物件指向自身後,如果呼叫 tianbai.call() 會響應下面的方法,OC方法中呼叫js中的Callback方法,並傳值

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


將物件指向自身後,如果呼叫 tianbai.getCall(callInfo) 會響應下面的方法,OC方法中僅呼叫JavaScript中的alerCallback方法

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


將物件指向自身後,還可以向html注入js

- (void)alert{

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

}


君凱商聯網-iOS-字唐名僧