I am aware that this question is already posted lot many times. But none of them are helping me to solve my issue. Please consider reading entire question before downvote :-)
So, for I have below lines of code
- (void)viewDidLoad {
[super viewDidLoad];
NSURL * url = [NSURL URLWithString: #"https://www.w3schools.com/code/tryit.asp?filename=FEGU9IV4SAK8"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
self.webView.delegate = self;
[self.webView loadRequest:request];
}
#pragma mark - UIWebView Delegates
- (void) webViewDidFinishLoad:(UIWebView *)webView {
NSString * jsString = [NSString stringWithFormat:#"test()"];
[webView stringByEvaluatingJavaScriptFromString:jsString] ;
//This code is working. Able to prompt "Hello"
// jsString = [NSString stringWithFormat:#"alert('Hello');"];
// [webView stringByEvaluatingJavaScriptFromString:jsString] ;
}
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType;
{
// ignore legit webview requests so they load normally
if (![request.URL.scheme isEqualToString:kSchemeName]) {
return YES;
}
// look at the actionType and do whatever you want here
if ([actionType isEqualToString:kJSActionForPay]) {
//Call objective-c method - Success
}
// make sure to return NO so that your webview doesn't try to load your made-up URL
return NO;
}
So, Far I have tried / understood.
[1] Call JS function only after web view loaded. (used delegate)
[2] Able to prompt "Hello" from
[webView stringByEvaluatingJavaScriptFromString:#"alert('Hello')"] ;
[3] Changes done in HTML side
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1 id="id1">My Heading 1</h1>
<button type="button"
onclick="document.getElementById('id1').style.color = 'red'">
Click Me!</button>
</body>
<script>
function test() {
alert("Started");
}
</script>
</html>
Please help to find out what I am missing in HTML Side ? or In my native Objc?
EDIT 1:
As #Andy suggested, I loaded html from local. Then I am able to call JS function "test()"
You should not use the w3schools editor to be the source html for your project. The url you tried to visit not only contains your content but also the scripts used by w3schools. Instead, you should put your html file on your own server or a .html file inside your project. Then, you can call the test() method.
Related
I have dashboard.html page and DashboardController.js is associated with dashboard.html. I am loading page in UIWebview and now I want to call a angularjs function from DashboardController.js from uiwebview. It does not get called.
Below is the code which I am trying in iOS
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
NSURL *url = [request URL];
NSLog(#"URL:%#",url);
if (![Utility isInternetAvailable]) {
return FALSE;
}
NSString *jsCallBack = [NSString stringWithFormat:#"DashboardController.test()"];
NSString *response = [webView stringByEvaluatingJavaScriptFromString:jsCallBack];
NSLog(#"%#",response);
return YES; // Return YES to make sure regular navigation works as expected.
}
I also tried without Controller reference after making sure that dashboard.html has been loaded inside uiwebview.
NSString *jsCallBack = [NSString stringWithFormat:#"test()"];
While test() is js function inside my DashboardController.js scope.
function test (){
alert('sendCredentialsToNativeApp');
}
Thanks in advance.
This test() method should be called if you have defined without controller reference in the controller JS. However, this will only be available after page readystate because you cannot call any method from the controller until its loaded completely.
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);
}
<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.
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/
In a MacOS X application, I create a Window containing a WebView.
The WebView is initialized on a html page that contains an anchor:
Go To Google.
I would like to click on that link from another class.
It seems clear that a simple javascript code would do the trick: document.getElementById("myLink").click();
So, I wrote that small objective-c code that should do it:
NSString *cmd = #"document.getElementById(\"myLink\").click();";
id result = [[attachedWebView windowScriptObject] evaluateWebScript:cmd];
if ([result isMemberOfClass:[WebUndefined class]]) {
NSLog(#"evaluation of <%#> returned WebUndefined", cmd)
But I can't make it work.
If anybody has an idea, that would really help.
I think it is nothing todo with webview, but just your javascript.
Does it work if you try it in Safari's console? I wouldn't expect it to as you can only click() input elements (buttons) reliably cross-browser. A JQuery click() should work tho.
see How do I programmatically click a link with javascript?
So here is the solution I used.
Created a file: WebAgent.js containing the following code:
function myClick(id) {
var fireOnThis = document.getElementById(id);
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( 'click', true, true );
fireOnThis.dispatchEvent(evObj);
}
And the following code in my objective-c class
// load cmd.js
NSString *path = #"/code/testagent/WebAgent/WebAgent/WebAgent.js";
NSString *jsCode = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
[[self attachedWebView ]stringByEvaluatingJavaScriptFromString:jsCode];
//do the click
NSString * anchorId = #"myId";
NSString *call = [NSString stringWithFormat:#"WebAgent_click('%#')",anchorId];
[[self attachedWebView] stringByEvaluatingJavaScriptFromString:call];
NB: I used this solution to have the JS code in a specific file, as I expect to have more JS code in the future.
Thanks for your help.