JavaScriptとObjective-cは相互作用します.

4383 ワード

JavaScriptとObjective-cは相互作用します.
  • 現在の開発は元の開発ではなく、多くのAPPの中で、多くの活動ページ、またはテーマページがH 5のページ
  • を採用しています.
  • このような方法の利点は、これらのページは簡単に変更できます.新しいAPPをAppStoreに提出して審査しなくてもいいです.
  • では、jsとocの相互作用は、js呼び出しのoc方法、oc呼び出しのjs方法の2つのケースに分けられます.
    OC呼び出しJS
  • stringByEvaluatingJavaScriptFromString方法でjs文
  • を実行する.
    //   JS  
    [webView stringByEvaluatingJavaScriptFromString:@"alert(100);"];
    
    //   JS         
    NSString *title = [webView stringByEvaluatingJavaScriptFromString:@"document.title;"];
    
    //   JS  
    [webView stringByEvaluatingJavaScriptFromString:@"login();"];
    
    JS呼び出しOC
  • このようなモードはちょっと面倒です.つまり、伝達パラメータの問題です.
  • は、パラメータ、1つまたは2つのパラメータを渡さないので、これらの場合は比較的簡単です.
  • ですが、複数のパラメータを伝えたいと思います.
  • 考え方:
  • 1、ウェブページで要求を送信し、OC方法を呼び出したい場合、カスタムプロトコルヘッド
  • が必要となる.
  • 、要求されたアドレスはカスタムが必要です.プロトコルヘッダと方法名とパラメータのスプラインはルールを定義する必要があります.
  • 、UICbViewのプロキシ方法において要求をブロックし、プロトコルヘッド
  • を判断する.
  • 、切り取り方法名とパラメータ
  • パラメータなし
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        // URL:YYHttp://   
        NSString *url = request.URL.absoluteString;
        //       
        NSString *scheme = @"YYHttp://";
        if ([url hasPrefix:scheme]) {
            
            NSString *methodName = [url substringFromIndex:scheme.length];
            [self performSelector:NSSelectorFromString(methodName) withObject:nil];
            return NO;
        }
        return YES;
    }
    
    一つまたは二つのパラメータ
    - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
    {
        // url == YYHttp://sendMessage_number2_?200&300
        NSString *url = request.URL.absoluteString;
        NSString *scheme = @"YYHttp://";
        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
            NSString *param = [subpaths lastObject];
            NSArray *subparams = nil;
            if (subpaths.count == 2 || [param containsString:@"&"]) {
                subparams = [param componentsSeparatedByString:@"&"];
            }
            //      2   
            NSString *firstParam = [subparams firstObject];
            NSString *secondParam = subparams.count <= 1 ? nil : [subparams lastObject];
            
            [self performSelector:NSSelectorFromString(methodName) withObject:firstParam withObject:secondParam];
            
            return NO;
        }
        return YES;
    }
    
    
    3つ以上のパラメータ
  • このときは、複数のパラメータを転送するためのカスタム方法が必要である
  • .
  • NSInvocation
  • を使用する必要があります.
  • は、この方法が定義されている限り、直接に行列に入ることができる
  • .
  • - (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;
            [invocation setArgument:&object atIndex:i + 2];
        }
        
        //     
        [invocation invoke];
        
        //      
        id returnValue = nil;
        if (signature.methodReturnLength) { //       ,       
            [invocation getReturnValue:&returnValue];
        }
        return returnValue;
    }