thedp
thedp

Reputation: 8516

Am I using correctly the requestImageForRequest at DFImageManager?

I'm using a lib called DFImageManager, and I'm not quite sure I'm going with it the right way.

I was led to believe that within the completion block of requestImageForRequest the info can be used to detect if the request was a success.

However, 10% of the time the info is nil but the image has a value.

What the info param is for? When the info is nil, can I still use the value of image?

DFImageRequestOptions *options = [[DFImageRequestOptions alloc] init];
options.expirationAge = 60;

DFImageRequest *request = [DFImageRequest requestWithResource:[NSURL URLWithString:imageURL] targetSize:imageView.frame.size contentMode:DFImageContentModeAspectFill options:options];

[[DFImageManager sharedManager] requestImageForRequest:request completion:^(UIImage *image, NSDictionary *info) {

        if (info != nil) {

            [imageView setImage:image];
        }
        else {

            // use a placeholder
        }
}];

Upvotes: 0

Views: 207

Answers (2)

kean
kean

Reputation: 1561

Completion block is guaranteed to be called on the main thread. Completion block is called synchronously when the requested image can be retrieved from the memory cache and the request was made on the main thread.

This is the case when info is nil. The implementation is similar to the PHImageManager, which sometimes calls completion blocks synchronously (instead of asynchronously) based on the request. This is necessary so that you could reload your UI without worrying about drawing frames with empty image views, when the images are actually available in the memory cache. And a single requestImageForRequest method keeps memory caching transparent to the client.

What the info param is for?

If holds an error when there is one (see DFImageInfoErrorKey key). And a requestID (DFImageInfoRequestIDKey). But the info is nil, when the request is handled by the memory cache.

When the info is nil, can I still use the value of image?

Yes, you can. You should always check if the image is not nil instead of checking the info:

if (image != nil) {
    [imageView setImage:image];
} else {
    // use a placeholder
    NSError *error = info[DFImageInfoErrorKey];
    // handle a specific error (if there is one)
}

I'm going to make things much more obvious with nullability in the next release:

  • The requestID should be nonnull. The info should be nonnull (even when the request can be handled by the memory cache) and should always contain a requestID.
  • The request and its resource should both be nonnull.
  • Image manager should raise an exception when the request is invalid (unsupported asset).

Upvotes: 2

A. Trejo
A. Trejo

Reputation: 660

I use DFImageManager for my iWatch app and works! very good! Load the images quickly. I hope that help you.

Code:

NSURL *imageURL = [NSURL URLWithString:dataObject.thumbnail];

        DFImageRequestOptions *options = [DFImageRequestOptions new];
        options.allowsClipping = YES;
        options.progressHandler = ^(double progress){
            // Observe progress
        };
        options.userInfo = @{ DFURLRequestCachePolicyKey : @(NSURLRequestReturnCacheDataDontLoad) };

        DFImageRequest *request = [DFImageRequest requestWithResource:imageURL targetSize:CGSizeMake(100.f, 100.f) contentMode:DFImageContentModeAspectFill options:options];

        [[DFImageManager sharedManager] requestImageForRequest:request completion:^(UIImage *image, NSDictionary *info) {
            // Image is resized and clipped to fill 100x100px square

            if (info != nil) {

                [self.iboGroup setBackgroundImage:image];

            }else
            {
                NSError *error = info[DFImageInfoErrorKey];
                NSLog(@"error %@", error);
            }

        }];

Upvotes: 0

Related Questions