3

I was trying to use MBProgressHUD with NSURLConnection.

The example in Demo project of MBProgressHUD reports:

- (IBAction)showURL:(id)sender {
    NSURL *URL = [NSURL URLWithString:@"https://github.com/matej/MBProgressHUD/zipball/master"];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [connection start];
    [connection release];

    HUD = [[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES] retain];
    HUD.delegate = self;
}



- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    expectedLength = [response expectedContentLength];
    currentLength = 0;
    HUD.mode = MBProgressHUDModeDeterminate;
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    currentLength += [data length];
    HUD.progress = currentLength / (float)expectedLength;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]] autorelease];
    HUD.mode = MBProgressHUDModeCustomView;
    [HUD hide:YES afterDelay:2];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    [HUD hide:YES];
}

Running it, the HUD in determinate mode spins fine.

I tried to implement this, but here

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
        currentLength += [data length];
        HUD.progress = currentLength / (float)expectedLength;
    }

the circle is empty and not filled.

I don't know if it depends on the dimension of the requested url.

I request to download a plist (~80 kb) from my website, but the circle keeps being empty and console reports

<Error>: void CGPathAddArc(CGPath*, const CGAffineTransform*, CGFloat, CGFloat, CGFloat, CGFloat, CGFloat, bool): invalid value for start or end angle.

I even tried to do this way:

float progress = 0.0f;
    while (progress < 1.0f) {
        progress += 0.01f;
        HUD.progress = progress;
    }

But now the circle is completely full and not doing any animation.

I think it depends on the dimension of the requested url, but i'm not so sure, does anyone know how to fix this?

Phillip
  • 4,276
  • 7
  • 42
  • 74

3 Answers3

8

I solved the problem this way, switching from NSURLRequest to NSMutableURLRequestand setting the value none to the encoding (previously in gzip)

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:anURL];
[request addValue:@"" forHTTPHeaderField:@"Accept-Encoding"];
Phillip
  • 4,276
  • 7
  • 42
  • 74
  • This does indeed work around the issue, but why? Can you explain why this causes the server to return the content length when it otherwise wouldn't? – Johannes Fahrenkrug Jan 14 '15 at 19:20
  • 2
    Having same issue with `NSURLSession` and it was returning `NSURLSessionTransferSizeUnknown`(-1) for totalexpectedbytes in response for a download. This situation most likely occurs when server returns a "gzip"ed response and your answer put me in the right direction. Setting blank for "Accept-Encoding" tells the the server that the client is not ready to accept the response in any specific format like "gzip". So server simply bypasses "gzip"ping the response stream and returns the raw bytes. Fortunately `NSURLSession` (and `NSURLconnection`) could get the expected no. of bytes from it. – Ayan Sengupta Apr 25 '16 at 02:39
6

You should check the value of [response expectedContentLength] in didReceiveResponse.

A http server can omit the "Content-Length" header and use "Transfer-Encoding: chunked" instead. In that case the content length is not known a priori and [response expectedContentLength] returns NSURLResponseUnknownLength (which is -1)`.

I could imagine that setting HUD.progress to a negative value causes the CGPathAddArc console messages.

According to the documentation, it can also happen that the accumulated currentLength becomes larger than the expected response length, so you should check for that also.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • You were right. The value is -1. Is there anything i can do to fix this? – Phillip Sep 02 '12 at 15:29
  • 1
    @Pheel: There is nothing you can do on the client side. If the server uses "Transfer-Encoding: chunked" then you just don't know how many bytes to expect. – Martin R Sep 02 '12 at 15:31
0

In swift i solved this issue by sending empty string in Accept-Encoding header field of the url request. Total bytes expected to write now returns the actual size in bytes of the file being downloaded.

var request = URLRequest(url: url)
request.addValue("", forHTTPHeaderField: "Accept-Encoding")
Kegham K.
  • 1,589
  • 22
  • 40