Check for Internet in UIWebView App on jQuery .click() - iphone

I use this code to check for internet when the app opens for the first time:
//No Internet Connection error code
-(void)webView:(UIWebView *)webVIEW didFailLoadWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"No Internet Connection!" message:#"In order to use this app you need an active Internet connection!" delegate:self cancelButtonTitle:#"Close" otherButtonTitles:nil, nil];
[alert show];
}
//Close app from Alert View
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
exit(0);
}
I have a UIWebView app that has a jQuery .click() function. Is there a way to check for Internet again once the user clicks that button?

Take a look at Apple's sample code. The Reachability project shows how to detect a connection
http://developer.apple.com/iphone/library/samplecode/Reachability/index.html

Keep in mind, a click doesn't necessarily request more resources over a network connection.
UIWebViewDelegate has a webView:shouldStartLoadWithRequest:navigationType selector that will be your friend here. To trigger it whenever you want (on click or other actions), set the source of a hidden iframe to some dummy value, and check for that value in your delegate method (which will run your test and return NO.
I recommend not exiting when there is no connection though, since users may see it as a crash, especially if their connection loss is only temporary (going through a tunnel). Also, repeatedly testing for connection may slow down your app unnecessarily, and incur more data charges for the user.

you could do like that:
in function click() you should add this code:
window.location = "fake://myApp/checkForInternet";
in your Objective-C code add this one:
-(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSString *link = request.URL.absoluteString;
if ([link isEqualToString:#"fake://myApp/checkForInternet"])
{
// check for Reachability here
return NO;
}
return YES;
}
note that in this example -webView:shouldStartLoad... is called only once per event in webView. I can provide more complexed code if you want to do checking twice or more in one javascript function at one event
read about checking for reachability you can, as #Rajneesh071 said, in Apple documentation or here is the project on GitHub

If you're using Apple's Reachability code or similar then you want the currentReachabilityStatus method; otherwise call the underlying SCNetworkReachabilityGetFlags function

Related

UIWebView Error Delegate Method vs Reachability

I'm in the process of submitting my app to the App Store, but I read that I must notify the user if the internet connection is down when my app needs it. The Apple page mentioned Reachability as well. Currently, though, I'm using the UIWebView delegate method didFailLoadWithError...
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error Loading" message:[error localizedDescription] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[errorAlert show];
}
...and it's working fine. My question is, will my app be rejected for not using Reachability to do this, or is it fine doing what I am currently doing?
Thanks in advance.
No, you're perfectly ok using didFailLoadWithError:.
Reachability class could be used to check if host is up (or internet connection at all) before even trying to load some page. But it is not neccessery, as long as you handle the possible errors - which obviously you do.
EDIT:
It is still a good practice to know wheather you will be able to reach a certain host or not. You could even modify GUI for each case (instead of just reporting an error). But this can always be done in update :)

simple alert view for connection check in a web view

dear Stackover community,
Nearly a week I'm struggling around with the fact that I must have a connection check
for my web view so I'm surviving the App review process by Apple :-)
I know that I can use the Reachablity sample but for me as a beginner I would say its not smart to deal with such a code.
I found out that it gets a bit simpler with a simple alert and code like this:
-(void)webview:(UIWebView *)webview didFailLoadWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"Can't connect. Please check your internet Connection"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show]; }
My problem is that I implemented this code into the .m of my Webviewcontroller and connected the delegate to the Filesowner but the App won't be that nice to me to show me the error message :-)
At the moment I'm using Xcode 4.2.1 with ARC enabled and storyboards.
Would anybody please give me a step by step guide how to get this work?
Its probably the last code I need for my App.
Thanks in advance
The delegate method is:
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error;
Note it's "-(void)webView" not "-(void)webview". Just capitalize the "v" in "view" and it will work.
To answer your subsequent question:"now when i stop the loading of the page the error message comes too. Is there another tip ?"
As you can see an NSError is passed to your function. That error contains information about the failure. You can see that information by adding: NSLog(#"Epic fail with error:%#",error); ('Epic' added for dramatic effect). When you log that error you will see a code 'property' listed. Through some experimentation you will see that this code property changes based on the type of error. It seems that this code will equal -1009 for a connection error. All of the possible errors are enumerated here under "URL Loading System Error Codes". Best of all since they are defined in an enumeration you don't have to remember much of that. You can just use:
-(void)webView:(UIWebView *)webview didFailLoadWithError:(NSError *)error {
if (error.code == NSURLErrorNotConnectedToInternet){
NSLog(#"You are not connected");
}
}
TRY ...
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error"
message:[error localizedString
]
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];

iPhone - UIWebView - Clicking on a URL before page has loaded makes didFailLoadWithError throw an error

In my iPhone application, I'm showing a web page in webview.
I implemented the delegate method as follows:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Error loading the requested URL" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
When ever I open a URL and loaded half page, i'm immediately clicking some other link in the web page. At that time also, this delegate method is being called.
How should I prevent to call delegate method when web page is loaded half and URL link is clicked.
Or some other solution can be to call stopLoading when some URL is clicked. How can I do that?
The error code NSURLErrorCancelled notifies you that the URLLoadingSystem 'stopped the load'. This happens for instance when the user clicks a link in a page that is only half loaded...the URLLoadingSystem stops it so you don't need to.
- (void) webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
// If the URLLoadingSystem cancelled the load don't show anything.
if ( [error code] == NSURLErrorCancelled )
{
//...this is called when the load is cancelled...
}
else
{
//...handle the error and show the alert ...
}
}
How should I prevent to call delegate method when web page is loaded half and URL link is clicked.
You can't really stop the method from being called - but you might be able to check the properties of the error object to determine what kind of error you got.
Or some other solution can be to call stopLoading when some URL is clicked. How can I do that?
You can use webView:shouldStartLoadWithRequest:navigationType: which will be called whenever the user takes some kind of navigation action (e.g. clicks a link, submits a form etc. You can use navigationType to determine what the action was). It should be possible to call stopLoading from there (though the webView might still call the webView:didFailWithError: method, I'm not sure... see the first part on how you can deal with that).

Is it possible to access UIAlertView using tag?

I hope to access UIAlertView using tag. The codes show below
UIAlertView *a=(UIAlertView *)[self.view viewWithTag:presetTag];
but a returns no object(0x0)
I am looking to find a way to get the pointer to the UIAlertView object that is displayed without creating a reference to it in my UIViewController class that is displaying it. I am creating the UIAlertView and assigning it's tag property a constant non-zero value, then displaying it via show and releasing the UIAlertView reference.
An example where this could come in handy is if I want to hide the alert view based on some other event that is not touching one of the buttons on the alert view. Say a server informs the app that the alert is no longer valid and so I dismiss with button index -1 on the alert view. But, I have no reference to that alert so how can I find it?
Welcome any comment
Thanks
interdev
As the UIAlertView is not part of the application's view hierarchy, the only way to access it would be to store the instance right after you created it, such as in a dictionary so you can later retrieve it.
Something like:
UIStateAlertView *alert = [[UIStateAlertView alloc]
initWithTitle:#"my_message"
message:nil
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles: nil];
alert.tag = kMY_TAG;
[_alertIndex setObject:alert forKey:[NSNumber numberWithInt:kMy_TAG]];
[alert show];
[alert release];
to retrieve the alert:
UIAlertView *alert = [_alertIndex objectForKey:[NSNumber numberWithInt:kMy_TAG]];
When you're done with the view, make sure to remove it from the dictionary:
[_alertIndex removeObjectForKey:[NSNumber numberWithInt:kMy_TAG]];
_alertIndex being a NSMutableDictionary
iPhone SDK: check if a UIAlertView is showing provides a solution, however this is relying on how Apple does its internal affair and could break at any moment; and so should be avoided
UIAlertView creates its own UIWindow, which is not part of your app's main hierarchy of UIViews. Therefore it is not possible to find it using [UIView viewWithTag:].
You must store the pointer to the UIAlertViews you create in order to find them again later.
There is a way to access UIAlertViews in your app (and then you could use tags to verify that it's the one you're looking for), but it is relying on the internal structure of the app and may therefore stop working in future versions of iOS, though it is unlikely. If you are interested, please see this other SO response.
I think it is possible, please check that you are setting a non-zero value to the tag.
Is this what you need? Specifically speaking, you can access each UIAlertView's tag info through its tag property in protocol callback methods.
#protocol UIAlertViewDelegate <NSObject>
#optional
// Called when a button is clicked. The view will be automatically dismissed after this call returns
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex;
// Called when we cancel a view (eg. the user clicks the Home button). This is not called when the user clicks the cancel button.
// If not defined in the delegate, we simulate a click in the cancel button
- (void)alertViewCancel:(UIAlertView *)alertView;
- (void)willPresentAlertView:(UIAlertView *)alertView; // before animation and showing view
- (void)didPresentAlertView:(UIAlertView *)alertView; // after animation
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex; // before animation and hiding view
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex; // after animation
#end

Close UIAlertView and Replace with Another

I'm running an application that requires LocationServices be enabled. I'm checking if they are by making a call to the service and catching the error. In the error case, I want to pop up an alertview notifying the user to activate location services. I have another AlertView open already when this test happens. I want to close that one and give the user the dialog box I mentioned previously.
Currently, I have
case kCLErrorDenied: // CL access has been denied (eg, user declined location use)
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"NOTICE"
message:#"Sorry, this application needs your location. Please select 'Allow' when asked to use your current location. You don't need to be on or near the trail."
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"EXIT"];
[alert show];
[alert release];
//exit(0);
break;
This causes the app to just exit. I had an NSLog output in there so I know it gets to this case.
here you are specifying delegate:self, then it searches for alert handlers declared at UIAlertViewDelegate and when it doesn't find it crashes.
So you should define
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
in your class.
Also you can implement other methods of UIAlertViewDelegate which will help you in your required task.
You need to keep track of the previous alert with an instance variable, and call the method to dismiss that previous dialog before showing the new one. You also need a delegate handler for the alert.