Communication between iOS's native app and webpage's javascript - javascript

I have a webpage loaded in a UIWebView, and a javascript function of the page needs to data from native iOs app, a NSString. How can a Js function access the data in native app?
Thanks,
lvreiny

You can execute JavaScript in your UIWebView from Obj-C. Simply call [webView stringByEvaluatingJavaScriptFromString:#"myJavaScript"];.
I could imagine a setup like this:
Webpage
<html>
<head>
<script type="text/javascript">
function callmeFromObjC(para1) {
// do something
alert(para1);
}
</script>
</head>
<body>
</body>
</html>
Objective-C
NSString *myParameter = #"myParameter";
[webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"callmeFromObjC('%#')", myParameter]];

With WebViewJavaScriptBridge you can achieve two way communication between javaScript and iOS.
Check this link below for WebViewJavaScriptBridge .
I used this bridge for one of my application for communication between iOS and JS and also vice versa.
https://github.com/marcuswestin/WebViewJavascriptBridge.

I created an iOS/JS library to help make this easier -- that is, communication in both directions using similar methods. You can check it out here: https://github.com/tcoulter/jockeyjs

Let the javascript load a custom URL, which your app intercepts. It than can parse it, prepare the data and pass it on to your webpage via stringByEvaluatingJavaScriptFromString:.

