美文网首页我爱编程
JavaScriptCore:OC和JS交互小记

JavaScriptCore:OC和JS交互小记

作者: HWenj | 来源:发表于2016-02-17 10:31 被阅读754次

    JavaScriptCore中类和协议:

    • JSContext: JavaScript上下文环境。
      JSContext *jsContext = [webView valueForKeyPath:"documentView.webView.mainFrame.javaScraptContext"];
    • JSValue:JSOC之间的数据和方法桥梁。
      1. 从JS上下文中获取JS方法:
        JSValue *jsFunc = jsContext[@"jsFunc"];
      2. 从本地JS代码中获得JS对象
        JSContext *jsContext = [[JSContext alloc] init];
        JSValue *localJS;
        NSString *path = [[NSBundle mainBundle] pathForResource:@"script" ofType:@"js"];
        NSString *scriptStr = [NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
        localJS = [jsContext evaluateScript:scriptStr];
      3. 调用JS方法后获得数据
        JSValue *jsFunc = localJS[@"jsFunc"];
        JSValue *jsValue = [jsFunc callWithAruments:@[args1,args2...]];
        Bool ocValue = [jsValue toBool];
    • JSManagedValue: 管理数据和方法的类。
    • JSVirtualMachine: 处理线程关系。
    • JSExport: 这是协议, 如果需要将一个OC对象回传给JS, 需要OC对象遵守此协议。
      1. 给JS传值
        #import <Foundation/Foundation.h>
        #import <JavaScriptCore/JavaScriptCore.h>

        @protocol userInfoProtocol <JSExport>
        @property (nonatomic ,copy) NSString *result;
        @property (nonatomic ,copy) NSString *fullName;
        @end
        
        @interface XDUserInfoLoginResult:NSObject<userInfoProtocol>
        @property (nonatomic ,copy) NSString *result;
        @property (nonatomic ,copy) NSString *fullName;
        @end
        -----------------------------------------
        //注入JS方法
        self.jsContext[@"getLoginInfo"] = ^() {
           XDUserInfoLoginResult *result = [[XDUserInfoLoginResult alloc] init];
           return result;
        };
        
      2. 给JS传方法

        html代码
        <!DOCTYPE html>
        <html>
        <head lang="en">
           <meta charset="UTF-8">
        </head>
        <body>
            <div style="margin-top: 100px">
                <h1>JavaScriptCore:OC和JS交互小记</h1>
                <input type="button" value="CallOC" onclick="nativeObj.callOC()">
            </div>       
        <script>
            var ocCallback = function(){
               alert('success');
            }
        </script>
        </body>
        </html>
        
      oc代码
            #import "ViewController.h"
            #import <JavaScriptCore/JavaScriptCore.h>
      
            @protocol JSObjcDelegate <JSExport>
            //实现JS中需要调用的callOC方法
            - (void)callOC;
            @end
      
            @interface ViewController () <UIWebViewDelegate, JSObjcDelegate>
      
            @property (nonatomic, strong) JSContext *jsContext;
            @property (weak, nonatomic) IBOutlet UIWebView *webView;
      
            @end
      
            @implementation ViewController
      
            #pragma mark - Life Circle
      
            - (void)viewDidLoad {
                [super viewDidLoad];
      
                NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
                [self.webView loadRequest:[[NSURLRequest alloc] initWithURL:url]];
            }
      
            #pragma mark - UIWebViewDelegate
      
            - (void)webViewDidFinishLoad:(UIWebView *)webView {
                //拿到JS上下文
                self.jsContext = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
                //注入JS代码,定义JS中需要调用的nativeObj
                self.jsContext[@"nativeObj"] = self;
                self.jsContext.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
                    context.exception = exceptionValue;
                    NSLog(@"异常信息:%@", exceptionValue);
                };
            }
      
            #pragma mark - JSObjcDelegate
            //实现callOC方法
            - (void)callOC {
                NSLog(@"callOC");
                // JS调用OC成功之后在回调JS的方法ocCallback
                JSValue *ocCallback = self.jsContext[@"ocCallback"];
                [ocCallback callWithArguments:nil];
            }
      
            @end
      

    OC执行JS代码方法:

    // UIWebView的方法
    - (nullable NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)script;
    
    // JavaScriptCore中JSContext的方法
    - (JSValue *)evaluateScript:(NSString *)script;
    - (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL
    
    相关应用
    // 获取当前页面的title
    NSString *title = [webview stringByEvaluatingJavaScriptFromString:@"document.title"];
    
    // 获取当前页面的url
    NSString *url = [webview stringByEvaluatingJavaScriptFromString:@"document.location.href"];
    
    // 阻止alert
    [webView stringByEvaluatingJavaScriptFromString:@"window.alert=null;"];
    
    //出现304白屏问题
    if ([webView stringByEvaluatingJavaScriptFromString:@"document.body.innerHTML"].length < 1 ) { 
        HXLog(@"Reconstructing request...");
        [self loadWithOutCacheUrl:self.currentUrl];
        return;
    }
    

    参考

    Objective-C与JavaScript交互的那些事

    相关文章

      网友评论

        本文标题:JavaScriptCore:OC和JS交互小记

        本文链接:https://www.haomeiwen.com/subject/vlfmkttx.html