Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
Hello guys, so in my program I load the iPhone version of the news.google.com website into a WebView. When I try to click a link, nothing happens. The reason for this is because it is a java script that asks to open a new window. I have no idea how to implement this into my code. I would like the program to open the link in my program, not a new window.
 

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
I have this:

Code:
- (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id)listener {
    [ [ NSWorkspace sharedWorkspace ] openURL:[ request URL ] ];
}

But it doesn't actually work. I have searched for hours now, and still can't make it work. Is there a bug in webkit?
 
Last edited:

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
Thank you for posting the link, I have read it and implemented the code, but it doesn't work. When the javascript is involved, it just ignores it. Is there any way to make it work with javascript?
 

chown33

Moderator
Staff member
Aug 9, 2009
10,747
8,420
A sea of green
Post some basic debugging information:
1. Show the exact URL.
2. Also show the action dictionary.

Pretend we can't reach into your computer and add NSLog() calls that show this info, then recompile, run, and remotely see the results.


At a basic level, asking NSWorkspace to openURL is almost certainly the wrong thing. You want YOUR program to handle the URLs, not some other application that handles the URL by default. In short, I don't think you understand what you're asking NSWorkspace to do.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
It works for me.

Did you implemented a WebUIDelegate? Particularly did you implement webView:createWebViewWithRequest: and, if appropriate, webViewShow:?

Did you connect the delegate to your WebView's UIDelegate outlet?

How did you implement webView:createWebViewWithRequest:?

If you put a NSLog in webView:createWebViewWithRequest: do you see the log message in the debugger console?
 

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
It works for me.

Did you implemented a WebUIDelegate? Particularly did you implement webView:createWebViewWithRequest: and, if appropriate, webViewShow:?

Did you connect the delegate to your WebView's UIDelegate outlet?

How did you implement webView:createWebViewWithRequest:?

If you put a NSLog in webView:createWebViewWithRequest: do you see the log message in the debugger console?

So for connecting the the delegates, in IB I connected them with the control click/drag method. So they are linked.

Then for the code what I have is:
Code:
.h file:
IBOutlet WebView *web1;
.m file:
-(void)awakeFromNib
{
    [web1 setUIDelegate:self];
    [web1 setPolicyDelegate:self];
    [web1 setCustomUserAgent:@"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"];
    NSString *sentURL = @"http://news.google.com";
    [[web1 mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:sentURL]]]; 
}

- (void)web1:(WebView *)sender
decidePolicyForNavigationAction:(NSDictionary *)actionInformation
request:(NSURLRequest *)request
frame:(WebFrame *)frame
decisionListener:(id <WebPolicyDecisionListener>)listener
{[listener ignore];
    [[NSWorkspace sharedWorkspace] openURL:[request URL]];
}
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Forget about the policy delegate, you're on the wrong path there.

You need to implement webView:createWebViewWithRequest:. See the WebUIDelegate informal protocol reference.

If you want to ignore that the request is for a new window: implement webView:createWebViewWithRequest: to just load the new URL in your WebView's mainFrame, and then return your WebView.

If you want to open the link in a new window within your program: implement webView:createWebViewWithRequest: to create a new WebView, load the new URL into the new WebView's mainFrame, and then return the new webView. Additionally implement webViewShow: to create a new window that has the passed WebView added to it, and to order the new window on screen.
 

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
I am still having trouble understanding this, do you mind posing some code to help me out some more with this? I really appreciate all the help so far.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
I am still having trouble understanding this, do you mind posing some code to help me out some more with this? I really appreciate all the help so far.

Really? Oh well...... :(

Code:
- (void)awakeFromNib
{
   [web1 setUIDelegate:self];
   [web1 setCustomUserAgent:@"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"];
   NSString *sentURL = @"http://news.google.com/";
   [[web1 mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:sentURL]]]; 
}

- (WebView *)webView:(WebView *)aSender createWebViewWithRequest:(NSURLRequest *)aRequest
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
    [[aSender mainFrame] loadRequest:aRequest];
    return aSender;
}

The links do work with this code. They open within the same window.
 

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
Really? Oh well...... :(

Code:
- (void)awakeFromNib
{
   [web1 setUIDelegate:self];
   [web1 setCustomUserAgent:@"Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7"];
   NSString *sentURL = @"http://news.google.com/";
   [[web1 mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:sentURL]]]; 
}

- (WebView *)webView:(WebView *)aSender createWebViewWithRequest:(NSURLRequest *)aRequest
{
    NSLog(@"%s", __PRETTY_FUNCTION__);
    [[aSender mainFrame] loadRequest:aRequest];
    return aSender;
}

