I am new to objective-c, I am doing the same app for android and iPhone.
When in Java I use a try-catch block to catch a network exception and handle it.
In Objective-C I am using:
[[NSXMLParser alloc] initWithContentsOfURL:url]
So, How can I handle a network exception when parsing that input stream, so if network goes down or there's any problem I can notify user and keep my app working?.
If you are using NSXMLParser then use its delgate method..
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
NSLog(#"Error = %#", parseError);
}
It is never a good idea to use the initWithContentsOfURL: methods.
You are better of retrieving the the data via NSURLConnection or some library like AFNetworking. This will allow you to handle the HTTP status code and network error.
For example the NSURLConnectionDelegate has a call back method – connection:didFailWithError: which will be called in case of an error.
You can then examen the error object to see what went wrong.
Before you call the URL You can check the internet connectivity.
I suggest you to look the below link
How to check for an active Internet connection on iOS or OSX?
And I suggest for parsing XML file use raptureXML Which is very simple.
https://github.com/ZaBlanc/RaptureXML
Related
I'm trying to receive broadcast UDP datagrams on iOS. I started to use the CocoaAsyncSocket library which seems pretty good. I'm using it like this:
m_socket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
[m_socket setIPv6Enabled:NO];
NSError* error = nil;
if (![m_socket enableBroadcast:YES error:&error])
return log_warn(#"Failed to enable broadcast: %#.", error.description);
if (![m_socket bindToPort:43211 error:&error])
return log_warn(#"Failed to bind to port: %#.", error.description);
if (![m_socket beginReceiving:&error])
return log_warn(#"Failed to begin receiving.");
The result is that the didReceiveData callback seems not to be called.
I therefore tried to use regular socket API and it seems I can get some bytes: I simply used this code.
I am curious about why the CocoaAsyncSocket code above is not working. I tried to compare the two approaches by reading the internals of CocoaAsyncSocket but I'm still not able to find which difference is causing no byte to arrive. Am I missing something in the above code using CocoaAsyncSocket?
By reading the code in CocoaAsyncSocket I see that the member holding the reference to the delegate is weak. Therefore the reason why no callback and no error were received was that the delegate was freed. Storing a strong reference to the object was sufficient to get the data.
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
SITUATION I am trying to figure out the best practices for error handling with the parse.com iOS SDK. I have read the parse docs and they do a great job of documenting how to check for connectivity to parse and if objects can be found, but my question would be what do I do then?
EXAMPLE
[object saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if ([error code] == kPFErrorConnectionFailed) {
//COULD NOT REACH PARSE
//SO WHAT NOW?
}
else {
//EVERYTHINGS COOL
}
}];
SO WHAT NOW? Am I supposed to have this on an NSTimer and fire this off again in 5 minutes to see if we can reach parse then?
If saving objects is as important as it seems to be for your case, then this could be a solution, instead of using an NSTimer:
In the SO WHAT NOW? block, just call the method that saves this object recursively. If you ever get an error other than ConnectionFailed you could handle that appropriately, but if you're just worried about saving this even if the first attempt fails, this could be a way.
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.
I am trying retrieve data from a .php file on a server from within an iPhone OS app. In one method, I employ the following code:
NSString *aString = [[NSString alloc] initWithContentsOfURL:aURL encoding:anEncoding error:nil];
//See what I got
NSLog(aString);
When I run the App it seems like the App runs through the code so fast I doubt that there was enough time for a Data Request to have transpired. The resulting string is totally empty, which further supports my suspicions. What is happening here? Is the app not waiting for the -initWithContentsOfURL to retrieve data from the .php file on my server? If the app does not wait for this method, is there another method I can use to perform a Data Request in a manner that WAITS for the request to be completed before moving onto the next code?
(I've also read a little on NSURLConnection -- is this maybe what I should be looking into instead of -initWithContentsOfURL?)
NSURLConnection is great for getting a file from the web... It doesn't "wait" per se but its delegate callbacks:
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
...allow you to be notified when data has been received and when the data has been completely downloaded. This way you can have the App show (if you like) a UIProgressBar as the data comes in and then handle the file as you please when it is completely received.