How to show loading view controller in my webservices - ios

I want to show a loading view controller or activity indicator view when I call my loginUserintoserver method but while debugging I found the view becomes inactive at this line.
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
For sometime till I get the response. I have tried showing activity indicators but did not succeed. Please any guidelines to resolve this. Thanks in advance.
-(void) loginUserintoserver
{
NSString *str_validateURL = #"callogin";
// em,password,devicereg,devicetype,flag = ("e" or "m")
NSString *str_completeURL = [NSString stringWithFormat:#"%#%#", str_global_domain, str_validateURL];
NSURL *url = [NSURL URLWithString:str_completeURL];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
str_global_UserPhone = [NSString stringWithFormat:#"%#%#",signupCountryCodeTextField.text,signupMobileTextField.text];
NSString *postData = [NSString stringWithFormat:#"em=%#&password=%#&devicereg=%#&devicetype=%#&flag=%#", loginEmailTextField.text, loginPasswordTextField.text, str_global_DeviceRegID, #"1", [NSString stringWithFormat:#"%#", emailphoneFlag]];
NSLog(#"==============%#",postData);
NSString *length = [NSString stringWithFormat:#"%d", [postData length]];
[theRequest setValue:length forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPBody:[postData dataUsingEncoding:NSASCIIStringEncoding]];
// here the view becomes inactive and takes time to get response from server
NSData *responseData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
NSLog(#"response data is %#", responseData);
if (responseData == nil)
{
NSLog(#"No data from server");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"No data downloaded from server!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alertView show];
}
else
{
NSLog(#"response data is %#", responseData);
NSString *returnString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"returnString....%#",returnString);
NSDictionary *response_dic = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:nil];
NSString *msg;
msg = [response_dic objectForKey:#"Result"];
NSDictionary *loginDict=[[NSDictionary alloc]init];
loginDict=[response_dic objectForKey:#"Result"];
NSLog(#"msg is : %# ",[response_dic objectForKey:#"Result"]);
if ([[[response_dic objectForKey:#"Result"] objectForKey:#"ErrorCode"] isEqualToString:#"0"])
{
// success
NSLog(#"Successfull Login!!!!!");
NSString *UserId=[loginDict objectForKey:#"userid"];
[[NSUserDefaults standardUserDefaults] setValue:UserId forKey:#"LoginId"];
[self initRevealViewController];
} else if ([[[response_dic objectForKey:#"Result"] objectForKey:#"ErrorCode"] isEqualToString:#"1"]){
NSLog(#"Invalid Password!");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message: #"ReEnter Password" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}else if ([[[response_dic objectForKey:#"Result"] objectForKey:#"ErrorCode"] isEqualToString:#"3"]){
NSLog(#"Invalid input parameters!");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message: #"Email address or Mobile number, Password, devicereg, devicetype, flag are Mandatory" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}else if ([[[response_dic objectForKey:#"Result"] objectForKey:#"ErrorCode"] isEqualToString:#"6"]){
NSLog(#"Invalid input parameters!");
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message: #"User Registered but not activated" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
}

You have to used this: MBProgressHUD
Import framwork from above link and do some stuff like:
.h file:
#import "MBProgressHUD.h"
MBProgressHUD *HUD;
.m file do this :
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
[HUD show:YES];
// call your webservice here
[HUD hide:YES];
May be it will help.
Happy coding...:)

Mak ,
I use MBProgressHUD all my project . You can use also .Really MBProgressHUD is suitable , lightweight.
Showing indicator :
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
hiding :
[MBProgressHUD hideHUDForView:self.view animated:YES];

Most of the answers are partial which do not point out the main issue in your code.
Synchronous request on main thread will block it, thus you cannot show any UI updates like activity indicator while the sync request is in progress. Instead make asynchronous request (or make request in background using GCD) and use UIActivityIndicatorView or any other open source available for this.
Follow this Q&A to learn how to make asyn request using GCD: NSURLConnection and grand central dispatch
You can create and add an activity indicator to the view. Present and start showing activity when request is initiated and stop the activity when request completes downloading.
Hope that helps!

https://github.com/jdg/MBProgressHUD
Download the project for MBProgressHUD , and copy MBProgressHUD.h & .m classes in to your project, Now by simply creating an instance of MBProgressHUD and using the available methods by MBProgressHUD you can show loading view on to your web services
HUD = [[MBProgressHUD alloc] initWithWindow:[[UIApplication sharedApplication] delegate].window];
[HUD showWhileExecuting:#selector(loginUserintoserver) onTarget:self withObject:nil animated:YES];
[[[UIApplication sharedApplication] delegate].window addSubview:HUD];
Hope it will help you .

Related

Response in alert view

I am new to IOS i want to display response from post in alert view.in nslog i showed response. i need when i clicked button alert view can display my response.
coding:
-(void) sendDataToServer : (NSString *) method params:(NSString *)str{
NSData *postData = [str dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%lu", (unsigned long)[str length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL]];
NSLog(#"%#",str);
[request setHTTPMethod:#"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setHTTPBody:postData];
NSURLConnection *theConnection = [NSURLConnection connectionWithRequest:request delegate:self];
if( theConnection ){
mutableData = [[NSMutableData alloc]init];
}
}
alerview:
- (IBAction)butt1:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Value"
message:#"%#"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"ok", nil];
[self sendDataToServer :#"POST" params:str];
[alert show];
}
post method delegates:
here i get response in json111 that i showed in nslog successfully but in alert view i failed
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[mutableData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
return;
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError* error111;
json111 = [NSJSONSerialization JSONObjectWithData: mutableData
options:kNilOptions
error:&error111];
NSLog(#"%#",json111);
}
[![emptyvalue in alertview][1]][1]
change this into
updated answer
#interface myViewController : UIViewController <UIAlertViewDelegate>
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError* error111;
json111 = [NSJSONSerialization JSONObjectWithData: mutableData
options:kNilOptions
error:&error111];
NSLog(#"%#",json111);
NSArray *temp = [ json111 objectForKey:#"Currencies"];
// you can directly fetch like
NSDictionary *fetchDict = [temp objectAtIndex:0];
NSDictionary *fetchUnit = [temp objectAtIndex:1];
// finally you can fetch like
NSString * total = [fetchDict objectForKey:#"total"];
NSString * one_unit = [fetchUnit objectForKey:#"one_unit"];
//updated
NSString *final = [NSString stringWithFormat:#"%# , %#", total,one_unit];
// in here you can assign the value to Alert
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Value"
message:final
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"ok", nil];
alert.tag = 100;
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 100)
{
if (buttonIndex == 0)
{
// ok button pressed
//[self sendDataToServer :#"POST" params:str];
}else
{
// cancel button pressed
}
}
You should know the basics of NSString, refer here.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Value"
message:[NSString stringWithFormat:#"%#", str]
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"ok", nil];
You can save your response in an NSString and then pass this string in the message field of your alert view.
However, as of iOS 8,
UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead
Change your Alert View as following :
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Value"
message:[NSString stringWithFormat:#"Response Message : %#",str]
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"ok", nil];
This will display your response message instead %#..
If you want to send Data to Server on Click on alertView, you need to write code in alertView Delegate clickedButtonAtIndex
Hope it helps..

NSMutableRequest not working for the second time (ARC enabled)

I am performing JSON POST request by clicking UIButton and after the submission, segue perform can be done. So, After submitting values, I cannot perform POST request anymore. It shows status code 200 and response is OK. But, data is not reflected in the Backend. Here is my code:
(IBAction)transitsurveydone:(id)sender {
if([tempArray count]!=0){
/* alert= [[UIAlertView alloc] initWithTitle:#"Survey Submission"
message:#"Please Enter your location"
delegate:self
cancelButtonTitle:#"Modify"
otherButtonTitles:#"Submit",nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
alert.tag=2;
[alert show];*/
NSLog(#"Caption array is %# %#",captionArray,tempArray);
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:#"myURL"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSMutableDictionary *postDict = [[NSMutableDictionary alloc]init];
NSMutableDictionary *d=[[NSMutableDictionary alloc] initWithObjectsAndKeys:#10,#"\"Bus\"", nil];
NSMutableArray *m=[[NSMutableArray alloc] init];
NSString *str1,*str2,*str3,*str4;
// Checking the format
if(tempArray.count==1){
for (int x=0; x<1; x++) {
str1=[NSString stringWithFormat:#"\"%#\"",[captionArray objectAtIndex:x]];
[d setObject:[tempArray objectAtIndex:x] forKey:str1];
}
[request setHTTPBody:[[NSString stringWithFormat: #"{\n \"instance\" : %#,\n \"response_method\": \"web\",\n \"routes\": [\n {%#:%#}\n ]\n}",randomString,str1,[d objectForKey:str1] ]dataUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"%#:%#",str1,[d objectForKey:str1]);
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
// Handle error...
return;
}
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSLog(#"Response HTTP Status code: %ld\n", (long)[(NSHTTPURLResponse *)response statusCode]);
NSLog(#"Response HTTP Headers:\n%#\n", [(NSHTTPURLResponse *)response allHeaderFields]);
}
NSString* body = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response Body:\n%#\n", body);
}];
[task resume];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *respData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSLog(#"~~~~~ Status code: %d", [response statusCode]);
if([response statusCode]==200){
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Transit Survey submitted" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
alert.transform = CGAffineTransformMakeTranslation( 10, 740);
[alert show];
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:1.0f];
submitteddonthide=NO;
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:#"Transit Survey Submission Failed" delegate:self cancelButtonTitle:nil otherButtonTitles:nil];
alert.transform = CGAffineTransformMakeTranslation( 10, 740);
[alert show];
[self performSelector:#selector(dismissAlert:) withObject:alert afterDelay:1.0f];
}
if([prefs integerForKey:#"humandone"]==1){
[self performSegueWithIdentifier:#"transittohuman" sender:nil];
}
else{
[self performSegueWithIdentifier:#"gobackfromtransit" sender:nil];
}
}
`
The above code is in IBAction
Your code looks fine and there is no any issues.
If this issue is happens all the time, add "Advanced Rest Client" add-on to chrome browser and test your server URL passing respective input values. If this process also can't be able to update values on your backend there should be some issue on your backend.
A couple of thoughts:
You are using status code to determine whether the server inserted the data correctly or not. You should actually have your web service build an affirmative response (in JSON, would be great) that says whether data was successfully inserted or not. You should not be relying solely on the web server's request response code.
I would observe the request with something like Charles and make sure it looks OK.
You're building a JSON request manually, which is very fragile. I would suggest using Charles to observe the request, and copy and paste it into http://jsonlint.com and make sure it's OK.
Even better, use NSJSONSerialization which is more robust and easier to use.
Also, you're sending this request twice. Lose this second request (you shouldn't do synchronous requests, anyway) and put all of your confirmation logic inside the session's completion handler block.
Yes. After struggling a bit, Clearing cookies helped me a lot :-
Here is a chunk of code, which is pretty much simple
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookiesForURL:[NSURL URLWithString:urlString]];
for (NSHTTPCookie *cookie in cookies) {
NSLog(#"Deleting cookie for domain: %#", [cookie domain]);
[cookieStorage deleteCookie:cookie];
}
Thank you Mr. reddys and Rob for the suggestions

Displaying error messages after modal dismissal

So just like the question suggests, I'm trying not to freeze up the UI after the user sends some data to the server. In my case, they're possibly sending a lot of data and server side I have to do a foreach loop for multiple queries.
While all that is happening, I don't want the user to wait for a response so I'm dismissing the modal VC after "Send" is clicked. The data still gets inserted into the database but what if there's an error? Right now I'm showing a UIAlertView after the modal VC is dismissed but I get a bad access error. What's the best way of showing an error?
- (void)send:(id)sender{
if ([[Data sharedInstance].someData objectForKey:#"time"] != NULL) {
[self dismissViewControllerAnimated:YES completion:^(){
NSMutableDictionary *paramDic = [NSMutableDictionary new];
[paramDic setValue:[[Data sharedInstance].someData objectForKey:#"oneArray"] forKeyPath:#"oneArray"];
[paramDic setValue:[NSArray arrayWithObjects:[[[Data sharedInstance].someData objectForKey:#"two"] valueForKey:#"Name"], [[[Data sharedInstance].someData objectForKey:#"two"] valueForKey:#"State"], [[[Data sharedInstance].someData objectForKey:#"two"] valueForKey:#"Country"], nil] forKeyPath:#"twoArray"];
[paramDic setValue:[[[Data sharedInstance].someData objectForKey:#"three"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKeyPath:#"three"];
[paramDic setValue:[[NSUserDefaults standardUserDefaults] valueForKey:#"username"] forKey:#"username"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:paramDic options:NSJSONWritingPrettyPrinted error:nil];
NSURL *url = [NSURL URLWithString:#"http://localhost/myapp/handleData.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSString *length = [NSString stringWithFormat:#"%d", jsonData.length];
[request setValue:length forHTTPHeaderField:#"Content-Length"];
[request setValue:#"json" forHTTPHeaderField:#"Data-Type"];
[request setHTTPBody:jsonData];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (![httpResponse statusCode] == 200 || ![[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] isEqualToString:#"success"]) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Problem on the server. Please try again later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
}
}];
}];
}
That's how I'm doing it now...what's a better way?
The above answer is valuable. But I think this is what causes the problem.
Change:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Problem on the server. Please try again later." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
To:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Problem on the server. Please try again later." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
Hope this helps.
I'm thinking the issue has to do with your nested completion blocks. Because you place your web service call in the modal dismissal completion block, by the time it finishes and starts to execute your URL completion block, the class/controller in charge of that block has already been forgotten/destroyed/deallocated/whatever. At the very least, the view no longer exists where you're trying to present your alert view. You've listed self as the delegate of that alert view, but self doesn't exist anymore.
Try this first: instead of trying to display your alert on a no-longer-in-memory view from a background thread (big no-no even if the view still existed), try posting a notification to the main thread that you can pick up elsewhere in your app (such as your root view controller) and present the alert from there:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (![httpResponse statusCode] == 200 || ![[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] isEqualToString:#"success"]) {
dispatch_async(dispatch_get_main_queue(),^{
// observe this notification in root view controller or somewhere
// that you know will be in memory when it fires
[[NSNotificationCenter defaultCenter] postNotificationName:#"ErrorAlert"
object:nil
userInfo:imageDict];
});
}
}];
If that still doesn't work because the app has discarded your completion block when the view was dismissed, you will need to create a separate class that is in charge of sending this web service request instead of doing it all directly in the completion block. But still, remember to present your alert on the main thread :)

Storyboard list data demo, how to check condition back to list segue

I am new ios, i use storyboard to implement list data function demo, include add data.
In my AddWrokLogViewController,I have a method (IBAction)done:(id)sender bind + button.
as follow, in my do function, I want to check user inputs and save user input datas by http post. when post data in remote save success, I want go back to list view.
as before I search apple article introduction storyboard, but in this demo, when user tap add button,direct transfer to list page view :http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/SecondiOSAppTutorial/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011318-CH1-SW1
If I use AFHTTPClient to save data in remote server success, then go back to list page view, or still in add page view and display error message.
any one can give me some suggestions, thanks!
NSString *url = [NSString stringWithFormat:#"%#",api_createworklog];
NSDictionary *params=[NSDictionary dictionaryWithObjectsAndKeys:uname,#"loginname",token,#"token",beginTime
,#"beginTime",content,#"content",address,#"address",projectNameTemp,#"projectName"
,workType,#"workType",workDate,#"workDate",validDate,#"validDate", nil];
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:BASE_URL]];
[client postPath:url parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *responseString = [operation responseString];
NSDictionary *data = [responseString objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode];
NSString *sysCode = [data objectForKey:#"syscode"];
NSString *businessCode = [data objectForKey:#"businesscode"];
if(sysCode != nil && ![sysCode isEqualToString:#""] && businessCode != nil && ![businessCode isEqualToString:#""]){
if([sysCode isEqualToString:ws_access_success] && [businessCode isEqualToString:ws_access_success]){
//[self.navigationController popViewControllerAnimated:YES];
addSuccess = true;
} else{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"添加失败" message:responseString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSString *responseString = operation.responseString;
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"访问服务器异常,添加失败!" message:responseString delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
}];

iOS UIAlertView giving EXC_BAD_ACCESS

I have searched for awhile and tried many things, but I cannot get this error to go away. I have a table that is refreshed by a pull down method. I also use Apple's Reachability to determine internet connectivity. When I run my application WITH internet, and then while the app is running, shut the internet off, my app crashes trying to display a UIAlertView. Although, when I start my app WITHOUT internet and then turn on internet while the app is running and turn it back off, the app does not crash and everything works as it should. Any help would be greatly appreciated.
The error occurs on the [message show] line.
Edited code:
- (void)loadCallList {
NSURL *theURL = [NSURL URLWithString:#"http://www.wccca.com/PITS/"];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection) {
NSLog(#"Reachable");
self.headerHeight = 45.0;
NSData *data = [[NSData alloc] initWithContentsOfURL:theURL];
xpathParser = [[TFHpple alloc] initWithHTMLData:data];
NSArray *elements = [xpathParser searchWithXPathQuery:#"//input[#id='hidXMLID']//#value"];
if (elements.count >= 1) {
TFHppleElement *element = [elements objectAtIndex:0];
TFHppleElement *child = [element.children objectAtIndex:0];
NSString *idValue = [child content];
NSString *idwithxml = [idValue stringByAppendingFormat:#".xml"];
NSString *url = #"http://www.wccca.com/PITS/xml/fire_data_";
NSString *finalurl = [url stringByAppendingString:idwithxml];
xmlParser = [[XMLParser alloc] loadXMLByURL:finalurl];
[callsTableView reloadData];
}
}
else {
NSLog(#"Not Reachable");
self.headerHeight = 0.0;
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"No Internet Connection"
message:#"Please check your internet connection and pull down to refresh."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[message show];
[message release];
}
[pull finishedLoading];
}
I tested the following method using sendAsynchronousRequest:queue:completionHandler: as the method to download data from the URL. It seems to work fine, I can get the else clause to fire, either by messing up the URL or making the timeout interval .1 seconds.
NSURL *theURL = [NSURL URLWithString:#"http://www.wccca.com/PITS/"];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:theURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:5];
[NSURLConnection sendAsynchronousRequest:theRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (error == nil) {
//do whatever with the data. I converted it to a string for testing purposes.
NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#",text);
}else{
NSLog(#"%#",error.localizedDescription);
UIAlertView *message = [[UIAlertView alloc] initWithTitle:#"No Internet Connection" message:#"Please check your internet connection and pull down to refresh." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[message show];
}
}];
You have two problems:
You shouldn't be using Reachability to determine whether there is an internet connection. Reachability is only useful to determine when an offline connection comes back online. Really. Making the networking calls is sometimes enough to power up the radios and connect so if you try to pre-check whether there is an internet connection the radios will remain off.
The second problem is that no synchronous networking calls can be made on the main thread. This includes Reachability and [NSData dataWithContentsOfURL:xxx]. Make them on a secondary thread using Grand Central Dispatch, NSOperationQueues, NSURLConnections, or NSThreads. Otherwise your application can lock up if the network isn't in good shape and the system watchdog timer will kill your app.

Resources