I'm trying to fire Javascript to a WebView when the home button is pressed.
So far, a simple
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSLog(#"webView finishing loading");
NSString *title = [webView stringByEvaluatingJavaScriptFromString:#"document.title"];
NSLog(#"result = %#", title);
}
works perfectly.
But the same code from
- (void)applicationWillResignActive:(UIApplication *)application
does nothing and title string is (null).
Related
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.
I have create an app, which works fine. The only thing i need is to pass the alerts from uiwebview to my iOS app.
i have this alert on my uiwebview
<div id="alerts" class="alerts">
<p class="alert-red">ok. come back again tomorrow, not now.</p>
i want this alert to transfer into my app and make it into an uialertview
UIAlertView *errr = [[UIAlertView alloc]initWithTitle:#"nil" message:#"ok. come back again tomorrow, not now." delegate:self cancelButtonTitle:#"Ok, Got it" otherButtonTitles:nil, nil];
[errr show];
any idea how to achieve this result? do i need NSNotification to listen when this alert show up on uiwebview?
I tried something like this
NSString *theTitle=[webView stringByEvaluatingJavaScriptFromString:#"var targetDiv = document.getElementById('alerts').getElementsByClassName('alert-red')[0];"];
NSLog(#"%#",theTitle);
So I can try to retrieve that message from "alert-red" but doesn't work.
I'm new to javascript and html
This is the typical workaround used to solve this problem:
in your webpage when you want to show this alert, run this javascript code:
window.location = 'custom_action';
then in objc implement shouldStartLoadWithRequest on your controller (and set yourWebView.delegate = yourController)
-(BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
// detect when the webview switches to this custom url
if([[[request URL] absoluteString] isEqualToString: #"custom_action"]) {
UIAlertView *errr = [[UIAlertView alloc]initWithTitle:#"nil" message:#"ok. come back again tomorrow, not now." delegate:self cancelButtonTitle:#"Ok, Got it" otherButtonTitles:nil, nil];
[errr show];
// this prevents the webview from actually trying to load the custom url
return NO;
}
// allow the url to load if its not your custom url
return YES;
}
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.
<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'm developing an iOS app with a UIWebView instance.
If the user touches an object in a webpage shown by the web view, how can I extract metadata regarding the object touched (such as an "id" for an HTML element) over in Objective C land?
[I'm not interested in whether the web view was touched or not, I'm only interested in what part of the page was touched and being able to act on this.]
You probably need to do this in JavaScript land. In your webview set up some javascript to monitor the click (e.g. element.onclick = function() { ... }, or use jQuery if that's easier).
Now you can call out to the native code in your app by using a made up url and then intercepting it using the webview delegate, e.g.
//in your web page, in javascript
myDiv.onclick = function() { document.location.href = 'http://madeupdomain/' + this.id};
//webview delegate in cocoa
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSURL *URL = [request URL];
NSString *host = URL.host;
if ([host isEqualToString:#"madeupdomain"])
{
NSString *theDivID = URL.path;
//now do something based on the div id value
return NO;
}
return YES;
}
This is essentially how frameworks like PhoneGap communicate between the webview and the native code.