mardi 13 octobre 2015

Best way to implement this while downloading from AWS3?

Ill try to explain this as best as i can. Im using "AFAmazonS3Manager.h" which is a subclass that uses AFNetworking to call AmazonA3 functionality. Now i already wrote all my code to be encapsulated in its own class. This class downloads any items i need off of aws3 and saves them into the local system. All fine and dandy. Now im trying to implement a progress indicator, this is where my trouble is abrewing. On the class level i added a dispatch_group to wait for all downloads to happen then be notified when the download happens. Again it works fine for me. heres an example of what im doing

- (void)getContentLengthOfMediaItem:(UFPMediaObject*)media_object contentLength:(float*)content_length{

dispatch_group_enter(_amazon_dispatch_group);
[_amazon_manager.requestSerializer setBucket:media_object.aws_media_bucket_name];
[_amazon_manager headObjectWithPath:[media_object shortpathForMediaFile]
                            success:^(NSHTTPURLResponse *response) {

                                NSString *lengthString = [[response allHeaderFields] objectForKey:@"Content-Length"];
                                *content_length = [lengthString longLongValue];
                                dispatch_group_leave(_amazon_dispatch_group);

                            } failure:^(NSError *error) {

                                NSLog(@"Error getting metadata for video %@",[media_object shortpathForMediaFile]);
                                NSLog(@"%@",error.localizedDescription);
                                dispatch_group_leave(_amazon_dispatch_group);

                            }];

}

I need to 1 be able to return the content_length to the calling class. Im trying to pass it by reference here but it keeps returning 0 instead of the number im getting from content length. So thats one issue. I mean i could just add a class level float variable and assign it in the success block but i dont want to do that. It doesnt seem like the right way to do it.

Heres something that i have working and thought i could write the content_length function the same way but my content_length function isnt working.

- (void)checkIfFileIsOver20MB:(UFPMediaObject *)media_object isOverTwentyMegabytes:(BOOL*)overTwenty{

dispatch_group_enter(_amazon_dispatch_group);
[_amazon_manager.requestSerializer setBucket:media_object.aws_media_bucket_name];
[_amazon_manager headObjectWithPath:[media_object shortpathForMediaFile]
                            success:^(NSHTTPURLResponse *response) {

                                NSString *lengthString = [[response allHeaderFields] objectForKey:@"Content-Length"];
                                NSString *byte_count_string = [NSByteCountFormatter stringFromByteCount:[lengthString longLongValue] countStyle:NSByteCountFormatterCountStyleFile];
                                NSInteger megabytes = [byte_count_string integerValue];

                                if(megabytes > 20)
                                    *overTwenty = TRUE;
                                else
                                    *overTwenty = FALSE;
                                dispatch_group_leave(_amazon_dispatch_group);


                            } failure:^(NSError *error) {

                                NSLog(@"Error getting metadata for video %@",[media_object shortpathForMediaFile]);
                                NSLog(@"%@",error.localizedDescription);
                                *overTwenty = FALSE;
                                dispatch_group_leave(_amazon_dispatch_group);

                            }];

}

When this group leaves and im back in the calling class. The Boolean isOver20MB has the value set within the success block. So i thoguht i could follow the same methodology for a float. But its not working.

Also anothet problem for me is that i want to update the progress indicator once its downloading. Now theres a nice block function that updates the progress in like so.

dispatch_group_enter(_amazon_dispatch_group);
[_amazon_manager.requestSerializer setBucket:media_object.aws_thumbnail_bucket];
[_amazon_manager getObjectWithPath:[media_object shortpathForThumbnailFile]
                          progress:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {


                          } success:^(id responseObject, NSData *responseData) {
                              @autoreleasepool {

                                  [UFPMediaLocalStorage saveDataToLocalStorageInFolder:kUFPLocalStorageFolderThumbnails
                                                                     subdirectory:media_object.aws_thumbnail_file_path
                                                                             data:responseData
                                                                         filename:media_object.aws_thumbnail_file_name];
                                  responseObject = nil;
                                  responseData = nil;
                                  dispatch_group_leave(_amazon_dispatch_group);

                              }
                          } failure:^(NSError *error) {

                              NSLog(@"Error Downloading Thumbnail for file %@",[media_object shortpathForThumbnailFile]);
                              NSLog(@"%@",[media_object shortpathForThumbnailFile]);
                              dispatch_group_leave(_amazon_dispatch_group);

                          }];

How am i able to get the progress indicator i need to update, which is in the calling viewcontroller subview to get the values from the progress block? I am going to pass the actual view for the progress view in the function and just update its progress within the success block but i dont want to do that. Since i cant just one day remove this code and plug it into another project like that. Since now the class i wrote for downloading Amazon data will be coupled with the progress indicator im creating. I know its hard to understand. but if anyone can help me go around the implementation i described that would be great.

It just seems like im missing one part mostly. Which is being able to pass back the values i need from within the blocks returning the values.




Aucun commentaire:

Enregistrer un commentaire