[webView loadHTMLString:#"<script src=\"filename.js\"></script>"
baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] resourcePath]]];
NSString *result = [webView stringByEvaluatingJavaScriptFromString:#"function(parameter)"];
Give feedback to iOS
window.location = customprefix://function/parameter=value
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
if ([[URL scheme] isEqualToString:#"customprefix"]) {
// handle function name and paramters
}
}
I also wrote a guide on how to call and handle different javascript functions from within iOS.
http://www.dplusmpage.com/2012/07/20/execute-javascript-on-ios/

Sample code for this is available here,you can check it....very usefull
http://ramkulkarni.com/blog/framework-for-interacting-with-embedded-webview-in-ios-application/

Related

I would like to export the contents of ios web view as html

I am writing an app for ios to extract information from a webpage, however, the relevant pieces on the page are built by javascript. So when it is loaded by webview, the javascript is executed and the information displays no problem. If I try to load the page into a string by using the following method, the javascript is loaded, but not actually executed, therefore the string has no useful data in it.
NSData *urlData = [NSData dataWithContentsOfURL:[NSURL URLWithString:fullURL]];
NSString *responseString = [[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding];
Is there another way besides loading the page into webview and exporting it from there? If not, how do you do that?
I'm not sure if there's another way outside of letting the UIWebView execute the JS and render the page, but if you do end up going this route, you could just grab the HTML of the whole page and pass that to the native end like so:
[dummyWebView stringByEvaluatingJavaScriptFromString:#"document.getElementsByTagName('html')[0].outerHTML;"];
Listening to the window.load event might be better to know when the page has finished going through all the JS
Good luck!
You set delegate to webView: self.webView.delegate = self; and implement UIWebViewDelegate:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
NSString *html = [webView stringByEvaluatingJavaScriptFromString:#"document.documentElement.outerHTML"];
NSLog(#"html1 = %#", html);
// or use
NSString *html2 = [webView stringByEvaluatingJavaScriptFromString:#"document.body.innerHTML"];
NSLog(#"html2 = %#", html2);
}

Capture (and prevent) alert() modal in UIWebView [duplicate]

<script language="javascript">
alert("Hell! UIWebView!");
</script>
I can see the alert message inside my UIWebView but can I handle this situation?
Update:
I'm loading a web-page into my UIWebView:
- (void)login {
NSString *requestText = [[NSString alloc] initWithFormat: #"%#?user=%#&password=%#", DEFAULT_URL, user.name, user.password]; // YES, I'm using GET request to send password :)
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestText]];
[webView loadRequest:request];
}
The target page contain a JS. If user name or password is incorrect this JS show alert.
I have not any access to its sources.
I want to handle it inside my UIWebViewDelegate.
A better solution to this problem is to create a Category for UIWebView for the method
webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:
So that you can handle the alert event in any way that you'd like. I did this because I don't like the default behavior of UIWebView when it puts the filename of the source in the UIAlertView title. The Category looks something like this,
#interface UIWebView (JavaScriptAlert)
- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame;
#end
#implementation UIWebView (JavaScriptAlert)
- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(WebFrame *)frame {
UIAlertView* dialogue = [[UIAlertView alloc] initWithTitle:nil message:message delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil];
[dialogue show];
[dialogue autorelease];
}
#end
This seems to do it:
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
JSContext *ctx = [webView valueForKeyPath:#"documentView.webView.mainFrame.javaScriptContext"];
ctx[#"window"][#"alert"] = ^(JSValue *message) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"JavaScript Alert" message:[message toString] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
};
}
Note: only tested on iOS 8.
If by "contain a flash" you mean the page you're loading into your web view has an Adobe Flash movie in it, you're out of luck, I'm afraid. Mobile Safari doesn't support Flash, and most likely never will.
In the general case, if you want JavaScript running in a web view to communicate with the native app hosting it, you can load fake URLs (for example: "myapp://alert?The+text+of+the+alert+goes+here."). That will trigger the webView:shouldStartLoadWithRequest:navigationType: delegate method. In that method, inspect the request, and if the URL being loaded is one of these internal communications, trigger the appropriate action in your app, and return NO.

iOS: call obj-c methods using javascript in a UIWebview

I am writing a function that collaborates with a JS web page. I use UIWebView to contain the webpage and then situation has become complicated when I want the web page to communicate with my app.
Calling a javascript function in UIWebView is easy by using the – stringByEvaluatingJavaScriptFromString: method
But is there any easier way to call an obj-c function in the web page, using javascript? I tried using the UIWebView delegate method, but I think it's too hacky.
Any advice?
I guess using delegate is the only (one or two) methodology you can use in iOS WebView. But there are several wrappers that may help you easy out.
EasyJSWebView - This replicates the development experience as in Android. In Android, you can simply use the addJavascriptInterface() method in WebView to bridge the Javascript to Java. EasyJSWebView provides both sync-style and async-style for getting the return value from Objective-C methods.
WebViewJavascriptBridge - The code may look a little bit like socket programming. You can pass data to and fro between the "server" in Objective-C and the "client" in Javascript.
GAJavaScript - This may provide a better DOM manipulation experience.
Take a look at all of them and choose one that fits your need.
Yes it does feel hacky and is a little laggy but you need to do it with the UIWebViewDelegate
function init()
{
$('input').on('click', function(e) { answerBoxShouldBeginEditing(e); });
}
function answerBoxShouldBeginEditing(e)
{
var object = e.toElement;
var answer = $(object).attr('name');
var request = 'engine:' + answer;
var iframe = document.createElement('IFRAME');
iframe.setAttribute('src', request);
document.documentElement.appendChild(iframe);
iframe.parentNode.removeChild(iframe);
iframe = null;
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *requestString = [[request URL] absoluteString];
if ([requestString hasPrefix:#"engine:"]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Hello" message:nil delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return NO;
}
return YES;
}
If you are considering to upgrade to WKWebView, XWebView may be the best solution.

Can you call a javascript function from native code (not in a callback) using PhoneGap and iOS?

I'm hoping to be able to use PhoneGap for my app. I will have to build a custom protocol/plugin so that I can call Native methods from the Javascript. I know you can call a success function in the Javascript when the native code returns.
What I need to be able to do is call a javascript function from the native code. Basically the app will connect to an OSX companion app over local network and when the OSX app send data to the iOS app it is processed in an Objective C method, I need to be able to send the result into the PhoneGap/javascript and do something with it in the WebView.
Is this possible? I have only been able to find information about calling native from javascript not the other way around.
Thanks,
Thomas
Using the code from Answer below here:
MyPhoneGapPlugin.m
- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(#"Connected To %#:%i.", host, port);
NSString* jsString = [NSString stringWithFormat:#"alert(connected to: %#);", host];
[theWebView stringByEvaluatingJavaScriptFromString:jsString];
[self readWithTag:2];
}
Giving me the error 'Unknown receiver 'theWebView' did you mean 'UIWebView'?
UPDATE: Found the answer: using the phonegap helper I can write something like this...
[super writeJavascript:#"alert('connected');"];
You can easily call JavaScript from native code with a UIWebView:
[webView stringByEvaluatingJavaScriptFromString:#"myJSFunction()"];
To use the result of a function somewhere as an arg to a JS function:
NSString *stringData = getStringData(); // however you get it
[webView stringByEvaluatingJavaScriptFromString:
[NSString stringWithFormat:#"myJSFunction(%#)", stringData]];
Found the PhoneGap helper to accomplish this... Write javascript to the webView using:
[super writeJavascript:#"alert('it works');"];
You should try this,
[webView stringByEvaluatingJavaScriptFromString:#"sendSelectedDate()"];
Will this work for you?
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/DisplayWebContent/Tasks/JavaScriptFromObjC.html
Taken from this page:
You can also call JavaScript functions with arguments. Assume that you have written a JavaScript function which looks like this:
function addImage(image, width, height) { ... }
Its purpose is to add an image to a web page. It is called with three arguments: image, the URL of the image; width, the screen width of the image; and height, the screen height of the image. You can call this method one of two ways from Objective-C. The first creates the array of arguments prior to using the WebScriptObject bridge:
id win = [webView windowScriptObject];
NSArray *args = [NSArray arrayWithObjects:
#"sample_graphic.jpg",
[NSNumber numberWithInt:320],
[NSNumber numberWithInt:240],
nil];
[win callWebScriptMethod:#"addImage"
withArguments:args];

Calling Javascript in an iOS web app from Objective-C

I am developing a web app that is being displayed in a UIWebView. The app is loaded locally, i.e, not from a web server. I am communicating from Javascript to ObjC via the shouldStartLoadWithRequest: method in the UIWebViewDelegate protocol.
The last thing I need is to be able to call Javascript functions from ObjC without any page reloads. I hope this is possible.
Well, you can call
-[UIWebView stringByEvaluatingJavaScriptFromString:]
whenever you like, not just in response to a delegate method.
You can call any javascript function in your webview by simply using the stringByEvaluatingJavaScriptFromString method on your webview after you've loaded the webview:
[self.myWebView stringByEvaluatingJavaScriptFromString:#"myJavaScriptFunction(123.0)"];
You don't need to reload the webview to send this message (just don't release the webview before you're done).
Could't you just do this by doing a "loadRequest", and passing it an NSURL with contents like like:
javascript:myFunction("MyParameter");
It should call your function, but not reload the page.
One can use JavaScriptCore framework to run JavaScript code from Objective-C.
#import <JavaScriptCore/JavaScriptCore.h>
...
JSContext *context = [[JSContext alloc] init];
[context evaluateScript: #"function greet(name){ return 'Hello, ' + name; }"];
JSValue *function = context[#"greet"];
JSValue* result = [function callWithArguments:#[#"World"]];
[result toString]; // -> Hello, World
Here is a demo:
https://github.com/evgenyneu/ios-javascriptcore-demo

Categories

Resources