Detect window.open() from UIWebView - iphone

Short question: Is it possible to detect window.open() in a UIWebView using the UIWebViewDelegate or is there another way to reach this? I need the the url when a window.open()-Event is fired to show a UIAlertView.

You need to overwrite window.open() using JavaScript:
[webView stringByEvaluatingJavaScriptFromString:#"window.open = function (open) { return function (url, name, features) { window.location.href = url; return window; }; } (window.open);"];

Try using this delegate methods. Hope this helps.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
- (void)webViewDidStartLoad:(UIWebView *)webView;

Related

shouldStartLoadWithRequest doesn't run stringByEvaluatingJavaScriptFromString method

I am trying to run the code below in webview's shouldStartLoadWithRequest delegate method but it doesn't make any changes.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
NSLog(#"webView shouldStartLoadingWithRequest");
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.execCommand('bold', false,null)"]];
return TRUE;
}
There is no error, it prints the NSLog and everything in the method works great except "stringByEvaluatingJavaScriptFromString" method.
But if I try to make text bold in another function, for example an IBAction method, works fine.
-(IBAction)boldClick:(id)sender
{
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.execCommand('bold', false,null)"]];
}
Actually, this is my company's special application and this UIWebView will not show the web pages. I am using it to show some custom HTML pages.
I need to make everything in "shouldStartLoadWithRequest" because I am trying to run an objective-c method from javascript.
UPDATE
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType{
// Break apart request URL
NSString *requestString = [[request URL] absoluteString];
NSArray *components = [requestString componentsSeparatedByString:#":"];
// Check for your protocol
if ([components count]==3)
{
[self makeBoldText];
return NO;
}
else
{
return TRUE;
}
}
-(void)makeBoldText
{
[self.webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:#"document.execCommand('bold', false,null)"]];
}
The doc says that method webView:shouldStartLoadWithRequest: is sent before a web view begins loading a frame. After you return YES in this method, web view starts loading a request. So any javascript you execute will have no effect, because a new page will be loaded after your JS call.
You can probably use webViewDidFinishLoad: method to execute javascript after page finishes to load. Or if you want to trigger JS by clicking on a link, you can use shouldStartLoadWithRequest but return NO from it.

prevent to refresh a web page

I have a problem : I have a simple application with a menu and a link that goes to the web page. The web page is: "soundcloud" it is a site that generates music. for example, if I put on a play music and I return to the menu of my application, the music is still running when I return to the web page, the music is still here but the page is returned to zero. and I want to prevent this. sorry for my english I'm french –
Cordialy
Davy
EDIT: This is assuming that the page is contained in a UIWebView within your app. If it's a link that opens in Safari, I don't believe you are going to be able to block navigation in Safari...but in your own web view you can.
Set the controlling class (whichever view controller contains your web view) as a UIWebView delegate. Then, when you implement the delegate protocol:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{ //If you want to block ANY navigation
return NO;
//If you want to block refreshes but allow other navigation
if (navigationType == UIWebViewNavigationTypeReload) return NO;
{
Inspired by #Reid Belton's answer
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
//to prevent reloading html if it is already loaded
if( isHTMLLoaded)
{
return NO;
}else{
isHTMLLoaded = YES;
return YES;
}
}

Check if NSURLRequest target is "_blank"?

I'm listening for url loads from my UIWebView. Is there a way to check if the request has a target of "_blank"?:
- (BOOL) webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
{
if ([request targetIs:#"_blank"]) {
// do something.
}
}
Don't know about iOS, but as for OS X, it works perfectly, if you use policy delegate. I've placed my answer in this thread, mentioned by Russ above.
Maybe you can use [UIWebView -request] to get the NSURLRequest, and use [NSURLRequest URL] to check if the url contains anything you want.

Can I open an URL(a Facebook page) in a FBDialog or something in FBConnect?

I am struggling to find this. Can I open a URL in a FBDialog or using something in FBConnect. I tried to do it like the following. But it doesn't seem to be working.
FBDialog *dlg = [FBDialog new];
[dlg loadURL:#"http://www.facebook.com/pages/Apple-Inc/137947732957611" get:nil];
I don't even know whether this is possible or not. Can you guys please help me?
There are 2 problem to prevent you from your code. First, when you pass a url to -loadURL:get: method, Facebook iOS SDK rebuild the real url base on yours. So, the url you passed will not get into the webview finally. What you need to do is implementing a method in FBDialog.m like this:
-(void)hackLoadURL:(NSString*)url withDelegate:(id)delegate {
_webView.delegate = delegate;
[_webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:url]]];
}
The second problem is that you need to hack the
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
delegate method and replaced with the one you make implementation. But in order to keep the original Facebook SDK works, you need to add below code to FBDialog.m
_webView.delegate = self;
within -loadURL:get: method, and before this line
[_webView loadRequest:request];
finally, you need to implement
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
yourselves in your class, and use
FBDialog *dlg = [FBDialog new];
[dlg hackLoadURL: yourExpectUrl withDelegate: self];
to do what you wanted.

Use a button on a HTML page to call xcode IBAction

This seems like a strange one. Not even sure if it is possible!!
I have a UIWebView that loads a local html page. On this html page I have a button.
I want to click on the button and then call an IBAction in Xcode.
How would I go about this? Or can you even do this???
Thanks guys,
Stefan.
You can do it by using a custom protocol. In you html file, you can link to something like myProtocol://callSomeAction.
Then on your UIWebViewDelegate (probably your UIViewController) you have to implement the method called:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
(Docs here)
The idea is that on that code, you detect the protocol based on the data in the request parameter. If it is myProtocol, you can call your IBAction and return NO. If it's something else, you fallback to have the web view load the page, and just return YES.
The code would look something like this:
- (BOOL)webView:(UIWebView *)webView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSString* scheme = [[request URL] scheme];
if ([#"myProtocol" isEqual:scheme]) {
// Call your method
return NO;
} else {
return YES;
}
}
Have the button on the HTML page open a custom url such as myapp://buttonclick.
In your web view delegate, implement webView:shouldStartLoadWithRequest:navigationType:. Check whether the request includes your custom URL and if it does, call any Obj-C method you want.
I have similar kind of situation, but its an imageclick , href and handling this method of webview,
- (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener >)listener{
NSString *host = [[request URL] host];
//if (host!=nil)
{
WebNavigationType eActionType = (WebNavigationType)[[actionInformation valueForKey:WebActionNavigationTypeKey] intValue];
NSURL *pOrignalURL;
if(eActionType == WebNavigationTypeLinkClicked)// == [actionInformation valueForKey:WebActionNavigationTypeKey])
{
/* we will handle it */
pOrignalURL = [actionInformation valueForKey:WebActionOriginalURLKey];
NSString *pElementName = [actionInformation valueForKey:WebActionElementKey];
if([[pOrignalURL absoluteString] hasPrefix:#"app:"]){
[listener ignore];
return;
}
}
//[[NSWorkspace sharedWorkspace] openURL:pOrignalURL];
NSArray* urls = [ NSArray arrayWithObject:
[ NSURL URLWithString:[pOrignalURL absoluteString]]];
[[ NSWorkspace sharedWorkspace ]
openURLs:urls
withAppBundleIdentifier:nil
/* use default system bindings */
options:NSWorkspaceLaunchWithoutActivation
additionalEventParamDescriptor:nil
launchIdentifiers:nil ];
/* default behavior */
[listener download];
return;
}
}