使用ViewControllers中iOS 7中的JavaScriptCore从javascript触发目标C方法

use*_*486 8 javascript objective-c ios javascriptcore ios7

我正在webview中加载一个url,其中包含HTML和javascript函数调用.现在我正在研究用户触摸webview中的提交按钮时它应该调用viewController中的任何方法.Webview应该加载url(webview委托)是一种方法,但有任何新的方法来获取知道什么时候webview调用javascript函数应该通知viewcontroller或触发视图控制器中的任何方法.

我不是在寻找这个我们需要的解决方案

 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{

    NSLog(@"passed data from web view : %@",[[request URL] query]);

    if([[[request URL] query] isEqualToString:@"clickedOnLineNo"])
    {
//Do your action here

    }
Run Code Online (Sandbox Code Playgroud)

我们必须从你的javascript方法导航到假URL,比如

window.location = "someLink://yourApp/form_Submitted:param1:param2:param3";  
Run Code Online (Sandbox Code Playgroud)

点击按钮或您需要的操作.

但JavaScriptCore是否有任何新的可能性来实现同样的目标.

Mik*_*ike 21

iOS 7中引入的JavascriptCore框架中的Objective-C接口允许从Javascript调用Objective-C方法.有关这些功能的详细介绍,请参阅Apple开发者网络上的2013 WWDC简介"将JavaScript集成到本机应用程序"会话:https://developer.apple.com/videos/wwdc/2013/?id = 615

它确实在WebView上有一个简短的部分(MacO不是iOS)

下面的示例代码显示了如何实现iOS所需的功能.

- (void)viewDidLoad
{
    [super viewDidLoad];

    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(0,40,320,320)];
    webView.delegate = self;
    [self.view addSubview:webView];
     NSString *pageSource = @"<!DOCTYPE html> <html> <head> </head> <body> <h1>My Mobile App</h1> <p>Please enter the Details</p> <form name=\"feedback\" method=\"post\" action=\"mailto:you@site.com\"> <!-- Form elements will go in here --> </form> <form name=\"inputform\"> <input type=\"button\" onClick=\"submitButton('My Test Parameter')\" value=\"submit\"> </form> </body> </html>";
    [webView loadHTMLString:pageSource baseURL:nil];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    JSContext *context =  [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"]; // Undocumented access
    context[@"submitButton"] = ^(NSString *param1) {
        [self yourObjectiveCMethod:param1];
    };
}

- (void)yourObjectiveCMethod:(NSString *)param1 {
    NSLog(@"User clicked submit. param1=%@", param1);
}
Run Code Online (Sandbox Code Playgroud)

注意事项:

  • 访问UIWebView的JSContext没有记录.已知两种技术(请参阅访问UIWebView的JavaScriptCore引擎).这里使用第一种技术.
  • 你不需要在页面内定义javascript函数"submitButton",你将使用webView的JSContext定义Objective-C中的函数.
  • webview中的页面加载导致其JSContext被替换,因此您应该为UIWebView实现委托,并在-webViewDidFinishLoad的选择器实现中定义Objective-C回调:
  • 我假设你想要将参数传递给这个回调,所以我展示了一个示例参数.虽然上面提到的视频教程(或等效的PDF)没有涉及到这一点,但是查看JSValue.h表明JavascriptCore提供了以下Objective-C和Javascript类型之间的内置转换:

.

  Objective-C type  |   JavaScript type
--------------------+---------------------
        nil         |     undefined
       NSNull       |        null
      NSString      |       string
      NSNumber      |   number, boolean
    NSDictionary    |   Object object
      NSArray       |    Array object
       NSDate       |     Date object
      NSBlock *     |   Function object *
         id **      |   Wrapper object **
       Class ***    | Constructor object ***

* Instances of NSBlock with supported arguments types will be presented to
JavaScript as a callable Function object. For more information on supported
argument types see JSExport.h. If a JavaScript Function originating from an
Objective-C block is converted back to an Objective-C object the block will
be returned. All other JavaScript functions will be converted in the same
manner as a JavaScript object of type Object.

** For Objective-C instances that do not derive from the set of types listed
above, a wrapper object to provide a retaining handle to the Objective-C
instance from JavaScript. For more information on these wrapper objects, see
JSExport.h. When a JavaScript wrapper object is converted back to Objective-C
the Objective-C instance being retained by the wrapper is returned.

*** For Objective-C Class objects a constructor object containing exported
class methods will be returned. See JSExport.h for more information on
constructor objects.
Run Code Online (Sandbox Code Playgroud)