Erika Electra
Erika Electra

Reputation: 1883

AFNetworking - no response on all but the final request in a for loop

I've tried several variants of AFNetworking classes, and this is just one example, but in UIImageView+AFNetworking, for instance, I cannot make requests in a for loop and actually get more than one frame back. Meaning, I don't understand why only ever the last response comes back, in the success block, where the others just get sent out but hang indefinitely:

for (unsigned int i = 1; i <= numFrames; ++i)
    {
        // Fire a request
        NSLog(@"REQUEST MADE FOR FRAME #%u", i);

        // get ith frame
        NSString* urlString = [NSString stringWithFormat:@"%@%u.png", urlPrefix, i];
        NSURL* frameURL = [NSURL URLWithString:urlString];
        NSURLRequest* request = [[NSURLRequest alloc] initWithURL:frameURL];

        [_myImage setImageWithURLRequest:request
                        placeholderImage:spinnerImage
                                 success:^(NSURLRequest* request, NSHTTPURLResponse* response, UIImage* image)
         {
             if (image != nil)
             {
                 NSLog(@"Frame %u DONE!", i);
                 frames[i - 1] = image;
             }
             else
             {
                 NSLog(@"Frame #%u is nil, expected %lld bytes!", i, response.expectedContentLength);
             }
         }
                                       failure:^(NSURLRequest* request, NSHTTPURLResponse* response, NSError* error)
         {
             NSLog(@"REASON: %@ - %@", error, [error userInfo]);
         }];
    }

The output I get in the console is

2016-03-06 20:04:45.795 [2625:383915] Reachability Flag Status: -R ------- networkStatusForFlags
2016-03-06 20:04:45.825 [2625:383915] REQUEST MADE FOR FRAME #1
2016-03-06 20:04:45.833 [2625:383915] REQUEST MADE FOR FRAME #2
2016-03-06 20:04:45.834 [2625:383915] REQUEST MADE FOR FRAME #3
2016-03-06 20:04:45.921 [2625:383915] [Crashlytics] Version 3.7.0 (102)
2016-03-06 20:04:46.388 [2625:383915] Reachability Flag Status: -R ------- networkStatusForFlags
2016-03-06 20:04:46.389 [2625:383915] Reachability Flag Status: -R ------- networkStatusForFlags
2016-03-06 20:04:46.389 [2625:383915] Reachability Flag Status: -R ------- networkStatusForFlags
2016-03-06 20:04:46.468 [2625:383915] Frame 3 DONE!

If I change numFrames to something like 4, or 10, or 50, the same thing happens: a request is placed for every frame, but only the last one ever finishes. The other ones don't return anything, either a nil image in the success block, or an error in the failure block.

My question is, what am I doing wrong? Or better yet, in what way can we make a bunch of frame requests (not even necessarily sequentially or synchronously) and have them all return without hanging? I've checked network reachability and the actual URLs, and everything is normal there. There has to be a way to make a bunch of requests at once, and actually hear back from all of them when the URL and network accessibility all check out OK.

I have tried a few things:

(1) waiting a long time

(2) checking for timeout and errors

(3) putting the request for the second frame in the success block of the first (and the second request gets made, but doesn't hear back)

(4) other versions of AFNetworking

with no luck!

There has to be a better API than this for pulling frames from the network, because it's a common operation when putting together an animation...

Upvotes: 0

Views: 499

Answers (2)

Hong Duan
Hong Duan

Reputation: 4294

When using UIImageView+AFNetworking, one UIImageView will only keep a single request at a time, and the previous requests will be canceled, so only the last request works. See the source code for reference: UIImageView+AFNetworking.m.

You can use the AFImageDownloader API directly to download multiple images.

Upvotes: 1

Bharat Modi
Bharat Modi

Reputation: 4178

Your code looks fine, try using this code for downloading images, i'm able to use in loops successfully. Thats what i can help you for now.

NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];

AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];

requestOperation.responseSerializer = [AFImageResponseSerializer serializer];

[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

    [imageView setImage: responseObject];

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Image error: %@", error);
}];
[requestOperation start];

Upvotes: 2

Related Questions