0

I am trying to implement a progress bar for when an image gets downloaded to my app from a server. This is what my relevant code looks like:

NSString *queryStringss = [NSString stringWithFormat:@"%@", uploadURL];
queryStringss = [queryStringss stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
_manager = [AFHTTPRequestOperationManager manager];
_manager.responseSerializer=[AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];

NSString *usernameEncoded = marker.title;

NSDictionary *params = @{@"username": usernameEncoded, @"count": [object valueForKey:@"count"]};

progBar.hidden = NO;

[_manager POST:queryStringss parameters:params success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {

    [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
        float prog = (totalBytesWritten / (totalBytesExpectedToWrite * 1.0f) * 100);
        dispatch_async(dispatch_get_main_queue(), ^(void){
           [progBar setProgress:prog];
        });
        NSLog(@"%f%% Uploaded", (totalBytesWritten / (totalBytesExpectedToWrite * 1.0f) * 100));
    }];

    NSLog(@"Success: %@ ***** %@", operation.responseString, responseObject);
    NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:responseObject[@"image"] options:0];
    image.image = [UIImage imageWithData:decodedData scale:300/2448];
    dispatch_async(dispatch_get_main_queue(), ^(void){
        [image setHidden:NO];
        [respondButton setHidden:NO];
        [xButton setHidden:NO];
    });
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@ ***** %@", operation.responseString, error);
}];

Also, in viewDidLoad, I initialize the progress bar (which is declared in the @implementation block:

progBar = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
[progBar setFrame:CGRectMake(10, 264, 300, 10)];
[self.view addSubview:progBar];
progBar.hidden = YES;

My code works - I just don't see a progress bar displayed at any point.

ewizard
  • 2,801
  • 4
  • 52
  • 110
  • Have you added the progress bar to a view? – brandonscript Dec 19 '15 at 02:56
  • @remus no i haven't, i thought the `uiprogressview` is a view... – ewizard Dec 19 '15 at 03:36
  • Yup, but if you don't add it to a container view with a frame (e.g. `yourViewController.view` you won't be able to see it. You want `[view addSubview:progBar]`. – brandonscript Dec 19 '15 at 03:36
  • @remus ok thanks ill try that now – ewizard Dec 19 '15 at 03:37
  • @remus how do i handle the `uiview`? I initialized it in `viewdidload` and added the `uiprogview` using `addsubview` and did `sethidden:YES - then where the afnetworking code is...i did `[view setHidden:NO]` (basically) and still nothing...could u provide an answer showing how to use it with my code? – ewizard Dec 19 '15 at 03:44

2 Answers2

0

Looks like you haven't added the progress bar to a view. Let's assume you're doing this in viewDidLoad of a view controller:

- (void)viewDidLoad 
{
    // progBar needs to be a @property
    _progBar = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
    [_progBar setFrame:CGRectMake(0, 10, 300, 10)];
    [self.view addSubview:_progBar];
    _progBar.hidden = YES;
}

- (void)doYourHTTPCall 
{
    _progBar.hidden = NO;
    NSString *queryStringss = [NSString stringWithFormat:@"%@", uploadURL];
    queryStringss = [queryStringss stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    _manager = [AFHTTPRequestOperationManager manager];
    _manager.responseSerializer=[AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];

    NSString *usernameEncoded = marker.title;

    NSDictionary *params = @{@"username": usernameEncoded, @"count": [object valueForKey:@"count"]};

    [_manager POST:queryStringss parameters:params success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {

        [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
            float prog = (totalBytesWritten / (totalBytesExpectedToWrite * 1.0f) * 100);
            dispatch_async(dispatch_get_main_queue(), ^(void){
               [progBar setProgress:prog];
            });
            NSLog(@"%f%% Uploaded", (totalBytesWritten / (totalBytesExpectedToWrite * 1.0f) * 100));
        }];

        NSLog(@"Success: %@ ***** %@", operation.responseString, responseObject);
        NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:responseObject[@"image"] options:0];
        image.image = [UIImage imageWithData:decodedData scale:300/2448];
        dispatch_async(dispatch_get_main_queue(), ^(void){
            [image setHidden:NO];
            [respondButton setHidden:NO];
            [xButton setHidden:NO];
        });
    }
    failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@ ***** %@", operation.responseString, error);
    }];
}
brandonscript
  • 68,675
  • 32
  • 163
  • 220
  • had to go to sleep last night, thank you for posting! however still no luck - I have everything exactly like you said. – ewizard Dec 19 '15 at 12:27
  • I am wondering if I am allowed to use the `operation` variable like this with the progress bar inside the http call block?... – ewizard Dec 19 '15 at 12:27
  • 1
    Do the NSLogs work ok? You see the progress in the console? – brandonscript Dec 19 '15 at 15:41
  • actually no - `NSLog(@"%f%% Uploaded", (totalBytesWritten / (totalBytesExpectedToWrite * 1.0f) * 100)); ` never gets executed. – ewizard Dec 19 '15 at 19:10
  • that means that the whole block is being ignored i assume, right? – ewizard Dec 19 '15 at 19:11
  • i think what im going to do is rewrite the code so that the `operation` isn't included in the `POST` block...because that is how i see everyone doing it on stackoverflow. – ewizard Dec 19 '15 at 19:12
  • actually - here is someone trying to do it my way...but i don't understand the answer http://stackoverflow.com/questions/21951700/afnetworking-2-0-http-post-progress do you? – ewizard Dec 19 '15 at 19:14
  • also im a little confused - should i be doing stuff for download or upload? my code is retrieving an image from my computer (server) to my phone. – ewizard Dec 19 '15 at 19:20
  • i figured it out - i am downloading not uploading...but i had to refactor my code to get it to work - i read that it is not possible to just do it in the `success` block. – ewizard Dec 19 '15 at 20:01
0

I had to refactor my code like this - the only weird thing is that the percentDone number was not 0.0 - 1.0 (because of bytes I'm assuming). It was actually a negative number, starting near -1,000 and going to -110,000 (or something like that) so as you can see, I had to multiply that number by a very small negative fraction number to move the decimal point over so that it was between 0.0 and 1.0:

NSString * downloadURL = @"http://192.168.1.3/getimage.php";
NSLog(@"downloadImageURL: %@", downloadURL);`

NSString *queryStringss = [NSString stringWithFormat:@"%@", downloadURL];
queryStringss = [queryStringss stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
_manager = [AFHTTPRequestOperationManager manager];
_manager.responseSerializer=[AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];`

NSString *usernameEncoded = marker.title;

NSDictionary *params = @{@"username": usernameEncoded, @"count": [object valueForKey:@"count"]};

NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:downloadURL parameters:params error:&error];

AFHTTPRequestOperation *requestOperation = [_manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"operation success: %@\n %@", operation, responseObject);

    NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:responseObject[@"image"] options:0];
    image.image = [UIImage imageWithData:decodedData scale:300/2448];
    dispatch_async(dispatch_get_main_queue(), ^(void){
        [progBar setHidden:YES];
        [image setHidden:NO];
        [respondButton setHidden:NO];
        [xButton setHidden:NO];
    });
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

[requestOperation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
    progBar.hidden = NO;
    double percentDone = ((double)totalBytesRead / (double)totalBytesExpectedToRead) * -.000001;
    NSLog(@"progress updated(percentDone) : %f", percentDone);
    [progBar setProgress:percentDone];
}];

[requestOperation start];
ewizard
  • 2,801
  • 4
  • 52
  • 110