javascript - 在 ViewControllers 的 iOS 7 中使用 JavaScriptCore 从 javascript 触发 Objective-C 方法

标签 javascript ios objective-c ios7 javascriptcore

我正在 webview 中加载一个 url,它具有以下 HTML 和 javascript 函数调用。现在我正在研究当用户触摸 webview 中的提交按钮时它应该调用 viewController 中的任何方法。 Webview 应该加载 url(webview 委托(delegate))是一种方法,但是是否有任何新方法可以了解 webview 调用 javascript 函数时应该通知 viewcontroller 或触发 View Controller 中的任何方法。

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

 - (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

    }

我们必须从您的 javascript 方法导航到伪造的 URL,例如,

window.location = "someLink://yourApp/form_Submitted:param1:param2:param3";  

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

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

最佳答案

iOS 7 引入的 JavascriptCore 框架中的 Objective-C 接口(interface)允许从 Javascript 调用 Objective-C 方法。有关这些功能的精彩介绍,请查看 Apple 开发人员网络上的 2013 WWDC 介绍“将 JavaScript 集成到 native 应用程序” session :https://developer.apple.com/videos/wwdc/2013/?id=615

它确实有一个关于 WebView 的简短部分(仅限 MacOs 而不是 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);
}

注意事项:

  • 访问 UIWebView 的 JSContext 没有记录。已知两种技术(参见 Access the JavaScriptCore engine of a UIWebView)。这里使用第一种技术。
  • 您不需要在页面内定义 javascript 函数“submitButton”,您将使用 webView 的 JSContext 从 Objective-C 定义该函数
  • webview 中的页面加载会导致其 JSContext 被替换,因此您应该为 UIWebView 实现一个委托(delegate),并在您为 -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.

关于javascript - 在 ViewControllers 的 iOS 7 中使用 JavaScriptCore 从 javascript 触发 Objective-C 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21626137/

相关文章:

javascript - 如何从 FireFox 扩展中的错误获取堆栈跟踪?

javascript - 将数据传递回异步请求的调用函数

javascript - 无法使用 Greasemonkey 单击此超链接

ios - NSURLSession 中的 SSL 证书验证

iphone - 使用 map 缓存模态视图

ios - for循环中的方法只被调用一次?

ios - 从 UITableView 中删除行时以 NSException 类型的未捕获异常终止

javascript - 事件监听器附加到父元素,现在如何将单击的目标冒泡到特定的类名称?

javascript - 无法在 iOS Safari 上更改按钮选择

iOS Swift 检测键盘事件