(0085) advanced use of OC and JS interaction in IOS development (JavaScript core)

Posted by NottaGuru on Wed, 01 Jan 2020 02:11:41 +0100

Foregoing: Javascript core you don't know about the interaction between OC and JS. OC and JS use model to realize interaction, communication and value transfer! Interesting!

For nearly three years, I have been contacting OC and JS intermittently. I feel that UIWebView OC and JS have been very skilled in interaction, but I will get new results every time I study it. Also more and more feel JS and OC interaction originally so smooth, more and more senseless! You can use the object, property and method of OC just like OC! It's really convenient!

In fact, I have also summarized three situations of OC and JS interaction: WebView JavaScript bridge, JavaScript core, and interception URL.

Someone asked me? "Do I want to return a bunch of parameters for h5 in jsmodel?"
According to this question? I'll do it! The JSExport implementation of the JavaScript core used here!

Practice code: https://github.com/muyushifang07/jsCallOCModel

The first part:

//
//  ELLiveJSModel.h
//  JavaScriptCoreDemo
//
//  Created by giifidev on 2018/8/21.
//  Copyright © 2018 reborn. All rights reserved
//

#import <Foundation/Foundation.h>
#import <JavaScriptCore/JSExport.h>

@class ELLiveJSModel;
@protocol MyPointExports <JSExport>

@property (nonatomic,assign) double x;
@property (nonatomic,assign) double y;

- (NSString *)description;
- (ELLiveJSModel *)makePointX:(double)x PointY:(double)y;

@end

@interface ELLiveJSModel : NSObject<MyPointExports>

@property (nonatomic,assign) double x;
@property (nonatomic,assign) double y;

- (NSString *)description;
- (ELLiveJSModel *)makePointX:(double)x PointY:(double)y;

@end
//
//  ELLiveJSModel.m
//  JavaScriptCoreDemo
//
//  Created by giifidev on 2018/8/21.
//  Copyright © 2018 reborn. All rights reserved
//

#import "ELLiveJSModel.h"

@implementation ELLiveJSModel

- (NSString *)description {
    // self.x = 7;
    // self.y = 9;
    // Here you can see the value 20 assigned by the front end. The front end can directly operate the OC model and properties
    NSLog(@"Printing model Of X Value-----:%f",self.x);
    return @"description";
}

- (ELLiveJSModel *)makePointX:(double)x PointY:(double)y {
    ELLiveJSModel *model = [[ELLiveJSModel alloc]init];
    model.x = x;
    model.y = y;
    NSLog(@"Return to a new model.x:%f model.y:%f",model.x,model.y);
    return model;
}

@end

Part II:

//
//  JSModelViewController.m
//  JavaScriptCoreDemo
//
//  Created by giifidev on 2018/8/21.
//  Copyright © 2018 reborn. All rights reserved
//

#import "JSModelViewController.h"
#import "ELLiveJSModel.h"

#define kScreenWidth                [UIScreen mainScreen].bounds.size.width
#define kScreenHeight               [UIScreen mainScreen].bounds.size.height

@interface JSModelViewController ()<UIWebViewDelegate>
@property(nonatomic, strong) UIWebView *webView;
@property(nonatomic, strong) JSContext *context;
@end

@implementation JSModelViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    self.title = @"indexModel";
    self.view.backgroundColor = [UIColor whiteColor];

    self.webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight)];
    [self.view addSubview:self.webView];

    NSString *path = [[NSBundle mainBundle] pathForResource:@"indexModel" ofType:@"html"];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]];
    self.webView.delegate = self;
    [self.webView loadRequest:request];
}

#pragma mark - UIWebViewDelegate

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    // Get html title set navigation bar title
    self.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"];
    self.context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    // Catch exception callback
    self.context.exceptionHandler = ^(JSContext *context, JSValue *exceptionValue) {
        context.exception = exceptionValue;
        NSLog(@"Abnormal information: %@",exceptionValue);
    };

    // model's method JS interacts with OC
    ELLiveJSModel *jsModel = [ELLiveJSModel new];
    self.context[@"testobject"] = jsModel;

    // Note: jsModel is the object name in OC, testobject is the object name in JS

    // Simulate JS call method
    NSString *jsCallOCModelFunction = @"testobject.description()";
    JSValue *valu = [self.context evaluateScript:jsCallOCModelFunction];
    NSLog(@"vali----:%@",[valu toString]);  // Return value

    NSLog(@"Not yet assigned X Of log:%f",jsModel.x);

    // Simulate JS calling method to assign value to testobject.x
    NSString *jsCallOCModelFunction1 = @"testobject.x=30";
    [self.context evaluateScript:jsCallOCModelFunction1];
    NSLog(@"jsCallOCFunction1----%f",jsModel.x);

    // An example of JS two parameter call
    NSString *jsCallOCModelFunction2 = @"testobject.makePointXPointY('20','50')";
    [self.context evaluateScript:jsCallOCModelFunction2];
    NSLog(@"jsCallOCFunction2----%f",jsModel.x);
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    NSLog(@"error == %@",error);
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Test entry

JS to modify the value button of the properties of OC's model

The console log can get practical results:

JS can get the object of OC, operate the properties of OC model, and call the method of model! And JS and OC operate on the same model object!

Like children's shoes can be taken to study it! an endless enjoyment!

Topics: Javascript github