Why is my web view fail delegate not working? - iphone

.h
IBOutlet UIWebView *webview;
.m
- (void)viewDidLoad {
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://blabla.com"]]];
}
- (void)webView:(UIWebView *)webViewfail didFailLoadWithError:(NSError *)error {
if([webViewfail isEqual:webview]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Failed"
message:#"Check your Internet connection before refreshing."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
I do not know what I did wrong, I tried making it appear but setting off internet connection. Any tips or suggestions will be helpful.

Make sure you have hooked up the delegate in interface builder (if that is what you are using). You can do this by selecting the web view, and drag (while holding control) to the view controller / file's owner, and then select delegate (which pops up when you release the mouse).
Or you can hook up your delegate in code in your viewDidLoad method like so:
[webView setDelegate:self]
Make sure your view controller conforms to the UIWebViewDelegate protocol by adding in your .h
#interface MyViewController : UIViewController <UIWebViewDelegate>
Good luck :)

Check this:
Make sure the object containing the quoted method is indeed the web view's delegate.
Give the web view's url request a really short timeoutInterval.

Try this also:
In your ViewController.h
#interface ViewController : UIViewController <UIWebViewDelegate>
And in ViewController.m below [super viewDidLoad] add :
self.webView.Delegate = self;

Related

How to allow UITapGestureRecognizer to detect taps on web view?

I have made web browser for iPhone in Xcode, and to exit the web browser and go back to the main page you tap on the screen three times, except that the gesture will only work on the toolbars at the top and bottom of the screen but not on the web view.
What can I do?
Here is my code
.h File
#import <UIKit/UIKit.h>
#interface Internet : UIViewController {
IBOutlet UIWebView *webview;
IBOutlet UIBarButtonItem *forwards;
IBOutlet UIBarButtonItem *backwards;
IBOutlet UITextField *URLTextField;
}
- (IBAction)share:(id)sender;
- (IBAction)returnKeyPressed:(id)sender;
- (IBAction)google:(id)sender;
- (IBAction)reload:(id)sender;
- (IBAction)forwardsButton:(id)sender;
- (IBAction)backwardsButton:(id)sender;
#end
.m File (only relevant code shown)
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
NSString *homePageString = #"http://www.google.com";
NSURL *homePage = [NSURL URLWithString:homePageString];
NSURLRequest *requestHomePage = [NSURLRequest requestWithURL:homePage];
[webview loadRequest:requestHomePage];
forwards.enabled = NO;
backwards.enabled = NO;
UIAlertView *touchHelp = [[UIAlertView alloc] initWithTitle:#"Alert, Please Read" message:#"To go back to the App Selection Page please anywhere on the top or bottom toolbar three times" delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles:nil, nil];
[touchHelp show];
UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tapDetected:)];
tapRecognizer.numberOfTapsRequired = 3;
[self.view addGestureRecognizer:tapRecognizer];
}
- (void)tapDetected:(UITapGestureRecognizer *)tapRecognizer {
[self dismissViewControllerAnimated:YES completion:nil];
}
Implement shouldRecognizeSimultaneouslyWithGestureRecognizer delegate and return YES.
Implementation details:
Add the UIGestureRecognizerDelegate protocol to your .h file
#interface ViewController : UIViewController <UIGestureRecognizerDelegate>
Add this delegate in your .m file
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES
}

UIActionSheet code crashes when moved from UIViewController file to separate class file

