繁体   English   中英

如何使用AFNetworking在缓存中的UIImageView中显示图像?

[英]How to show Image in UIImageView from cache using AFNetworking?

这是我的代码,如何使用AFNetworking从URL下载图像并将其保存到文档目录中。

现在,我的问题是图像是否已从URL下载,然后从缓存加载图像,而不是重新下载图像。 我想使用AFNetworking做到这一点。 我知道此问题的解决方案在#import "UIKit+AFNetworking/UIKit+AFNetworking.h"

如果有人对如何提供帮助有任何想法,请帮助我解决问题。

#import "ViewController.h"

#define URL @"https://upload.wikimedia.org/wikipedia/commons/e/ec/USA-NYC-American_Museum_of_Natural_History.JPG"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.progressBar.hidden = YES ;
    self.lblProgressStatus.hidden = YES;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)Action:(UIButton *)sender
{
    self.progressBar.hidden = NO ;
    self.lblProgressStatus.hidden = NO ;
    self.ActionDownload.enabled = NO ;

    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];

    NSURL *strURL = [NSURL URLWithString:URL];
    NSURLRequest *request = [NSURLRequest requestWithURL:strURL];

    NSProgress *progress;

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:&progress destination:^NSURL *(NSURL *targetPath, NSURLResponse *response)
        {
                NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
                return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]];
        }
        completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error)
        {
                [self.progressBar setHidden:YES];
                self.lblProgressStatus.text = @"Download completed" ;
                NSLog(@"File downloaded to: %@", filePath);

                NSString * strTemp = [NSString stringWithFormat:@"%@", filePath];
                NSArray *components = [strTemp componentsSeparatedByString:@"/"];
                id obj = [components lastObject];
                NSLog(@"%@", obj);

            NSString *docPath = [NSSearchPathForDirectoriesInDomains (NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
            NSString *strFilePath = [NSString stringWithFormat:@"%@/%@",docPath, obj];

            BOOL fileExists=[[NSFileManager defaultManager] fileExistsAtPath:strFilePath];

            if (!fileExists)
            {
                NSLog(@"File Not Found");
            }
            else
            {
                UIImage * image = [UIImage imageWithContentsOfFile:strFilePath];
                self.imageView.image = image ;
            }
            [progress removeObserver:self forKeyPath:@"fractionCompleted" context:NULL];

        }];

    [self.progressBar setProgressWithDownloadProgressOfTask:downloadTask animated:YES];
    [downloadTask resume];

    [progress addObserver:self
               forKeyPath:NSStringFromSelector(@selector(fractionCompleted))                  options:NSKeyValueObservingOptionNew
                  context:NULL];

}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"fractionCompleted"])
    {
        NSProgress *progress = (NSProgress *)object;
        int temp = progress.fractionCompleted * 100 ;
       // NSLog(@"%d", temp);
       NSString * strTemp = @"%";

        dispatch_async(dispatch_get_main_queue(), ^{
            // Update the UI
            self.lblProgressStatus.text = [NSString stringWithFormat:@"%d %@", temp, strTemp];
        });
    }
    else
    {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

@end

您可以使用在UIImageView+AFNetworking定义的此方法下载图像:

[imageView setImageWithURL:[NSURL URLWithString:URL] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
    if ([[extension lowercaseString] isEqualToString:@"png"]) { 
        [UIImagePNGRepresentation(image) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"png"]] options:NSAtomicWrite error:nil];
    } else if ([[extension lowercaseString] isEqualToString:@"jpg"] || [[extension lowercaseString] isEqualToString:@"jpeg"]) {
        [UIImageJPEGRepresentation(image, 1.0) writeToFile:[directoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", imageName, @"jpg"]] options:NSAtomicWrite error:nil];
    }
} failure:NULL];

即使成功块从高速缓存中获取图像,也会调用成功块。 希望能有所帮助!

默认情况下,它使用缓存。 要进行测试,请访问您有权访问图像的url,然后删除该图像,然后再次加载,然后您将看到它已被缓存:D如果图像很大,则有时它们不会被缓存。

如果要增加此缓存的大小,请将其放入您的应用程序委托中:

[[NSURLCache sharedURLCache] setMemoryCapacity:(20*1024*1024)];
[[NSURLCache sharedURLCache] setDiskCapacity:(200*1024*1024)];

编辑RE:评论:

如果您只想将图像下载一次到文档路径,那么测试图像是否已经存在并且是否应该下载的最佳方法也许就是可以创建的测试。 例如,如果文档中已经存在图像的最后一个路径组件(图像文件路径的最后一部分),请不要下载它,否则请下载它。

编辑:进一步的评论

在UIKit + AFNetworking / UIImageView + AFNetworking.h中

/ **从指定的URL异步下载图像,并在请求完成后进行设置。 对接收者的任何先前图像请求将被取消。 如果图像在本地缓存,则立即设置图像,否则将立即设置指定的占位符图像,然后在请求完成后设置远程图像。 默认情况下,URL请求的Accept标头字段值为“ image / *”,缓存策略为NSURLCacheStorageAllowed ,超时间隔为30秒,并且设置为不处理cookie。 要以不同方式配置URL请求,请使用setImageWithURLRequest:placeholderImage:success:failure: @param url用于图像请求的URL。 * /

- (void)setImageWithURL:(NSURL *)url;

这看起来就像您要寻找的

使用:

#import <AFNetworking/UIKit+AFNetworking.h> 

和使用

NSURL *strURL = [NSURL URLWithString:@"http://www.example.com/image.jpg"];
[imageview setImageWithURL:strURL];

我建议您使用此库https://github.com/rs/SDWebImage

因此,您可以执行以下操作:

- (void)loadImage:(NSURL *)url
{
    __block UIImage *image = [[SDImageCache sharedImageCache] queryDiskCacheForKey:[url absoluteString]];

    if(!image) {

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        [request setTimeoutInterval: 30.0]; // Will timeout after 30 seconds
        [NSURLConnection sendAsynchronousRequest:request
                                           queue:[NSOperationQueue currentQueue]
                               completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {

                                   if (data != nil && error == nil) {

                                       image = [UIImage imageWithData:data];

                                       NSData *pngData = UIImagePNGRepresentation(image);
                                       [[SDImageCache sharedImageCache] storeImage:image imageData:pngData forKey:[url absoluteString] toDisk:YES];
                                   }
                                   else {
                                       // There was an error, alert the user
                                       NSLog(@"%s Error: %@", __func__, error);
                                   }
                               }];
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM