Connection Error Occurs When Browsing Too Fast - ios

In the app that I'm writing, I check to see if the device has an internet connection. I put a connection error image over the screen, and hide it unless the device is not connected. There is an odd issue though. I implemented a simple back button for the UIWebView, but when I press it too fast, the connection error occurs. Here is the code I use to check for connection, and decide whether to display the error:
-(void)webView:(UIWebView *)myWebView didFailLoadWithError:(NSError *)error {
_connectionError.hidden = NO;
}
So, I think the only way to solve this issue would be to have it check if there is a connection one time, only when the app first launches, and never run again for the remainder of the time. I'm extremely new to Objective-C, and have no idea how to do this. I'm thinking that I should put something in viewDidLoad, or implement some way to have the method run only once, but I have no idea how to do that.
Here's the code for the back button:
- (IBAction)backButtonTapped:(id)sender {
[_viewWeb goBack];
}

Call the method stopLoading on the webView before the goBack method to make sure there is no multiple request going which can cause the connection error:
- (IBAction)backButtonTapped:(id)sender {
[_viewWeb stopLoading];
[_viewWeb goBack];
}

To check for a connection you can use Reachability in your project. You can then use this answer to see how to use it. This would be more efficient and cleaner than using a UIWebview.

Related

How do I properly implement didFailProvisionalNavigation with WKWebView?

I'm making a web browser and like every other web browser I'd like to inform the user of the error that occurred when a web page failed to load.
Currently, I'm displaying the localizedDescription of the error in the didFailProvisionalNavigation method. That's all!
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
{
[self presentError:error.localizedDescription animated:YES];
[_delegate webViewDidFailNavigation:self error:error];
}
The presentError method handles some custom UI stuff irrelevant to the question.
The method above works excellent for displaying the usual errors such as:
The internet connection appears to be offline.
A server with the specified hostname could not be found.
But it also displays some unusual errors such as:
The operation could not be completed(NSURL ErrorDomain error -999)
I don't like this method for two reasons:
The error message displays some technical stuff "NSURL" but I could ignore that.
Most importantly most of the time when the error above is being displayed the web page is perfectly usable but since it's a didFailProvisionalNavigation error I have to disable the page from being used and instead present the error.
I'm not aware of what other minor errors could occur that shouldn't be handled the way I'm handling them. Unfortunately, I don't know of a way to distinguish between major errors such as "Connection appears to be offline" and minor errors such as "Operation couldn't be completed".
What is the standard way of handling navigation failures?
I needed to use didFailProvisionalNavigation too. For now I solved it like this:
- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(null_unspecified WKNavigation *)navigation withError:(nonnull NSError *)error
{
if(error.code != -999) // Prevent the error from showing when didFailProvisionalNavigation is triggered after a cancelled load (reload)
{
// Show the error
}
}
Instead of
webView(_:didFailProvisionalNavigation:withError:)
why do you not use this?
webView(_:didFail:withError:)
It seems that should only be called when there is an error preventing the site from displaying content, not when a page is already rendered and trying to load the next page.

Catching the Parse kPFErrorConnectionFailed error-code & Cancelling the pullToRefresh’s UIActivityIndicatorView in the IOS PFQueryTableViewController

I have two questions as follows:
I will like to catch the kPFErrorConnectionFailed error-code from the query in the IOS PFQueryTableViewController’s queryForTable. How do I go about it?
After the last attempt to connect to Network and I receive [Error]: Network connection failed, How do I cancel the pullToRefresh’s UIActivityIndicatorView which currently continues to load indefinitely?
What I’ve tried:
Concerning catching error-code kPFErrorConnectionFailed, I tried the following (which does not catch the error):
- (void)objectsDidLoad:(NSError *)error {
[super objectsDidLoad:error];
if(error.code == kPFErrorConnectionFailed)
{…}
}
A work around for Catching kPFErrorConnectionFailed is to use Apple's Reachability Class to check if the Parse Network Server is reachable before trying to load data.
A fix to the indefinite pullToRefresh UIActivityIndicatorView is to use kPFCachePolicyCacheThenNetwork as opposed to the kPFCachePolicyNetworkOnly. The kPFCachePolicyNetworkOnly keeps trying to load data from the network even with a bad connection. However, kPFCachePolicyCacheThenNetwork relies on the cached data when the network server is unreachable. Check here for more information

UIWebView - what NSError's are thrown?

