OCとJSのインタラクティブな呼び出しの神秘的なベールを明らかにします.

8147 ワード

まずOCではJSと対話し、先にヘッダファイル#import を導入し、スクリーンサイズのwebViewを作成してHTMLをレンダリングするページを作成します.
    NSString *path = [[NSBundle mainBundle] bundlePath];
    NSURL *baseURL = [NSURL fileURLWithPath:path];
    NSString * htmlPath = [[NSBundle mainBundle] pathForResource:@"index"
                                                          ofType:@"html"];
    NSString * htmlCont = [NSString stringWithContentsOfFile:htmlPath
                                                    encoding:NSUTF8StringEncoding
                                                       error:nil];
    self.webView.delegate = self;
    [self.webView loadHTMLString: htmlCont baseURL:baseURL];
次に粗悪なHTMLコードを書きました.以下の通りです.index.html


   
       
           OC JS  
           
           
               function secondClick(index) {
                   wgb_iOSHookJSButtonClick(index);
               }
           
           function showAlert(message) {
               alert('WGB__OC  JS      ' + message);
           }
           
           function wgb_testCallOCKeyboard() {
               jsCallOCAlertKeyboard();
           }
           
           function wgb_endEidting() {
               wgb_keyboardResignFirstResponder();
           }
           
           var getIOSImage = function () { ///   
               var parameter = {'title': 'JS OC', 'describe': '    JS  OC   '};
               //        js       api
               window.iosDelegate.getImage(JSON.stringify(parameter));//       json      
           }
           
           function getImageFromOC() { ///   
               iOSImageUpLoad();
           }
           
           //     iOS  js   
           function setJSImageWithPath(arguments) {
               ///         
               //var element = document.getElementById('changePhoto');
               //element.src =arguments['urlStringPath'];
               //var iOSParameters =  document.getElementById('iOSParameters');
               // iOSParameters.innerHTML = arguments['iosContent'] + arguments['img'];
               
               ///        
               var element_wgb = document.getElementById('wgb_changePhoto');
               element_wgb.src = arguments['urlStringPath'];
               var parameter_wgb = document.getElementById('wgb_iOSParameters');
               parameter_wgb.innerHTML = arguments['iosContent'] + arguments['img'];
           }
           
               
           
           
           
           
   
   
   
       
       


















![](test.jpg)
以上のコードをブラウザに置いてレンダリングして、いくつかのボタンしか見られません.一つのイメージが破れます.クリックすると第一弾のフレームだけが反応します.他のすべての反応は内在論理が実現しているため、ボタンをクリックしてOCコードをフィードバックしたり呼び出したりします.
1.OCでJSの関数を呼び出します.
一般的にこの場合はJS定義を直接傍受する関数です.
#pragma mark-    ,OC    JS       [JS  OC]
- (void)js_ocCallBack{
    JSContext *js = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    js[@"wgb_iOSHookJSButtonClick"] = ^(){
        NSArray *args = [JSContext currentArguments];
        NSString *arg = [args.firstObject toString];
        NSLog(@"arg = %@",arg);
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"JS  OC,JS       " message: arg delegate:self cancelButtonTitle:@"  " otherButtonTitles:nil];
            [alertView show];
        });
    };
}

//JS        :
function secondClick(index) {
                    wgb_iOSHookJSButtonClick(index);
                }
///  `button` `onclick`   `secondClick(1)` ,`secondClick(2)` `secondClick(3)`   ,  JS index,  OC   `wgb_iOSHookJSButtonClick `,        JS    index,         .

2.JSでOCを呼び出す関数
例えばJSは原生のキーボードやカメラのアルバムなどを呼び出します.
#pragma mark-     
- (void)alertKeyboard{
    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    context[@"jsCallOCAlertKeyboard"] = ^(){ 
///               ok 
    dispatch_async(dispatch_get_main_queue(), ^{
        UITextField *textfiled = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, 100, 10)];
        [self.view addSubview: textfiled];
        textfiled.hidden = YES;
        [textfiled becomeFirstResponder];
      });
    };
}

#pragma mark-       
- (void)wgb_keyboardResignFirstResponder{
    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    context[@"wgb_keyboardResignFirstResponder"] = ^(){
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.view endEditing:YES];
        });
    };
}

#pragma mark-             /       
- (void)js_callOCPhotoPickerImage{
    JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    context[@"iOSImageUpLoad"] = ^(){
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.manager quickAlertSheetPickerImage];
        });
    };
}

これらの関数はホームページのロードが完了したら直接に呼び出すことができます.
//         js   
- (void)webViewDidFinishLoad:(UIWebView *)webView{
   JSContext *jsContext = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    jsContext[@"iosDelegate"] = self;
    jsContext.exceptionHandler = ^(JSContext *context, JSValue *exception){
        context.exception = exception;
        NSLog(@"   self.jsContext     :%@",exception);
    };
}


- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
    [self js_ocCallBack];
    [self oc_jsCallBack];
    [self alertKeyboard];
    [self wgb_keyboardResignFirstResponder];
    [self js_callOCPhotoPickerImage]; 
    return YES;
}
Github Demoアドレス