【问题标题】:Trigger objective C method from javascript using JavaScriptCore in iOS 7 in ViewControllers在 ViewControllers 中使用 iOS 7 中的 JavaScriptCore 从 javascript 触发目标 C 方法
【发布时间】:2014-03-04 18:28:27
【问题描述】:

我正在 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 是否有任何新的可能性来实现相同的目标。

【问题讨论】:

  • 这是我正在加载的示例 HTML 页面

    My Mobile App

    请输入详细信息

    form>
  • 您可以创建一个phonegap应用程序,您可以在webview的地方调用该应用程序。将执行您想要的相同的excatly
  • 感谢 Rahul,但 Apple 最近在 iOS 7 中引入的 JavaScriptCore 框架不可能实现。
  • 感谢 Dark,但该链接具有在 Web 视图中调用假网址的相同方法

标签: javascript ios objective-c ios7 javascriptcore


【解决方案1】:

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);
}

注意事项:

  • 没有记录访问 UIWebView 的 JSContext。两种技术是已知的(参见Access the JavaScriptCore engine of a UIWebView)。这里使用第一种技术。
  • 您不需要在页面内定义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.

【讨论】:

  • JS 上下文的工作方式类似于 [webView stringByEvaluatingJavaScriptFromString:@"document.getElementById('lastname').value;"];但它提供的远不止这些。感谢迈克的解释。
  • @TMacGyver - Apple 尚未正式记录他们在 iOS7 发布时添加到 JavaScriptCore 框架的 Objective-C 扩展,因此对于这两种已知技术中的任何一种,您的里程可能会有所不同。我没有使用这两种技术提交应用程序,但是有报告称使用第一种技术成功提交了 SO(如上例中所用)。请参阅 mprudhom 对 stackoverflow.com/questions/18920536/… 的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-13
  • 1970-01-01
  • 2014-05-16
  • 1970-01-01
相关资源
最近更新 更多