I'm trying to throw up an alert to users when a UIWebView fails to load a page because it can't reach the server. I'm using the delegate method:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
// show NSAlert telling user there was a problem
}
(docs: https://developer.apple.com/library/ios/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html#//apple_ref/occ/intfm/UIWebViewDelegate/webView:didFailLoadWithError:)
The problem is that this method is called for other things as well - such as when you visit another page before the previous one has finished loading, etc. What specific NSError's should I check for for throwing my NSAlert? What NSError's does UIWebView throw? I can't see this documented anywhere!
Thanks.
If anyone does come up across the same problem, the solution ended up been to:
NSLog the error code and description every time the error function was called.
Do some stuff in my app that would generate errors
Watch the output to establish which codes corresponded to which actions (the error descriptions helped).
This is achieved simply by:
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
NSLog(#"%d", error.code);
NSLog(error.localizedDescription);
}

Objective c Thread 1 signal SIGSTOP app crashes

I'm trying to track down an error that appears to be definitely a timing issue. I have an application that uses a Universal Framework. When the process is complete in the framework an NSNotification is sent back to the application. We have recently added a third party framework to our framework. Now, while the methods for the third party framework are being executed, as execution returns to our framework I receive the following error in the Console Output:
Assertion failed: (exclusive), function assert_locked, file ../dep/include/boost/boost_1_55_0/boost/thread/pthread/shared_mutex.hpp, line 51.
But I'm not sure that is the ultimate issue, because our framework continues to execute and the NSNotification is sent back to the application. Right after the Notification is sent and execution returns to the calling method (or the method call) in our framework I see a warning on the executing thread. Then, execution continues back to the original calling method and the warning goes away.
Here's the weird part. If I step through the code very slowly, it might just work. If I'm not slow enough I get the SIGSTOP and the code never returns to the UI. If I'm too fast, I get a SIGABRT.
I've been trying to find the exact issue using Instuments. This answer to a similar question backed up my suspicion that this is a timing issue. I think the boost assert_locked Assertion might have something to do with this.
My code is pretty boring but I know you want to see it, so here it is:
- (void)generateImageTemplates:(UIImage *)src
{
int result = 0;
cv::Mat image = *(cv::Mat*)[self cvMatFromUIImage:src];
user = IEngine_InitUser();
int userID=0;
result = IEngine_AddFingerprintRAW(user, UNKNOWN, image.data, image.size().width, image.size().height);
result = IEngine_RegisterUser(user, &userID);
[[NSNotificationCenter defaultCenter] postNotificationName:#"InnovatricsComplete" object:self];
}
If you're wondering what result is, it's an error code. So far these have all come back equal to 0. Meaning no errors. I'll work on handling these errors once I can get a successful return to the UI without crashing.
Control returns to the method call:
- (void)generateImageTemplates:(UIImage *)processedImage
{
[self.captureCommand generateImageTemplates:processedImage];
}
Control returns to the method call in the application View Controller:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0){
[self clearPressed:self.clearButton];
} else {
[self.cameraVC generateImageTemplates:self.processedImage];
}
}
Finally, the NSNotification callback code:
- (void)onInnovatricsComplete:(NSNotification *)note
{
[self.cameraVC willMoveToParentViewController:nil];
[self.cameraVC.view removeFromSuperview];
[self.cameraVC removeFromParentViewController];
}
I warned you it was pretty boring!
I'm completely stumped! Though I continue to surf the internet for clues, is there anybody out there who can help me resolve this issue?
Thank you.
Here are some screenshots (in reverse order):
look at NSUinteger’s answer in How to know where crash for postNotificationName:object:userInfo
the listener might be deallocated before it recieves the notification.

how to response before the server return on iOS

my situation is like this:
when you press a button, it will first hide the button, and then send a http request to the server, the request is sent to a php script and execute an "exe" to use the printer to print something.
But when I test the app, I find the button hides when the "exe" on the server exits, the result is that when I press the button, the application is like "not response", the button
dose not hide and keep the state of "press down", it is not user-friendly. So any ideas
to help me solve this ?
Finally, I used slef performSelectorInBackground, since I did not care the result php return, it works well and easier than Asynchronous call.
It may be that you are making a synchronous call to the server. Check here for how to make asynchronous calls.
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html
interface updates are only done after the method finishes. try running the php part in an extra method with performSelector:
- (void)yourCurrentMethod {
button.hidden = YES;
[self performSelector:#selector(doSomething)];
}
- (void)doSomething {
/* call php script, etc */
}
Sorry, what I meant was performSelector:withObject:afterDelay:
- (void)yourCurrentMethod {
button.hidden = YES;
[self performSelector:#selector(doSomething) withObject:nil afterDelay:0.1];
}
- (void)doSomething {
/* call php script, etc */
}
That will process the hidden in the UI and then call the doSomething-method without making it a background thread, so you can use a synchronous request. Using asynchronous requests is a little more work (but cleaner), which you don't really need, if you only want to call the php and don't care about the result.

Resources