美文网首页
OC关于js相关

OC关于js相关

作者: KevenT | 来源:发表于2018-09-05 16:56 被阅读0次

    一、OC调用js

    - (void)webViewDidFinishLoad:(UIWebView *)webView
    {
        self.title = [webView stringByEvaluatingJavaScriptFromString:@"doucument.title;"];
    }
    

    二、js调用OC

    1. 无参
    • 在js中定义一个自己的协议头
    <script>
      function method()
    {
      //login为oc方法
       location.href = 'keven://login';
    }
    </script>
    
    • 方法调用
    //拦截请求
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        NSString *url = request.URL.absoluteString;
        NSString *scheme = @"keven://";
        if ([url hasPrefix:scheme]) {
            //截取方法名
            NSString *methodName = [url substringFromIndex:scheme.length];
            //调用方法
            [self performSelector:NSSelectorFromString(methodName) withObject:nil];
            return NO;
        }
        return YES;
    }
    
    1. 有参
    • 一个参数的时候
    [self performSelector:NSSelectorFromString(methodName) withObject:param];
    
    • 两个参数的时候
    [self performSelector:NSSelectorFromString(methodName) withObject:firstParam withObject:secondParam];
    
    • 多个参数的时候(使用NSInvocation,同样适用于一个或者两个参数)
      a. 给nsobject写分类
    #import "NSObject+Extension.h"
    
    @implementation NSObject (Extension)
    - (id)performSelector:(SEL)selector withObjects:(NSArray *)objects
    {
        // 方法签名(方法的描述)
        NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
        if (signature == nil) {
    //        @throw [NSException exceptionWithName:@"牛逼的错误" reason:@"方法找不到" userInfo:nil];
            [NSException raise:@"牛逼的错误" format:@"%@方法找不到", NSStringFromSelector(selector)];
        }
        
        // NSInvocation : 利用一个NSInvocation对象包装一次方法调用(方法调用者、方法名、方法参数、方法返回值)
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
        invocation.target = self;
        invocation.selector = selector;
        
        // 设置参数
        NSInteger paramsCount = signature.numberOfArguments - 2; // 除self、_cmd以外的参数个数
        paramsCount = MIN(paramsCount, objects.count);
        for (NSInteger i = 0; i < paramsCount; i++) {
            id object = objects[i];
            //传入空参数的时候的处理
            if ([object isKindOfClass:[NSNull class]]) continue;
            //从2开始,应为索引0和1被占用了
            [invocation setArgument:&object atIndex:i + 2];
        }
        
        // 调用方法
        [invocation invoke];
        
        // 获取返回值
        id returnValue = nil;
        if (signature.methodReturnLength) { // 有返回值类型,才去获得返回值
            [invocation getReturnValue:&returnValue];
        }
        
        return returnValue;
    }
    @end
    

    b. 在控制器中调用

    [self performSelector:@selector(sendMessage:number2:number3:) withObjects:@[
                                                                            [NSNull null],
                                                                            [NSNull null],
                                                                            @"10010"
                                                                            ]];
    //等价于==》
    [self sendMessage:nil number2:nil number3:@"10010"];
    

    c. For Example

    /**
     * 通过这个方法完成JS调用OC
     * JS和OC交互的第三方框架:WebViewJavaScriptBridge
     */
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        // url == xmg://sendMessage_?200
        NSString *url = request.URL.absoluteString;
        NSString *scheme = @"xmg://";
        if ([url hasPrefix:scheme]) {
            // 获得协议后面的路径  path == sendMessage_number2_?200&300
            NSString *path = [url substringFromIndex:scheme.length];
            // 利用?切割路径
            NSArray *subpaths = [path componentsSeparatedByString:@"?"];
            // 方法名 methodName == sendMessage:number2:
            NSString *methodName = [[subpaths firstObject] stringByReplacingOccurrencesOfString:@"_" withString:@":"];
            // 参数  200&300
            NSArray *params = nil;
            if (subpaths.count == 2) {
                params = [[subpaths lastObject] componentsSeparatedByString:@"&"];
            }
            // 调用
            [self performSelector:NSSelectorFromString(methodName) withObjects:params];
            
            return NO;
        }
        
        NSLog(@"想加载其他请求,不是想调用OC的方法");
        
        return YES;
    }
    

    相关文章

      网友评论

          本文标题:OC关于js相关

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