Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 具有永久缓存的sdwebimage_Ios_Sdwebimage - Fatal编程技术网

Ios 具有永久缓存的sdwebimage

Ios 具有永久缓存的sdwebimage,ios,sdwebimage,Ios,Sdwebimage,我正在开发一个iOS应用程序,它需要SDWebImage将图片永久缓存到手机上 SDWebImage代码中存在过期设置,我是否应该将过期时间设置为较大的值以永久存储缓存 既然我想永久缓存图片,我应该将它们存储到一个专用文件夹中,还是默认目录就足够了?我的应用程序需要这些图片在应用程序关闭、重新打开以及手机重新启动时保持不变 如果我想永久缓存图片,除了将过期时间设置为一个大值之外,还有什么需要注意的吗 谢谢 不幸的是,SDWebImage没有提供这样的功能 因此,为了利用SDWebImage提供的

我正在开发一个iOS应用程序,它需要SDWebImage将图片永久缓存到手机上

  • SDWebImage代码中存在过期设置,我是否应该将过期时间设置为较大的值以永久存储缓存
  • 既然我想永久缓存图片,我应该将它们存储到一个专用文件夹中,还是默认目录就足够了?我的应用程序需要这些图片在应用程序关闭、重新打开以及手机重新启动时保持不变
  • 如果我想永久缓存图片,除了将过期时间设置为一个大值之外,还有什么需要注意的吗
    谢谢

    不幸的是,SDWebImage没有提供这样的功能 因此,为了利用SDWebImage提供的高级缓存功能,我在其周围编写了一个包装器

    基本上,这个类管理一个回退永久缓存,因此如果在SDWeb映像缓存“磁盘和内存”中找不到请求的映像,它将在永久缓存中查找它 如果找到了永久缓存,它将被复制到SDwebImage缓存,以便在以后的请求中利用其内存兑现

    使用这种方法,我成功地使用SDWebImage将图像设置为表格单元格,与往常一样平滑 您还可以在需要时触发clearImageCache以更正永久缓存

    .h文件

    @interface CacheManager : NSObject
    + (CacheManager*)sharedManager;
    
    // Images
    - (BOOL) diskImageExistsForURL:(NSURL*) url;
    - (void) downloadImage:(NSURL*) url completed:(void(^)(UIImage*))onComplete;
    - (void) setImage:(NSURL*)url toImageView:(UIImageView*)iv completed:(void(^)(UIImage*))onComplete;
    - (void) clearImageCache;
    
    @end
    
    #import "CacheManager.h"
    #import <SDWebImage/UIImageView+WebCache.h>
    
    
    #define CACH_IMAGES_FOLDER      @"ImagesData"
    
    
    @implementation CacheManager
    
    
    static CacheManager *sharedManager = nil;
    
    #pragma mark -
    #pragma mark Singilton Init Methods
    // init shared Cache singleton.
    + (CacheManager*)sharedManager{
        @synchronized(self){
            if ( !sharedManager ){
                sharedManager = [[CacheManager alloc] init];
            }
        }
        return sharedManager;
    }
    
    // Dealloc shared API singleton.
    + (id)alloc{
        @synchronized( self ){
            NSAssert(sharedManager == nil, @"Attempted to allocate a second instance of a singleton.");
            return [super alloc];
        }
        return nil;
    }
    
    // Init the manager
    - (id)init{
        if ( self = [super init] ){}
        return self;
    }
    
    /**
      @returns YES if image found in the permanent cache or the cache managed by SDWebImage lib
     */
    - (BOOL) diskImageExistsForURL:(NSURL*) url{
    
        // look for image in the SDWebImage cache
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        if([manager diskImageExistsForURL:url])
            return YES;
    
        // look for image in the permanent cache
        NSString *stringPath = url.path;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        return [fileManager fileExistsAtPath:stringPath];
    }
    
    /**
     get the image with specified remote url asynchronosly 
     first looks for the image in SDWeb cache to make use of the disk and memory cache provided by SDWebImage
     if not found, looks for it in the permanent cache we are managing, finally if not found in either places
     it will download it using SDWebImage and cache it.
     */
    - (void) downloadImage:(NSURL*) url completed:(void(^)(UIImage*))onComplete{
    
        NSString *localPath = [[self getLocalUrlForImageUrl:url] path];
        NSFileManager *fileManager = [NSFileManager defaultManager];
    
        // -1 look for image in SDWeb cache
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        if([manager diskImageExistsForURL:url]){
            [manager downloadImageWithURL:url options:SDWebImageRetryFailed
                                 progress:^(NSInteger receivedSize, NSInteger expectedSize) {}
                                completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
                                    onComplete(image);
    
                                    // save the image to the perminant cache for later
                                    // if not saved before
                                    if(image){
                                        if ([fileManager fileExistsAtPath:localPath]){
                                            NSURL* localeUrl = [self getLocalUrlForImageUrl:url];
                                            [self saveImage:image toCacheWithLocalPath:localeUrl];
                                        }
                                    }
                                }];
            return;
        }
    
        // -2 look for the image in the permanent cache
        if ([fileManager fileExistsAtPath:localPath]){
            UIImage *img = [self getImageFromCache:url];
            onComplete(img);
            // save image back to the SDWeb image cache to make use of the memory cache
            // provided by SDWebImage in later requests
            [manager saveImageToCache:img forURL:url];
            return;
        }
    
        // -3 download the image using SDWebImage lib
        [manager downloadImageWithURL:url options:SDWebImageRetryFailed
                             progress:^(NSInteger receivedSize, NSInteger expectedSize) {}
                            completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
                                onComplete(image);
                                // save the image to the permanent cache for later
                                if(image){
                                    NSURL* localeUrl = [self getLocalUrlForImageUrl:url];
                                    [self saveImage:image toCacheWithLocalPath:localeUrl];
                                }
                            }];
    
    }
    
    - (void) setImage:(NSURL*)url toImageView:(UIImageView*)iv completed:(void(^)(UIImage*))onComplete{
        [self downloadImage:url completed:^(UIImage * downloadedImage) {
            iv.image = downloadedImage;
            onComplete(downloadedImage);
        }];
    }
    
    
    /**
     @param:imgUrl : local url of image to read
     */
    - (UIImage*) getImageFromCache:(NSURL*)imgUrl{
        return [UIImage imageWithData: [NSData dataWithContentsOfURL:imgUrl]];
    }
    
    /**
     writes the suplied image to the local path provided
     */
    -(void) saveImage:(UIImage*)img toCacheWithLocalPath:(NSURL*)localPath{
        NSData * binaryImageData = UIImagePNGRepresentation(img);
        [binaryImageData writeToFile:[localPath path] atomically:YES];
    }
    
    // Generate local image URL baesd on the name of the remote image
    // this assumes the remote images already has unique names
    - (NSURL*)getLocalUrlForImageUrl:(NSURL*)imgUrl{
        // Saving an offline copy of the data.
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *cachesDirectory = [paths objectAtIndex:0];
        NSString *folderPath = [cachesDirectory stringByAppendingPathComponent:CACH_IMAGES_FOLDER];
        BOOL isDir;
        // create folder not exist
        if (![fileManager fileExistsAtPath:folderPath isDirectory:&isDir]){
            NSError *dirWriteError = nil;
            if (![fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:&dirWriteError]){
                NSLog(@"Error: failed to create folder!");
            }
        }
    
        NSString *imgName = [[[imgUrl path] lastPathComponent] stringByDeletingPathExtension];
    
        NSURL *cachesDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        NSString *pathString = [NSString stringWithFormat:@"%@/%@", CACH_IMAGES_FOLDER, imgName];
        return [cachesDirectoryURL URLByAppendingPathComponent:pathString];
    }
    
    
    /**
     removes the folder contating the cahced images,
     the folder will be reacreated whenever a new image is being saved to the permanent cache
     */
    -(void)clearImageCache{
        // set the directory path
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *cachesDirectory = [paths objectAtIndex:0];
        NSString *folderPath =  [cachesDirectory stringByAppendingPathComponent:CACH_IMAGES_FOLDER];
        BOOL isDir;
        NSError *dirError = nil;
        // folder exist
        if ([fileManager fileExistsAtPath:folderPath isDirectory:&isDir]){
            if (![fileManager removeItemAtPath:folderPath error:&dirError])
            NSLog(@"Failed to remove folder");
        }
    }
    
    @end
    
    .m文件

    @interface CacheManager : NSObject
    + (CacheManager*)sharedManager;
    
    // Images
    - (BOOL) diskImageExistsForURL:(NSURL*) url;
    - (void) downloadImage:(NSURL*) url completed:(void(^)(UIImage*))onComplete;
    - (void) setImage:(NSURL*)url toImageView:(UIImageView*)iv completed:(void(^)(UIImage*))onComplete;
    - (void) clearImageCache;
    
    @end
    
    #import "CacheManager.h"
    #import <SDWebImage/UIImageView+WebCache.h>
    
    
    #define CACH_IMAGES_FOLDER      @"ImagesData"
    
    
    @implementation CacheManager
    
    
    static CacheManager *sharedManager = nil;
    
    #pragma mark -
    #pragma mark Singilton Init Methods
    // init shared Cache singleton.
    + (CacheManager*)sharedManager{
        @synchronized(self){
            if ( !sharedManager ){
                sharedManager = [[CacheManager alloc] init];
            }
        }
        return sharedManager;
    }
    
    // Dealloc shared API singleton.
    + (id)alloc{
        @synchronized( self ){
            NSAssert(sharedManager == nil, @"Attempted to allocate a second instance of a singleton.");
            return [super alloc];
        }
        return nil;
    }
    
    // Init the manager
    - (id)init{
        if ( self = [super init] ){}
        return self;
    }
    
    /**
      @returns YES if image found in the permanent cache or the cache managed by SDWebImage lib
     */
    - (BOOL) diskImageExistsForURL:(NSURL*) url{
    
        // look for image in the SDWebImage cache
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        if([manager diskImageExistsForURL:url])
            return YES;
    
        // look for image in the permanent cache
        NSString *stringPath = url.path;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        return [fileManager fileExistsAtPath:stringPath];
    }
    
    /**
     get the image with specified remote url asynchronosly 
     first looks for the image in SDWeb cache to make use of the disk and memory cache provided by SDWebImage
     if not found, looks for it in the permanent cache we are managing, finally if not found in either places
     it will download it using SDWebImage and cache it.
     */
    - (void) downloadImage:(NSURL*) url completed:(void(^)(UIImage*))onComplete{
    
        NSString *localPath = [[self getLocalUrlForImageUrl:url] path];
        NSFileManager *fileManager = [NSFileManager defaultManager];
    
        // -1 look for image in SDWeb cache
        SDWebImageManager *manager = [SDWebImageManager sharedManager];
        if([manager diskImageExistsForURL:url]){
            [manager downloadImageWithURL:url options:SDWebImageRetryFailed
                                 progress:^(NSInteger receivedSize, NSInteger expectedSize) {}
                                completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
                                    onComplete(image);
    
                                    // save the image to the perminant cache for later
                                    // if not saved before
                                    if(image){
                                        if ([fileManager fileExistsAtPath:localPath]){
                                            NSURL* localeUrl = [self getLocalUrlForImageUrl:url];
                                            [self saveImage:image toCacheWithLocalPath:localeUrl];
                                        }
                                    }
                                }];
            return;
        }
    
        // -2 look for the image in the permanent cache
        if ([fileManager fileExistsAtPath:localPath]){
            UIImage *img = [self getImageFromCache:url];
            onComplete(img);
            // save image back to the SDWeb image cache to make use of the memory cache
            // provided by SDWebImage in later requests
            [manager saveImageToCache:img forURL:url];
            return;
        }
    
        // -3 download the image using SDWebImage lib
        [manager downloadImageWithURL:url options:SDWebImageRetryFailed
                             progress:^(NSInteger receivedSize, NSInteger expectedSize) {}
                            completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
                                onComplete(image);
                                // save the image to the permanent cache for later
                                if(image){
                                    NSURL* localeUrl = [self getLocalUrlForImageUrl:url];
                                    [self saveImage:image toCacheWithLocalPath:localeUrl];
                                }
                            }];
    
    }
    
    - (void) setImage:(NSURL*)url toImageView:(UIImageView*)iv completed:(void(^)(UIImage*))onComplete{
        [self downloadImage:url completed:^(UIImage * downloadedImage) {
            iv.image = downloadedImage;
            onComplete(downloadedImage);
        }];
    }
    
    
    /**
     @param:imgUrl : local url of image to read
     */
    - (UIImage*) getImageFromCache:(NSURL*)imgUrl{
        return [UIImage imageWithData: [NSData dataWithContentsOfURL:imgUrl]];
    }
    
    /**
     writes the suplied image to the local path provided
     */
    -(void) saveImage:(UIImage*)img toCacheWithLocalPath:(NSURL*)localPath{
        NSData * binaryImageData = UIImagePNGRepresentation(img);
        [binaryImageData writeToFile:[localPath path] atomically:YES];
    }
    
    // Generate local image URL baesd on the name of the remote image
    // this assumes the remote images already has unique names
    - (NSURL*)getLocalUrlForImageUrl:(NSURL*)imgUrl{
        // Saving an offline copy of the data.
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *cachesDirectory = [paths objectAtIndex:0];
        NSString *folderPath = [cachesDirectory stringByAppendingPathComponent:CACH_IMAGES_FOLDER];
        BOOL isDir;
        // create folder not exist
        if (![fileManager fileExistsAtPath:folderPath isDirectory:&isDir]){
            NSError *dirWriteError = nil;
            if (![fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:&dirWriteError]){
                NSLog(@"Error: failed to create folder!");
            }
        }
    
        NSString *imgName = [[[imgUrl path] lastPathComponent] stringByDeletingPathExtension];
    
        NSURL *cachesDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
        NSString *pathString = [NSString stringWithFormat:@"%@/%@", CACH_IMAGES_FOLDER, imgName];
        return [cachesDirectoryURL URLByAppendingPathComponent:pathString];
    }
    
    
    /**
     removes the folder contating the cahced images,
     the folder will be reacreated whenever a new image is being saved to the permanent cache
     */
    -(void)clearImageCache{
        // set the directory path
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *cachesDirectory = [paths objectAtIndex:0];
        NSString *folderPath =  [cachesDirectory stringByAppendingPathComponent:CACH_IMAGES_FOLDER];
        BOOL isDir;
        NSError *dirError = nil;
        // folder exist
        if ([fileManager fileExistsAtPath:folderPath isDirectory:&isDir]){
            if (![fileManager removeItemAtPath:folderPath error:&dirError])
            NSLog(@"Failed to remove folder");
        }
    }
    
    @end
    
    #导入“CacheManager.h”
    #进口
    #定义CACH_IMAGES_文件夹@“ImagesData”
    @实现缓存管理器
    静态缓存管理器*sharedManager=nil;
    #布拉格标记-
    #pragma-mark-Singilton初始化方法
    //初始化共享缓存单例。
    +(CacheManager*)共享管理器{
    @同步(自){
    如果(!sharedManager){
    sharedManager=[[CacheManager alloc]init];
    }
    }
    返回共享管理器;
    }
    //Dealloc共享API单例。
    +(id)alloc{
    @同步(自){
    NSAssert(sharedManager==nil,@“试图分配单例的第二个实例”);
    返回[super alloc];
    }
    返回零;
    }
    //初始化经理
    -(id)init{
    if(self=[super init]){}
    回归自我;
    }
    /**
    @如果在永久缓存或SDWebImage库管理的缓存中找到映像,则返回YES
    */
    -(BOOL)diskImageExistsForURL:(NSURL*)url{
    //在SDWebImage缓存中查找图像
    SDWebImageManager*manager=[SDWebImageManager共享管理器];
    如果([manager diskImageExistsForURL:url])
    返回YES;
    //在永久缓存中查找图像
    NSString*stringPath=url.path;
    NSFileManager*fileManager=[NSFileManager defaultManager];
    返回[fileManager fileExistsAtPath:stringPath];
    }
    /**
    异步获取具有指定远程url的映像
    首先在SDWeb缓存中查找映像,以利用SDWebImage提供的磁盘和内存缓存
    如果未找到,则在我们正在管理的永久缓存中查找它,如果未在任何位置找到,则最后查找
    它将使用SDWebImage下载并缓存它。
    */
    -(void)下载图像:(NSURL*)url已完成:(void(^)(UIImage*)未完成{
    NSString*localPath=[[self-getLocalUrlForImageUrl:url]path];
    NSFileManager*fileManager=[NSFileManager defaultManager];
    //-1在SDWeb缓存中查找图像
    SDWebImageManager*manager=[SDWebImageManager共享管理器];
    如果([manager diskImageExistsForURL:url]){
    [manager下载ImageWithURL:url选项:SDWebImageRetryFailed
    进度:^(NSInteger receivedSize,NSInteger expectedSize){}
    已完成:^(UIImage*image,NSError*error,SDImageCacheType cacheType,BOOL finished,NSURL*imageURL){
    未完成(图像);
    //将图像保存到perminant缓存以备以后使用
    //如果之前没有保存
    如果(图像){
    if([fileManager fileExistsAtPath:localPath]){
    NSURL*localeUrl=[self-getLocalUrlForImageUrl:url];
    [self-saveImage:image-toCacheWithLocalPath:localeUrl];
    }
    }
    }];
    返回;
    }
    //-2在永久缓存中查找图像
    if([fileManager fileExistsAtPath:localPath]){
    UIImage*img=[self-getImageFromCache:url];
    未完成(img);
    //将图像保存回SDWeb图像缓存以使用内存缓存
    //由SDWebImage在以后的请求中提供
    [manager saveImageToCache:img for url:url];
    返回;
    }
    //-3使用SDWebImage库下载图像
    [manager下载ImageWithURL:url选项:SDWebImageRetryFailed
    进度:^(NSInteger receivedSize,NSInteger expectedSize){}
    已完成:^(UIImage*image,NSError*error,SDImageCacheType cacheType,BOOL finished,NSURL*imageURL){
    未完成(图像);
    //将图像保存到永久缓存以备以后使用
    如果(图像){
    NSURL*localeUrl=[self-getLocalUrlForImageUrl:url];
    [self-saveImage:image-toCacheWithLocalPath:localeUrl];
    }
    }];
    }
    -(void)setImage:(NSURL*)图像视图的url:(UIImageView*)iv已完成:(void(^)(UIImage*)未完成{
    [自下载图像:url已完成:^(UIImage*下载图像){
    iv.image=下载的图像;
    完成(下载图像);
    }];
    }
    /**
    @param:imgUrl:要读取的图像的本地url
    */
    -(UIImage*)getImageFromCache:(NSURL*)imgUrl{
    返回[UIImage imageWithData:[NSData dataWithContentsOfURL:imgUrl]];
    }
    /**
    将提供的映像写入提供的本地路径
    */
    -(无效)保存图像:(UIImage*)img