3

I downloaded some examples in order to learn Ios.

The examples include:

  • AFNetworking;
  • Inapp purchase (from RayW);
  • MBProgressHud;

In my viewcontroller i push a UIbutton which triggers the Inapp purchase Singleton example and start download a file from my server with AFHTTPRequestOperation. This part of communication works. But what i want to achieve is to have my hud updated while downloading. As the file is >10Mb.

So, the question is how do i update the hud with the progress of the download? I try to draw it down.

  • I push the button in Viewcontroller and the hud will displayed;

    • --> request will sent to the Singleton InApp helper class which handles the networking part;

      • --> After that the AFHTTPRequestOperation will be called inside the singleton class for the download of file;

        • ---> During this download i use the setDownloadProgressBlock method for the progress.

But how do i sent the progress info back to my hud in the viewcontroller?

Thanks.

KevinC
  • 79
  • 2
  • 8

2 Answers2

3

This is what I did with a similar problem, following @mattt advice. My Singleton InApp helper has productDownloadURL ivar and a prepareForDownload method that returns an AFHTTPRequestOperation to the caller:

- (AFHTTPRequestOperation * )prepareForDownload:(NSString *)productIdentifier
{
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:_productDownloadURL]];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:productIdentifier];
    operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];

    return  operation;
}

My RootViewController make the request by using AFHTTPRequestOperation and sets downloadProgress/success/failure blocks as below:

AFHTTPRequestOperation *operation = [[InAppRageIAPHelper sharedHelper] prepareForDownload:productIdentifier];
[operation setDownloadProgressBlock:^(NSInteger bytesRead, NSInteger totalBytesRead, NSInteger totalBytesExpectedToRead) {
     float percentDone = ((float)((int)totalBytesRead) / (float)((int)totalBytesExpectedToRead));    
     [(UIProgressView *)_hud.customView setProgress:percentDone];
     _hud.labelText = [NSString stringWithFormat:@"%f",percentDone];
 }];

 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
   _hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"success.png"]];
   [self performSelector:@selector(dismissHUD:) withObject:nil afterDelay:1.5];
 } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
   _hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"error.png"]];
 }];
 [operation start];

hud is a MBProgressHUD. You could also enhance the progress display using MBProgressHUDModeDeterminate mode.

microspino
  • 7,693
  • 3
  • 48
  • 49
  • 1
    hey, was wondering as to where and how you instantiated the mbprogresshud? I'm having the same issue, the examples on the afnetworking github only uses activityindicator. i wanted to use mbprogresshud for this one. – gdubs Jun 27 '13 at 01:17
2

Make the request from a controller, and keep a reference to the operation when you create and enqueue it in a variable (you can do this by creating an intermediary operation object with HTTPOperationWithRequest:success:failure, and manually doing enqueueHTTPOperation:.

In the body ofsetDownloadProgressBlock, set the progress property of the progress view (you need to divide bytesReceived by bytesExpectedToReceive in order to normalize between 0.0 and 1.0.

mattt
  • 19,544
  • 7
  • 73
  • 84
  • Could you expand your answer a little bit. I've the same thing to do and I can't understand well ho to use "intermediary op. object" THX – microspino Mar 11 '12 at 10:46
  • Rather than doing `AFHTTPClient -getPath:parameters:success:failure:`, create an operation, configure it by callback blocks (e.g. with `setDownloadCallbackBlock:`), and then enqueue it. – mattt Mar 20 '12 at 17:38