Como chamar o Objective-C de Javascript?

Eu tenho um WebView, e eu quero chamar uma visão em Objective-C do JavaScript. Alguém sabe como posso fazer isso?


Eu tenho este código no meu 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. } 

E em Javascript:

 function store(event) { document.location = "myapp:" + "myfunction:" + param1 + ":" + param2; } 

Mas nada acontece.

A solução padrão para o UIWebView é definir um UIWebViewDelegate e implementar o método webView:shouldStartLoadWithRequest:navigationType: Em seu código JavaScript, acesse alguns URLs falsos que codificam as informações que você deseja transmitir para seu aplicativo, por exemplo:

 window.location = "fake://myApp/something_happened:param1:param2:param3"; 

Em seu método delegado, procure essas URLs falsas, extraia as informações necessárias, execute a ação apropriada e retorne NO para cancelar a navegação. Provavelmente é melhor se você adiar qualquer processamento demorado usando algum sabor do performSelector .

O método window.location de chamar o objective c de JS não é recomendado. Um exemplo de problemas: se você fizer duas chamadas consecutivas imediatas, uma é ignorada (desde que você não pode mudar de local muito rapidamente) – tente você mesmo.

Eu recomendo a seguinte abordagem alternativa:

 function execute(url) { var iframe = document.createElement("IFRAME"); iframe.setAttribute("src", url); document.documentElement.appendChild(iframe); iframe.parentNode.removeChild(iframe); iframe = null; } 

Você chama a function execute repetidamente e, como cada chamada é executada em seu próprio iframe, elas não devem ser ignoradas quando chamadas rapidamente.

Créditos para esse cara .

Obliviux,

Seu código parece ser perfeito.

A razão para o problema é que você deve ter perdido para mapear o delegado.

Ou

  1. Conecte o delegado do webView ao proprietário do arquivo no arquivo .xib

ou

  1. Use webView.delegate = self;

no seu viewDidLoad .

obrigado

Como as pessoas disseram aqui, você tem que usar o método webView: shouldStartLoadWithRequest: navigationType: from the UIWebviewDelegate.

Este api http://code.google.com/p/jsbridge-to-cocoa/ faz isso por você. É muito leve. Você pode passar imagens, seqüências de caracteres e matrizes de javascript para objective-C.

Eu tive um problema com essa abordagem: eu queria enviar várias mensagens para o dispositivo iphone, mas parecia que elas estavam “sobrepostas”, já que não podiam processar todas elas sequencialmente.

Exemplo: ao executar este código:

 window.location = "app://action/foo"; window.location = "app://action/bar"; 

A ação foo nunca foi executada.

O que eu tive que fazer foi o seguinte:

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

Com essa abordagem, o iPhone precisa chamar o MsgProcessed () após processar a chamada. Desta forma funciona para mim e talvez ajude alguém com o mesmo problema!

Supondo que você esteja fazendo um aplicativo, você pode ver como o PhoneGap implementa isso (ou até mesmo usá-lo). É uma biblioteca que suporta a comunicação de ida e volta entre JS e OBJ-C. Existem outras bibliotecas e soluções também.

Se você está falando de um aplicativo da web (algo que o usuário acessa do Mobile Safari), você não pode acessar o Objective-C de lá.

Marque esta – entendendo as respostas XMLHttpRequest usando esta (ou outra function javascript)? , ele está usando o objective C para chamar ajax js function e obter a resposta depois que é feito, você sabe o truque é que webview será acionado quando você alterar o local em javascript, para que você possa verificar o local para saber sua chamada javascript ou o pedido real.

Embora essa seja uma pergunta muito antiga agora, ela continua sendo retornada pelo Google e agora há uma boa resposta: o protocolo informal do WebScripting. Ele permite que você exponha um object objective C para JavaScript.

http://developer.apple.com/library/safari/documentation/appleapplications/Conceptual/SafariJSProgTopics/Tasks/ObjCFromJavaScript.html#//apple_ref/doc/uid/30001215-BBCBFJCD