Как вызвать Objective-C из Javascript?
У меня есть WebView, и я хочу вызвать представление в Objective-C из JavaScript. Кто-нибудь знает, как я могу это сделать?
У меня этот код в моем ViewController:
- (BOOL)webView:(UIWebView *)webView2
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:@":"];
if ([components count] > 1 &&
[(NSString *)[components objectAtIndex:0] isEqualToString:@"myapp"]) {
if([(NSString *)[components objectAtIndex:1] isEqualToString:@"myfunction"])
{
NSLog([components objectAtIndex:2]); [[Airship shared] displayStoreFront]; //<- This is the code to open the Store
NSLog([components objectAtIndex:3]); // param2
// Call your method in Objective-C method using the above...
}
return NO;
}
return YES; // Return YES to make sure regular navigation works as expected.
}
И в Javascript:
function store(event)
{
document.location = "myapp:" + "myfunction:" + param1 + ":" + param2;
}
Но ничего не происходит.
Ответы
Ответ 1
Стандартным обходным решением для UIWebView
является установка UIWebViewDelegate
и реализация метода webView:shouldStartLoadWithRequest:navigationType:
. В своем JavaScript-коде перейдите к некоторому фальшивому URL-адресу, который кодирует информацию, которую вы хотите передать в ваше приложение, например:
window.location = "fake://myApp/something_happened:param1:param2:param3";
В своем методе делегата найдите эти поддельные URL-адреса, извлеките необходимую информацию, выполните любые действия и верните NO
, чтобы отменить навигацию. Лучше всего, если вы отложите длительную обработку, используя некоторый вкус performSelector
.
Ответ 2
Метод window.location вызова объекта c из JS не рекомендуется. Один из примеров проблем: если вы делаете два последовательных последовательных вызова, один игнорируется (поскольку вы не можете быстро изменить местоположение) - попробуйте сами..
Я рекомендую следующий альтернативный подход:
function execute(url)
{
var iframe = document.createElement("IFRAME");
iframe.setAttribute("src", url);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
Вы вызываете функцию execute
несколько раз, и поскольку каждый вызов выполняется в своем собственном iframe, они не должны игнорироваться при быстром вызове.
Кредиты этого парня.
Ответ 3
Obliviux,
Ваш код кажется идеальным.
Причиной проблемы является то, что вы должны были пропустить карту для делегирования.
Либо
- Подключите делегат webView к владельцу файла в файле .xib.
или
- Используйте
webView.delegate = self;
в viewDidLoad
.
Спасибо
Ответ 4
Как и люди, упомянутые здесь, вы должны использовать метод webView: shouldStartLoadWithRequest: navigationType: из UIWebviewDelegate.
Этот api http://code.google.com/p/jsbridge-to-cocoa/ делает это за вас. Это очень легкий вес. Вы можете передавать изображения, строки и массивы с javascript на objective-C.
Ответ 5
У меня возникла проблема с этим подходом: я хотел отправить несколько сообщений на устройство iphone, но казалось, что они были "перекрыты", поскольку они не могли обрабатывать все из них последовательно.
Пример: при выполнении этого кода:
window.location = "app://action/foo";
window.location = "app://action/bar";
Действие foo
никогда не выполнялось.
Мне нужно было сделать следующее:
waitingForMessage = false;
function MsgProcessed(){
waitingForMessage = false;
}
function SyncLaunchURL(url){
if (waitingForMessage){
setTimeout(function(){SyncLaunchURL(url)},100);
}else{
window.location = url
waitingForMessage = true;
}
}
SyncLaunchURL("app://action/foo");
SyncLaunchURL("app://action/bar");
При таком подходе iphone должен вызвать MsgProcessed() после обработки вызова. Этот способ работает для меня, и, возможно, помогает кому-то с той же проблемой!
Ответ 6
Предполагая, что вы делаете приложение, вы можете посмотреть, как PhoneGap реализует это (или даже использует его). Это библиотека, которая поддерживает обратную связь между JS и OBJ-C. Существуют и другие библиотеки и решения.
Если вы говорите о веб-приложении (что-то пользователь получает от Mobile Safari), вы не можете добраться до Objective-C оттуда.
Ответ 7
Проверьте это - понимание ответов XMLHttpRequest с использованием этой функции (или других javascript)?, используя объектив C для вызова функции ajax js и получив ответ после нее вы знаете, что трюк заключается в том, что веб-просмотр будет срабатывать при изменении местоположения в javascript, чтобы вы могли проверить местоположение, чтобы узнать его свой javascript-вызов или реальный запрос.
Ответ 8
Хотя сейчас это очень старый вопрос, он продолжает возвращаться Google, и сейчас есть хороший ответ: неофициальный протокол WebScripting. Это позволяет вам выставить объектный объект C в Javascript.
http://developer.apple.com/library/safari/documentation/appleapplications/Conceptual/SafariJSProgTopics/Tasks/ObjCFromJavaScript.html#//apple_ref/doc/uid/30001215-BBCBFJCD