自己尝试等装一下恩美第二个APP项目小知识点

iOS请求缓存、离线缓存 框架 ZBNetworking

2017-03-15  本文已影响657人  Andi

ZBNetworking

优点:
1 低耦合,易扩展。(这个下篇文章体现)
2.有缓存文件过期机制 默认一周(以最后缓存文件修改时间为准)
3.显示缓存大小/个数,全部清除缓存/单个文件清除缓存/按时间清除缓存 方法多样 并且都可以自定义路径 可扩展性强
4.离线下载功能
5.多种请求类型的判断。也可不遵循,自由随你定。

    /** 重新请求 ,不读取缓存,重新请求*/
    ZBRequestTypeRefresh,
    /** 有缓存,读取缓存 无缓存,重新请求*/
    ZBRequestTypeCache,
    /** 加载更多 ,不读取缓存,重新请求*/
    ZBRequestTypeRefreshMore,
    /** 加载更多 ,有缓存,读取缓存 无缓存,重新请求*/
    ZBRequestTypeCacheMore,
    /** 详情    ,有缓存,读取缓存 无缓存,重新请求*/
    ZBRequestTypeDetailCache,
    /** 自定义  ,有缓存,读取缓存 无缓存,重新请求*/
    ZBRequestTypeCustomCache

6.可见的缓存文件


ZBNetworking_cache_gif.gif

AFNetworking 不多介绍了 在使用OC开发的,很多都用这个。封装了一个缓存管理类ZBCacheManager,主要参照了SDWebImage的SDImageCache磁盘存储的思路,SDWebImage的存储性能大家应该不用怀疑,但也要进行大量的改动,毕竟SDImageCache 只是缓存图片的。不管用那种请求方法 缓存文件都会存储到沙盒 /Library/Caches/ZBKit/AppCache 路径下 。
有一点要注意,请求下来的数据格式 是二进制的 因为缓存也是二进制数据 。所以设置了responseSerializer = [AFHTTPResponseSerializer serializer];不能更改。

F0C2D948-9691-40B5-8251-554FB85A84EA.png

请求示例 具体看demo 。
2017-8-21 重构了此库 现在默认为Refresh (重新请求,不读缓存)。

[ZBRequestManager requestWithConfig:^(ZBURLRequest *request){
        request.urlString=list_URL;
        request.methodType=ZBMethodTypeGET;//默认为GET
        request.apiType=ZBRequestTypeCache;//默认为ZBRequestTypeRefresh
    }  success:^(id responseObj,apiType type){
        if (type==ZBRequestTypeRefresh) {
              //下拉结束刷新
        }  
        if (type==ZBRequestTypeLoadMore) {
            // 上拉结束刷新
        }
             //请求成功
        
    } failed:^(NSError *error){
        if (error.code==NSURLErrorCancelled)return;
        if (error.code==NSURLErrorTimedOut){
            [self alertTitle:@"请求超时" andMessage:@""];
        }else{
            [self alertTitle:@"请求失败" andMessage:@""];
        }
    }];

//取消对应的网络请求
 [ZBRequestManager cancelRequest: list_URL completion:^(NSString *urlString){
        //如果请求成功 或 读缓存 会返回null 无法取消。请求未完成的会取消并返回对应url
        //NSLog(@"取消对应url:%@ ",urlString);
    }];

离线缓存/下载

//使用SDWebImage方法替换内部实现
- (void)downloadImages:(int)index {
    
    [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:_imageArray[index]] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize){
        
    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType,BOOL finished,NSURL *imageURL){
        if (image) {
            self.images[index] = image;
            //如果下载的图片为当前要显示的图片,直接到主线程给imageView赋值,否则要等到下一轮才会显示
            if (_currIndex == index) [_currImageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
        }
    }];
}

C2A147C7-8F29-490F-82CE-62810491A150.png

好了 我们的列表图片包括轮播图片 缓存 都在SDWebImage 的默认缓存路径里了,因为XRCarouselView 我并没有征得作者的同意更改,所以demo中就不使用了,主要让大家 知道 图片的请求与存储要统一
而我们的json 数据 已经缓存到/Library/Caches/ZBKit/AppCache 路径下 。下面开始 实现离线功能

思路就是 每个频道就是一个url,把你要缓存的 url 放到一个数组里 进行遍历请求。ZBRequestManager已经封装好了 离线的方法

- (void)requestOffline:(NSMutableArray *)offlineArray{

    [ZBRequestManager sendBatchRequest:^(ZBBatchRequest *batchRequest){
         for (NSString *urlString in offlineArray) {
            ZBURLRequest *request=[[ZBURLRequest alloc]init];
            request.urlString=urlString;
            [batchRequest.urlArray addObject:request];
        }
    }  success:^(id responseObj,apiType type){

            NSLog(@"添加了几个url请求  就会走几遍");
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObj options:NSJSONReadingMutableContainers error:nil];
            NSArray *array=[dict objectForKey:@"videos"];
            for (NSDictionary *dic in array) {
                DetailsModel *model=[[DetailsModel alloc]init];
                model.thumb=[dic objectForKey:@"thumb"]; //找到图片的key
                [self.imageArray addObject:model];
                
                //使用SDWebImage 下载图片
                BOOL isKey=[[SDImageCache sharedImageCache]diskImageExistsWithKey:model.thumb];
                if (isKey) {
                    self.offlineView.progressLabel.text=@"已经下载了";
                } else{
                    
                    [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:model.thumb] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize){
                        
                        NSLog(@"%@",[self progressStrWithSize:(double)receivedSize/expectedSize]);
                        
                        self.offlineView.progressLabel.text=[self progressStrWithSize:(double)receivedSize/expectedSize];
                        
                        self.offlineView.pv.progress =(double)receivedSize/expectedSize;
                        
                    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType,BOOL finished,NSURL *imageURL){
                        
                        NSLog(@"单个图片下载完成");
                        self.offlineView.progressLabel.text=nil;
                        
                        self.offlineView.progressLabel.text=[self progressStrWithSize:0.0];
                        
                        self.offlineView.pv.progress = 0.0;
                        
                        [self.tableView reloadData];
                        //让 下载的url与模型的最后一个比较,如果相同证明下载完毕。
                        NSString *imageURLStr = [imageURL absoluteString];
                        NSString *lastImage=[NSString stringWithFormat:@"%@",((DetailsModel *)[self.imageArray lastObject]).thumb];
                        
                        if ([imageURLStr isEqualToString:lastImage]) {
                            NSLog(@"下载完成");
                            
                            [self.offlineView hide];//取消下载进度视图
                            [self alertTitle:@"下载完成"andMessage:@""];
                             self.imageArray=nil;
                        }
                        
                        if (error) {
                            NSLog(@"下载失败");
                        }
                    }];
                    
                }
                
            }

    } failed:^(NSError *error){
        if (error.code==NSURLErrorCancelled)return;
        if (error.code==NSURLErrorTimedOut){
            [self alertTitle:@"请求超时" andMessage:@""];
        }else{
            [self alertTitle:@"请求失败" andMessage:@""];
        }
    }];
}
cache

点击 Github地址 下载

结尾:水平有限,代码也很烂,一直在努力学习中,大家多多包涵。如果你喜欢这个轮子,请给个star,这是对作者最大的鼓励和支持,拜谢!!!假如你有更好的想法或方案请留言!

下篇文章:设计一个简单的图片缓存器

上一篇下一篇

猜你喜欢

热点阅读