I have searched and searched the board(s) and am not able to figure this out. It has got to be something simple and right in front of me.
I am trying clean up my code and make it more reusable. I was taking some UIActionSheet code that works from a UIViewController and making its own object file. Works fine, until I add UIActionSheetDelegate methods.
When a button is pressed, instead of firing the actionSheetCancel method, it crashes with no stack trace. Every time.
My code is below. Any help would be appreciated. My guess has been it is because I am not using the xcode storyboard tool to connect things together, but I would think this is legal.
egcTestSheet.h:
#import <UIKit/UIKit.h>
#interface egcTestSheet : NSObject <UIActionSheetDelegate> {
}
- (void) showSheet:(UITabBar *) tabBar
displayTitle:(NSString *) name;
#end
egcTestSheet.m
#import "egcTestSheet.h"
#implementation egcTestSheet
-(void) showSheet:(UITabBar *)tabBar displayTitle:(NSString *)name{
UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:name
delegate:self
cancelButtonTitle:#"Done"
destructiveButtonTitle:#"Cancel"otherButtonTitles:nil];
[menu showFromTabBar:tabBar];
[menu setBounds:CGRectMake(0,0,320, 700)];
}
// actionsheet delegate protocol item
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex: (NSInteger)buttonIndex{
NSLog(#"button index = %d", buttonIndex);
}
- (void)actionSheetCancel:(UIActionSheet *)actionSheet{
NSLog(#"in action canceled method");
}
#end
call code from a UIViewController object:
egcTestSheet *sheet = [[egcTestSheet alloc] init];
[sheet showSheet:self.tabBarController.tabBar displayTitle:#"new test"];
Your action sheet is probably being released as it is dismissed (are you using ARC?). This means when it tries to call it's delegate to inform said delegate of its dismissal/selection, it is trying to call self. Self is a dangling pointer by this time, because it has been released.
In the view controller that is presenting/calling this action sheet, set a property to keep a reference to the action sheet. Set the property to nil on dismissal of the action sheet.

Frustrating UIWebView Delegate Crash issue

I've created an ARC Application that run's perfect. It's got a UINavigationController that I use to push through the views and everything runs fine.
I'm converting the Application to iPad and i've decided to show one of the views as a popover. (I don't like UIPopoverController so i've created my own basic popup). It's added to the view as follows..
MyViewController *hotelinf = [[MyViewController alloc]
initWithNibName:#"MyViewController_iPad" bundle:nil];
[self.view addSubview:hotelinf.view];
The view is added as a subview fine. The view i'm adding contains a UIWebView that has the usual delegate methods in it, but when the view tries to access one of the delegates it simply crashes.
*** -[MyViewController respondsToSelector:]: message sent to deallocated instance 0x7917b90
Specifically, it crashes on this line..
[self.webView loadHTMLString:stringResponse baseURL:nil];
I've displayed views (and UINavigationControllers) as subViews many of times without any issues, although none of them included a UIWebView delegate. I'm guessing I have to set the delegate of my UIViewController istance but i'm not sure how. It's also worth noting that if I push the view in my existing UINavigationController it calls and loads the HTML fine, which surely means it has nothing to do with the code of the view itself.
Any help would be greatly appreciated! Here is the code (in addition to above that shows the controller)..
.h
#interface MyViewController : UIViewController <UIWebViewDelegate, UIActionSheetDelegate> {
//Unrelated IBOutlets
}
#property (nonatomic, strong) UIWebView *webView;
#end
.m
#implementation MyViewController
#synthesize webView;
- (void)viewDidLoad
{
[super viewDidLoad];
self.webView = [[UIWebView alloc]initWithFrame:CGRectMake(317,283,393,354)];
self.webView.delegate = self;
[self.view addSubview:self.webView];
[NSThread detachNewThreadSelector:#selector(getHTMLString) toTarget:self withObject:nil];
}
-(void)getHTMLString {
#autoreleasepool {
//Download a valid HTML String
[self performSelectorOnMainThread:#selector(loadHTML) withObject:nil waitUntilDone:NO];
}
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.webView = nil;
}
-(void)loadHTML {
self.webView.opaque = NO;
self.webView.backgroundColor = [UIColor clearColor];
if ([stringResponse isEqualToString:#""]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Could not connect to XXXXX.com. Please verify you are connected to a working 3G/WIFI Network." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
} else {
//it crashes here only when loaded as a subview - the first access to the delegate
[self.webView loadHTMLString:stringResponse baseURL:nil];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
[self stopIndicator];
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
if (error.code == NSURLErrorCancelled) return; // this is Error -999
[self stopIndicator];
// report the error inside the webview
NSString* errorString = [NSString stringWithFormat:
#"<html><center><font size=+10 color='black' face='Helvetica'>An error occurred:<br>%#</font></center></html>",
error.localizedDescription];
[self.webView loadHTMLString:errorString baseURL:nil];
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Cannot load URL."
message:#"You have a connection failure. Please verify you are connected to a WIFI or 3G enabled Network."
delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[alert show];
}
#end
The issue has nothing to do with the UIWebView, rather with your controller class. Indeed,
MyViewController *hotelinf = [[MyViewController alloc]
initWithNibName:#"MyViewController_iPad" bundle:nil];
[self.view addSubview:hotelinf.view];
You are allocating the controller and assigning it to a local variable; then you add the controller's view as subview to your current view. Doing that, that view is retained, but what happens to the controller object itself? Are you releasing it? Or it leaks (since it is assigned to a local variable)?
This possibly explains why when later the respondsToSelector method is called, the controller has already been deallocated...
A way to fix this is creating a new property or an ivar in your main controller class and store MyViewController in there. Don't forget to release it in dealloc.
I would also suggest another thing. In:
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.webView = nil;
}
set the webView delegate to nil before releasing the view:
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.webView.delegate = nil;
self.webView = nil;
}
And I would also possibly review the reason why you release the webView in viewDidDisappear. On the other hand you allocate it in viewDidLoad. This asymmetry is dangerous, since whenever the main view disappears (for any reason) the webView will be removed and when the view reappears, it is not there anymore.
Better add all the delegate methods. You havent added the first two. Most probably, your code is crashing when message webViewDidStartLoad is sent
– webView:shouldStartLoadWithRequest:navigationType:
– webViewDidStartLoad:
– webViewDidFinishLoad:
– webView:didFailLoadWithError:

How can I create an interaction with a URL by clicking a button in objective c?

I'm trying to make an app for iphone which will send a tcp connection to a specified urf (or web application). I want the button to firstly give an allert before sending. I wrote this code for this:
-(IBAction)tiklandi:(id)sender{
NSString *buton1 = [sender titleForState:UIControlStateNormal];
NSString *uyariText = [[NSString alloc] initWithFormat:#"istek gönderiliyor!"];
UIAlertView *alert= [[UIAlertView alloc]initWithTitle:#"Sunucuya Gönderildi" message:uyariText delegate:nil
cancelButtonTitle:#"işlemi iptal ettiniz!"
otherButtonTitles: nil];
[alert show];
//[alert release];
but I couldn't use any url methods in my code.
My second question is, I can't see my Interface builder in Developer directory and also in project navigator of Xcode I can't see folders, all the classes come mixed between each other. I use Xcode 4.2, and I'm new with all these, can anyone please help?
I tried the listed solutions but I dont know how to interact my view controller files and .xib file.
Here is my view controller .h file:
#interface ViewController : UIViewController
#property (nonatomic, retain) NSURLRequest *url;
#property (nonatomic,retain) UIButton *buton;
-(IBAction)fonksiyon:(id)sender;
#end
and this is my implementation file (of view control .. .m)
#import "ViewController.h"
#implementation ViewController
#synthesize buton;
#synthesize url;
-(IBAction)fonksiyon:(id)sender{
NSString *buton= [sender titleForState:UIControlStateNormal];
NSURL *url= [sender url];
NSString *uyariText= [[NSString alloc] initWithFormat:#"gönderiliyor!"];
UIAlertView *alertView= [[UIAlertView alloc]initWithTitle:#"Sunucuya Gönderildi"
message:uyariText
delegate:self
cancelButtonTitle:#"işlemi iptal ettiniz!"
otherButtonTitles:#"Server'a Git!", nil];
- (NSURL)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [alertView cancelButtonIndex]) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://192.168.69.290/cgi-bin/ipad.pl";nil]];
}
}
}
The problem is that I can not make a relation between .xib file and the other ones via File's Owner. As I understand, when I drag from file's owner I should see my function (here called fonksiyon) too. Can anyone help?
You have to implement the delegate protocol for UIAlert to handle user's response. Then you'll be able to open the URL you want.
Interface Builder is no longer a separate application (since XCode v4)> Just open a XIB/NIB file in XC.
To open a URL in Safari mobile check this question: How can I launch Safari from an iPhone app?
If you want to open an URL inside your app you need to build your own UIWebView:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebView_Class/
set the delegate to self when you create the UIAlertView and implement one of the UIAlertViewDelegate methods.
Of course if you want to provide the option to cancel you need a "otherButtonTitle"
UIAlertView *alert= [[UIAlertView alloc]initWithTitle:#"Sunucuya Gönderildi"
message:uyariText
delegate:self
cancelButtonTitle:#"işlemi iptal ettiniz!"
otherButtonTitles:#"Go to website", nil];
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex != [alertView cancelButtonIndex]) {
// open url in external safari
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"http://foo.bar"]];
// EDIT: I might have misunderstood your question.
// you should read about NSURLConnection and put that code here.
}
}
my second question is, i cant see my Interface builder in Developer directory
Interface Builder is no longer an extra application. It is now built-in to Xcode. You don't need to launch it, just select the xib file in Xcode.
and also in project navigator of Xcode i can't see folders, all the classes come mixed between each other.
Select the files you want to group, do a secondary click and select "New Group from Selection".
You are responsible for grouping your files. When you have an existing group just drag&drop your files there.

'NSObject' may not respond to -navigationController

Hi there I currently I have a warning on a line of code where I am trying to push a new view onto the screen.
Outline // my NSObject receives a code=1 from my server I have set up. Everything works fine the code comes through which then initializes an AlertView where I have set up an if statement to catch the button click of my AlertView message. When that button is pressed my application falls over.
I have declared my ViewController of the view I am trying to push in its header file and there are no errors just the warning when compiled.
this is my NSObject I have made
/////.h
#import <Foundation/Foundation.h>
#interface alerts : NSObject {
}
- (void)pleaseRegisterDevice;
#end
/////.m
#import "alerts.h"
#import "instaCode1_3AppDelegate.h"
#import "RegisterDeviceViewController.h"
#implementation alerts
//use this alert when phone falls out of sync
- (void)pleaseRegisterDevice {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Please Register Device"
message:#"click OK to register"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert autorelease];
[alert show];
}
//Catch pleaseRegisterDevice method
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"OK"]) {
NSLog(#"msg from alertView method");
//open new wndow
RegisterDeviceViewController *regViewController = [[RegisterDeviceViewController alloc] init];
//Push it onto the top pf the navigation controller's stack
**[[self navigationController] pushViewController:regViewController animated:YES];**
}
else {
NSLog(#"was not able to push view");
}
}
- (void)dealloc {
[super dealloc];
}
#end
I have bolded the line of code where I get the warning 'alerts' may not respond to -navigationController
any help would be greatly appreciated.
I dont think an NSObject subclass has a UINavigationController...
You need to get a pointer to your app delegate's navigation controller like so
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.navigationController pushViewController:regViewController animated:YES];
navigationController is a property defined on a UIViewController. A NSObject does not have this method.
You don't have any instance member or method called navigationController, hence the warning.