open URL in Safari instead of webView - iphone

I have an app that populates an RSS feed in a table view. Selecting a row on the table, opens a new View with the whole post. My issue sometimes there are hyperlinks in the RSS feed. Clicking on the link opens the content in the same view instead of safari. I would like to open any links that are in the RSS feed in safari with an alert message about leaving the app. But I have no idea for to deal with this in my code. Any leads would be helpful. I am pasting my code for the DetailedView below.
- (void)viewDidLoad {
[self.itemSummary loadHTMLString:[item objectForKey:#"summary"] baseURL:nil];
}
- (id)initWithItem:(NSString *)theItem {
if (self = [super initWithNibName:#"Detail" bundle:nil]) {
self.item = theItem;
self.title = [item objectForKey:#"title"];
}
return self;
}

try this code:
-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if ( inType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}

Related

Need to open link in safari from uiwebview?

I have stored my whole html document with escape sequence in a variable...
and it contains some anchor tag.. where if that has clicked, it should open in safari, not in my app webview....
You can use following code for that.
-(BOOL) webView:(UIWebView *)inWeb shouldStartLoadWithRequest:(NSURLRequest *)inRequest navigationType:(UIWebViewNavigationType)inType {
if ( inType == UIWebViewNavigationTypeLinkClicked ) {
[[UIApplication sharedApplication] openURL:[inRequest URL]];
return NO;
}
return YES;
}
You can use the UIWebViewDelegate protocol to achieve this:
// assuming webView is a valid UIWebView
webView.delegate = self;
- (BOOL)webView:(UIWebView *)wv shouldStartLoadWithRequest:(NSURLRequest *)rq navigationType:(UIWebViewNavigationType)nt
{
if (nt == UIWebViewNavigationTypeLinkCkicked) {
[[UIApplication sharedApplication] openURL:[rq URL]];
return NO;
}
return YES;
}

Xcode 4.3 from a button in a UIWebView open the same url in safari

I am relatively new to Xcode and I have started building an app that uses UIWebView. To make it compliant for App Store submission, Apple prefers you use Safari. To overcome this problem I want to add a button to my UIWebView navigation that, when clicked, will open the same url in Safari. An example of this can be seen in the Twitter app; they have a button that opens the currently viewed UIWebView in a Safari window.
You can use the UIWebViewDelegate's method
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if iWantToOpenThisURLInSafari([request URL]) {
[UIApplication openUrl:[request URL]];
return NO; // tell the webView to not navigate to the URL, I'm handling it
} else {
return YES;
}
}
- (BOOL)iWantToOpenThisURLInSafari:(NSURL* url) [
// you just have to fill in this method.
return NO;
}
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intf/UIWebViewDelegate
EDIT: more details as requested by #PaulGraham
// You have a pointer to you webView somewhere
UIWebView *myWebView;
// create a class which implements the UIWebViewDelegate protocol
#interface MyUIWebViewDelegate:NSObject<UIWebViewDelegate>
// in this class' #implementation, implement the shouldStartLoad..method
#implementation
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if iWantToOpenThisURLInSafari([request URL]) {
[UIApplication openUrl:[request URL]];
return NO; // tell the webView to not navigate to the URL, I'm handling it
} else {
return YES;
}
}
// then, set the webView's delegate to an instance of that class
MyUIWebViewDelegate* delegate = [[MyUIWebViewDelegate alloc] init];
webView.delegate = delegate;
// your delegate will now recieve the shouldStartLoad.. messages.

UIWebView respond to Javascript calls

How can I intercept Javascript calls such as window.open as Mobile Safari does? I haven't seen anything listed about this, but it must be possible somehow?
Has anyone done this before?
When the page is finished loaded (webViewDidFinishLoad:), inject a window.open override. Of course it will not work for window.open which are called during page load.
Then use a custom scheme to callback your objective C code.
[EDIT] OK I have tested it. Now it works.
Create a new "view based" project and add a webview in the viewcontroller xib using IB.
#implementation todel2ViewController
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSString* page = #"<html><head></head><body><div onclick='javascript:window.open(\"http://www.google.com\");'>this is a test<br/>dfsfsdfsdfsdfdsfs</div></body></html>";
[self.view loadHTMLString:page baseURL:[NSURL URLWithString:#""]];
}
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString* urlString = [[request URL ] absoluteString ];
NSLog(#"shouldStartLoadWithRequest navigationType=%d", navigationType);
NSLog(#"%#", urlString);
if ([[[request URL] scheme] isEqualToString:#"myappscheme"] == YES)
{
//do something
NSLog(#"it works");
}
return YES;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
//Override Window
NSString*override = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"NewWindow" ofType:#"js"] encoding:4 error:nil];
[self.view stringByEvaluatingJavaScriptFromString:override];
}
#end
The Javascript:
var open_ = window.open;
window.open = function(url, name, properties)
{
var prefix = 'csmobile://';
var address = url;
open_(prefix + address);
return open_(url, name, properties);
};
The log
2011-07-05 14:17:04.383 todel2[31038:207] shouldStartLoadWithRequest navigationType=5
2011-07-05 14:17:04.383 todel2[31038:207] myappscheme:it%20works
2011-07-05 14:17:04.384 todel2[31038:207] it works
2011-07-05 14:17:04.386 todel2[31038:207] shouldStartLoadWithRequest navigationType=5
2011-07-05 14:17:04.386 todel2[31038:207] http://www.google.com/

Passing a URL from one UIWebView to another UIWebview

When a user clicks a link in the present UIWebView a new view is pushed onto the navigationController's stack that contains a UIWebView. I'd like to pass the URL that was touched to this new UIWebView. How do I go about doing this?
In your UIWebView delegate:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
if( navigationType == UIWebViewNavigationTypeLinkClicked ) {
YourWebViewController* vc = [[YourWebViewController alloc] initWithURL:[request URL]];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
return NO;
}
return YES;
}
Then you just need to implement the initializer in your custom viewcontroller:
- (id)initWithURL:(NSURL*)url {
self = [super init];
if( self ) {
myURL = [url retain];
}
return self;
}
Then load it at an appropriate time, like viewDidAppear:
- (void)viewDidAppear:(BOOL)animated {
[webView loadRequest:[NSURLRequest requestWithURL:myURL]];
}

When is Facebook Connect supposed to call its delegate methods?

The Facebook connect code is eluding me a bit.
I have no problem doing a login, and a wall post, however, I simply can not
figure out how the delegate methods for the FBDialog andFBStreamDialog is supposed to work.
- (void)postToWall {
FBStreamDialog *dialog = [[[FBStreamDialog alloc] init] autorelease];
dialog.delegate = self;
dialog.userMessagePrompt = #"Enter your message:";
dialog.attachment = [NSString stringWithFormat:#"JSONpost code"];
[dialog show];
}
I adhere to these protocols in my controller:
<FBDialogDelegate, FBSessionDelegate, FBRequestDelegate>
I then implement the two methods:
- (void) dialogDidCancel:(FBDialog *)dialog {
NSLog(#"Failed");
}
- (void) dialogDidSucceed:(FBDialog *)dialog {
NSLog(#"Success");
}
After I tap "publish" and the postToWall methods is done executing the Facebook "pop up" in the UI is empty, except a small "X" in the top right corner and a "F" (facebook logo) in the top left corner.
The UI will stay there until I tap the "X", this results in the dialogDidCancel delegate method being called. The post data is showing up on the Facebook page, everything seems to work.
Why is thedialogDidSucceedmethod never called? I need this to release my facebook controller and restore the UI back to where the user was before "starting" FB Connect.
Thank You:)
Facebook has fixed this issue, as you can see from their post at:
http://bugs.developers.facebook.com/show_bug.cgi?id=10531
I see where the problem is, but not sure what if anything we can do about it. It happens in the UIWebView Delegate method in the FBDialog class. If you click the Skip button, the request.URL is populated with 'fbconnect:success', it should really be 'fbconnect:cancel' but other people have already pointed out this problem out before. Our problem is that when you click the Publish button, the request.URL should read 'fbconnect:success' however, it ends up containing 'http://www.facebook.com/fbconnect/prompt_feed.php', so, it never calls dismissWithSuccess:YES or dialogDidSucceed.
I can't find anyplace where the Publish button's post URL is set, but if we can change it to fbconnect:success, it might work.
FBDialog.m
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType {
NSURL* url = request.URL;
if ([url.scheme isEqualToString:#"fbconnect"]) {
if ([url.resourceSpecifier isEqualToString:#"cancel"]) {
[self dismissWithSuccess:NO animated:YES];
} else {
[self dialogDidSucceed:url];
}
return NO;
} else if ([_loadingURL isEqual:url]) {
return YES;
} else if (navigationType == UIWebViewNavigationTypeLinkClicked) {
if ([_delegate respondsToSelector:#selector(dialog:shouldOpenURLInExternalBrowser:)]) {
if (![_delegate dialog:self shouldOpenURLInExternalBrowser:url]) {
return NO;
}
}
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
} else {
return YES;
}
}