The links do work with this code. They open within the same window.

Thank you, this does work. I have a few questions. Is the reason you are calling it "webView" because we are creating a new WebView? Because my original was called web1, and when the links open, they do not load the mobile version of the websites. So is it possible to preserve my web1 with the custom user-agent?
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
Thank you, this does work. I have a few questions. Is the reason you are calling it "webView" because we are creating a new WebView? Because my original was called web1, and when the links open, they do not load the mobile version of the websites. So is it possible to preserve my web1 with the custom user-agent?

I was calling the WebView object webView both generically and because that's what the name of the property in my window controller is. When I paste the code above for you, I noticed at the last moment that you've called it web1, so I replaced webView with web1 in the code.

Where exactly in the code do mean by my calling it "webView"?

EDIT: I just tested the code. The custom user agent is being preserved, as I would have expected, because at no point is a new WebView object created. Some sites display a mobile version, some don't; but the behaviour is identical under iOS 4.

EDIT 2: Upon further investigation, the mobile version of news.google.com has exactly the same links the regular versions of news.google.com. It doesn't specially provide links to the mobile versions of the news items.

If a news website is setup to detected a mobile user agent, it will redirect you to the mobile version of the news item. If the news website is not so setup, you'll get the regular version of the new item.

For example -- I'm in Australia so these are Australian examples -- the Sydney Morning Herald automatically detected the mobile user agent and redirected me to the mobile version of the website. The Australian newspaper's website did not. I need to manually navigate to the mobile version.

So for websites that don't automatically detect and redirect, you'll need to translate the regular URL to the mobile URL. This translation will be specific to search news website.
 
Last edited:

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
You are right about the user-agent, I just was not looking clearly at it. However, I am still confused on how this works. Because my WebView is called "web1". However if your code, its called "webView" and this works. When I change it to "web1" it does not work. What if my program had multiple WebViews, how can i distinguish the two? I hope you understand what I am asking, and I am very grateful for all the help you have given me so far.
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
You are right about the user-agent, I just was not looking clearly at it. However, I am still confused on how this works. Because my WebView is called "web1". However if your code, its called "webView" and this works. When I change it to "web1" it does not work. What if my program had multiple WebViews, how can i distinguish the two? I hope you understand what I am asking, and I am very grateful for all the help you have given me so far.

Are you talking about the code below in blue?
Code:
- (WebView *)[color=blue]webView[/color]:(WebView *)aSender createWebViewWithRequest:(NSURLRequest *)aRequest

Would you have expected the below?
Code:
- (WebView *)[color=red]web1[/color]:(WebView *)aSender createWebViewWithRequest:(NSURLRequest *)aRequest

Would you have hoped to have the below if you also had a web2?
Code:
- (WebView *)[color=red]web2[/color]:(WebView *)aSender createWebViewWithRequest:(NSURLRequest *)aRequest

If so, this is not how Objective-C works. The method signature keywords before the colons form the name of the message which selects the method. When you implement a delegate method, you must use exactly the same name as is documented in the delegate's reference. In this example, the name of the message is webView:createWebViewWithRequest:. If you implement web1:createWebViewWithRequest:, that's a completely different name and won't be called when a WebView send your delegate a webView:createWebViewWithRequest: message.

If you have multiple WebViews, you have at least 2 choices. Preferably you would implements 2 view controllers each acting as a delegate of 1 WebView object. Each would implement webView:createWebViewWithRequest: as appropriate for the WebView.

Alternatively, you would need an if structure in the 1 delegate shared by multiple WebView objects that selects the appropriate code based on who sent the delegate the message. Like so:
Code:
- (WebView *)webView:(WebView *)aSender createWebViewWithRequest:(NSURLRequest *)aRequest
{
  if (aSender == web1) {
    /* Directly implement webView:createWebViewWithRequest: for web1 */
    /* or send web1:createWebViewWithRequest: to self                */
    /*     and implement that method                                 */
  }
  else if (aSender == web2) {
    /* Directly implement webView:createWebViewWithRequest: for web2 */
    /* or send web2:createWebViewWithRequest: to self                */
    /*     and implement that method                                 */
  }
  else {
    NSString *reason = 
      [NSString stringWithFormat:@"%@ not implemented for %@", 
                                 NSStringFromSelector(_cmd),
                                 sender];
    NSException *exception = 
      [NSException exceptionWithName:@"NotImplemented"
                              reason:reason
                            userInfo:nil]; 
    @throw exception;
  }
}
 

geoldr

macrumors newbie
Original poster
Apr 1, 2011
17
0
You have no idea how much your explanation has helped me understand. Thank you very much
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.