Триггер целевой метод C из JavaScript с использованием JavaScriptCore в iOS 7 в ViewControllers

Я загружаю URL-адрес в веб-представлении, которое имеет ниже HTML и вызов функции javascript. Теперь я смотрю, когда пользователь касается кнопки отправки в веб-представлении, он должен вызывать любой метод в viewController. Webview должен загружать url(делегат webview) - это один из подходов, но есть ли новый способ узнать, когда функция javascript вызывается webview, должна сообщить 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

    }

Мы должны перейти к фальшивому URL из вашего метода javascript, например,

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

на нажатие кнопки или ваши необходимые действия.

Но есть ли какая-то новая возможность от JavaScriptCore добиться того же.

1 ответ

Решение

Интерфейс Objective C в платформе JavascriptCore, представленной в iOS 7, позволяет вызывать методы Objective C из Javascript. Чтобы познакомиться с этими функциями, ознакомьтесь с презентацией WWDC 2013 года "Интеграция JavaScript в собственные приложения" в сети разработчиков Apple: 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);
}

Что следует отметить:

  • Доступ к JSContext из UIWebView не документирован. Известны два метода (см. Доступ к движку JavaScriptCore в UIWebView). Первая техника используется здесь.
  • Вам не нужно определять функцию javascript "submitButton" внутри страницы, вы будете определять функцию из Objective-C, используя JSContext веб-представления
  • Загрузка страницы в веб-представлении приводит к замене его JSContext, поэтому вы должны реализовать делегат для UIWebView и определить ваш обратный вызов Objective-C в вашей реализации селектора для -webViewDidFinishLoad:
  • Я предполагал, что вы захотите передать параметры этому обратному вызову, поэтому я показал пример параметра. Хотя это не рассматривается в видеоуроке, упомянутом выше (или в 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.
Другие вопросы по тегам