Note that there are some explanatory texts on larger screens.

plurals
  1. PONSURLConnection Hangs under certain conditions
    text
    copied!<p>I'm posting to a RESTful webservice and receiving a response, this works great if I'm getting back only a few records however there is a threshold where didReceiveData: stops being called (6 records) and it just hangs. (does not matter what records, just the number)</p> <p>I can't seem to figure out why. I'm getting a status message of 200 application/json in didReceiveResponse: however that's the last I hear from my connection.</p> <p>From other clients I can get the full data with any number of records so it's related to my NSURLConnection code. </p> <p>See full NSURLConnection Post class below. </p> <p>the .h</p> <pre><code>#import &lt;Foundation/Foundation.h&gt; #import "MBProgressHUD.h" @protocol PostJsonDelegate &lt;NSObject, NSURLConnectionDelegate&gt; @optional - (void) downloadFinished; - (void) downloadReceivedData; - (void) dataDownloadFailed: (NSString *) reason; @end @interface PostURLJson : NSObject { NSMutableData *receivedData; int expectedLength; MBProgressHUD *HUD; } @property (strong, nonatomic) NSMutableData *receivedData; @property (weak) id &lt;PostJsonDelegate&gt; delegate; @property (assign, nonatomic) int expectedLength; + (id)initWithURL:(NSString *)url dictionary:(NSDictionary *)dictionary withDelegate:(id &lt;PostJsonDelegate&gt;)delegate; @end </code></pre> <p>the .m</p> <pre><code>#import "PostURLJson.h" #define SAFE_PERFORM_WITH_ARG(THE_OBJECT, THE_SELECTOR, THE_ARG) (([THE_OBJECT respondsToSelector:THE_SELECTOR]) ? [THE_OBJECT performSelector:THE_SELECTOR withObject:THE_ARG] : nil) @implementation PostURLJson @synthesize delegate; @synthesize receivedData; @synthesize expectedLength; + (id)initWithURL:(NSString *)url dictionary:(NSDictionary *)dictionary withDelegate:(id &lt;PostJsonDelegate&gt;)delegate { if (!url) { NSLog(@"Error. No URL"); return nil; } PostURLJson *postJson = [[self alloc] init]; postJson.delegate = delegate; [postJson loadWithURL:url dictionary:dictionary]; return postJson; } - (void)loadWithURL:(NSString *)url dictionary:(NSDictionary *)dictionary { [self setExpectedLength:0]; receivedData = [[NSMutableData alloc] init]; NSError* error; NSDictionary *tmp = [[NSDictionary alloc] initWithDictionary:dictionary]; NSData *postdata = [NSJSONSerialization dataWithJSONObject:tmp options:0 error:&amp;error]; NSString *someString = [[NSString alloc] initWithData:postdata encoding:NSASCIIStringEncoding]; NSLog(@"%@",someString); NSString *postLength = [NSString stringWithFormat:@"%d", [postdata length]]; NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init]; [request setURL:[NSURL URLWithString:url]]; [request setHTTPMethod:@"POST"]; [request setTimeoutInterval:10.0f]; [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setHTTPBody:postdata]; NSURLConnection *connection = [NSURLConnection connectionWithRequest:request delegate:self]; [connection start]; [self setLoadingModeEnabled:YES]; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *) response; int errorCode = httpResponse.statusCode; NSString *fileMIMEType = [[httpResponse MIMEType] lowercaseString]; NSLog(@"%d",errorCode); NSLog(@"%@",fileMIMEType); [receivedData setLength:0]; // Check for bad connection expectedLength = [response expectedContentLength]; if (expectedLength == NSURLResponseUnknownLength) { NSString *reason = [NSString stringWithFormat:@"Invalid URL"]; SAFE_PERFORM_WITH_ARG(delegate, @selector(dataDownloadFailed:), reason); [connection cancel]; return; } } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [receivedData appendData:data]; SAFE_PERFORM_WITH_ARG(delegate, @selector(downloadReceivedData), nil); } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { SAFE_PERFORM_WITH_ARG(delegate, @selector(downloadFinished), nil); [self setLoadingModeEnabled:NO]; } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { NSLog(@"Something went wrong..."); HUD.labelText = @"Something went wrong..."; [self performSelector:@selector(didFailHideHud) withObject:nil afterDelay:2]; } - (void)setLoadingModeEnabled:(BOOL)isLoading { //when network action, toggle network indicator and activity indicator if (isLoading) { [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; UIWindow *window = [UIApplication sharedApplication].keyWindow; HUD = [[MBProgressHUD alloc] initWithWindow:window]; [window addSubview:HUD]; HUD.labelText = @"Loading"; [HUD show:YES]; } else { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; [HUD hide:YES]; [HUD removeFromSuperview]; } } -(void)didFailHideHud { [HUD hide:YES]; [HUD removeFromSuperview]; } @end </code></pre> <p><strong>Edit</strong> Server was not giving back a valid length after a certain size triggering NSURLResponseUnknownLength which I had mistakenly not logged so I was not getting my "Invalid URL" message in the console. </p> <pre><code>if (expectedLength == NSURLResponseUnknownLength) { NSString *reason = [NSString stringWithFormat:@"Invalid URL"]; SAFE_PERFORM_WITH_ARG(delegate, @selector(dataDownloadFailed:), reason); [connection cancel]; return; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload