Триггер целевой метод 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.