AFNetworking 3.0 setImageWithURLRequest download progress
Asked Answered
B

3

9

Does anyone have a nice working solution for getting the download progress when using the UIImageView+AFNetworking category and AFNetworking 3.0.

This category, which I did use for versions up till 3.0 has stopped working now.

Here is my own experimental version which sadly, for the moment, crashes randomly.

British answered 12/1, 2016 at 12:42 Comment(3)
Did you check this one -> github.com/xmartlabs/XLRemoteImageViewLief
please refer my answer below. I've made a pull request to AFNetworking, unfortunately it's rejected. Till then you can use this, if you don't want to change/upgrade your AFNetworking version.Irmairme
Thats a good effort @iOSEnthusiatic . By the way I also gave them a pullrequest some days ago github.com/AFNetworking/AFNetworking/pull/3306.British
I
2

Here is the modified version of AFNetworking 3.0 in which you can show a progress while loading image from server using UIImageView+AFNetworking category.

https://github.com/rushisangani/AFNetworking

Please replace following files with original AFNetworking files.

UIImageView+AFNetworking.h,
UIImageView+AFNetworking.m,

UIImage+ImageDownloader.h,
UIImage+ImageDownloader.m

NOTE: If you update your pod then this will be removed.

Irmairme answered 23/1, 2016 at 21:37 Comment(0)
P
1

If you look at AFImageDownloader this, it is used by the UIImageView category to download images. In this class you

- (nullable AFImageDownloadReceipt *)downloadImageForURLRequest:  (NSURLRequest *)request
                                                    success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse  * _Nullable response, UIImage *responseObject))success
                                                    failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;

It returns a receipt which has a NSURLSessionDataTask *task property. NSURLSessionDataTask has different properties of how bytes download, expected bytes to receive etc. Perhaps you can use this and achieve your task.

Parfait answered 19/1, 2016 at 7:15 Comment(0)
E
1

You can achieve this by adding few lines in UIImageView+AFNetworking.h

  1. Place this code at top of the file under the import statement

    static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedContext;
    
  2. And you need to register the observer to track the bytes received by adding below line under the function setImageWithURLRequest at the position

    if (cachedImage) {
        // AFNetworking default code
    }
    else{
        // AFNetworking default code
        // Our new lines to track the download
        [self.af_activeImageDownloadReceipt.task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext];
        [self.af_activeImageDownloadReceipt.task addObserver:self forKeyPath:@"countOfBytesReceived" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext];
    }
    
  3. Add this new function at end.

    #pragma mark - NSKeyValueObserving
    
    - (void)observeValueForKeyPath:(NSString *)keyPath
                          ofObject:(id)object
                            change:(__unused NSDictionary *)change
                           context:(void *)context
    {
        if (context == AFTaskCountOfBytesReceivedContext) {
    
            if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesReceived))]) {
                if ([object countOfBytesExpectedToReceive] > 0) {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        //You can do your stuff at here like show progress
                        NSLog(@"Progress : %f",[object countOfBytesReceived] / ([object countOfBytesExpectedToReceive] * 1.0f));
    
                    });
                }
            }
    
            if ([keyPath isEqualToString:NSStringFromSelector(@selector(state))]) {
                if ([(NSURLSessionTask *)object state] == NSURLSessionTaskStateCompleted) {
                    @try {
                        [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(state))];
                        NSLog(@"Image Download Complete");
                        if (context == AFTaskCountOfBytesReceivedContext) {
                            [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived))];
                        }
                    }
                    @catch (NSException * __unused exception) {}
                }
            }
        }
    }
    
Erlina answered 2/5, 2016 at 13:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.