iOS - oc与js交互的几种方式(2)

  • 本文主要讲js调用oc

    • 方式一:通过替换js中的function(方法)
    • 方式二:通过注入对象,直接调用对象方法
    • 方式三:利用网页重定向,截取字符串.
  • 代码如下:


#import "ViewController.h"
#import 
#import "Person.h"

#define kScreenW [UIScreen mainScreen].bounds.size.width
#define kScreenH [UIScreen mainScreen].bounds.size.height
#define kScreenB [UIScreen mainScreen].bounds
@interface ViewController ()

@property (nonatomic, strong) UIWebView *webView;

@end

@implementation ViewController

#pragma mark - oc点击btn调用js中的function
- (IBAction)clickBtn:(id)sender {
    
    /** 拼接js中function的字符串.通过webview调用 */
    NSString * str = [NSString stringWithFormat:@"showAlert('%@')",@"这是oc调用js的message"];
    

    [self.webView stringByEvaluatingJavaScriptFromString:str];
    
//    NSString * result = [self.webView stringByEvaluatingJavaScriptFromString:js];
//    NSLog(@"%@",result);
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.webView = [[UIWebView alloc] initWithFrame:kScreenB];
    self.webView.delegate = self;

    NSString * path = [[NSBundle mainBundle] pathForResource:@"First.html" ofType:nil];
    NSURL * url = [NSURL URLWithString:path];
    NSURLRequest * request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
    [self.view addSubview:self.webView];
}

#pragma mark - js调用oc 方式3 截取字符串
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{

    NSURL * url = [request URL];
    
    /** 方法名全部小写 */
//我加载的html的时候内部方法的方法名为copyText,通过url scheme来截取方法名,此处方法名一定要小写...否则执行不了.
//return NO 则调用我们制定的oc代码,而不调用js中的function copyText代码
    if ([[url scheme] isEqualToString:@"copytext"]) {
       
        UIAlertController * alertVc = [UIAlertController alertControllerWithTitle:@"操作提示" message:@"这是js调用oc的弹框" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction * action = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDestructive handler:nil];
        [alertVc addAction:action];
        [self presentViewController:alertVc animated:YES completion:nil];
        return NO;
    }
    
    return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webView{

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

    JSContext * context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
#pragma mark - js与oc交互方式 1
    /**
     1.加载完毕截取方法名,替换为block内部方法. ---- 替换方法
     2.我加载的html内部有方法名为copyText,通过context来将方法直接赋值成一个block,来替换掉原来的function copyText方法,从而调用js代码中的copyText的时候就调用block内部的oc代码. --- 我叫这个方法替换
     */
    context[@"copyText"] = ^(){
    
        /**
         1.block参数不限制.^(),括号内部参数没有限制
         2.[JSContext currentArguments] 获取参数数组
         */
        NSArray * params = [JSContext currentArguments];
        NSLog(@"hello copyText");
    };

#pragma mark - js与oc交互方式2
    /**
     1.给js注入对象,通过js调用对象方法 ---- 交互方式2
     2.被注入对象遵守协议NSExport,对象方法要与js方法名一样
     a.带参数方法名:jsStr3=@"testobject.TestTowParameterSecondParameter('参数A','参数B')" 对应如下oc方法名:
     -(void)TestTowParameter:(NSString *)message1 SecondParameter:(NSString *)message2
      b.Person中的协议只有两个方法一个是eat 一个是run
     */
    Person * per = [Person new];
    context[@"per"] = per;
    
//js调用oc对象的执行方式per.eat()
    NSString * jsStrEat = @"per.eat()";

//通过context 或者 webView都可以调用
    [context evaluateScript:jsStrEat];
    
}

小结js调用oc的三种方式:

1.根据网页重定向截取字符串通过url scheme判断
2.替换方法.context[@"copyText"]
3.注入对象:遵守协议NSExport,设置context[@"per"] = per调用方式类似swift中的链式编程per.eat();

你可能感兴趣的:(iOS - oc与js交互的几种方式(2))