美文网首页iOS那点事儿iOS自我学习库
iOS 批量下载多张图片,保持原始顺序

iOS 批量下载多张图片,保持原始顺序

作者: zhangyin | 来源:发表于2018-02-28 15:17 被阅读1265次

经常会遇到这样的应用场景,例如在调用iOS系统分享功能前(UIActivityViewController),需要将所有的图片事先准备好,但是图片都在网络上.
这时,就需要先将图片都下载好后再进行调用.
可能是这个功能的实现太简单了,所以像SDWebImage,AFNetwork等都没有提供可以直接调用的API方法.
所以只好花了2秒钟自己写了一个方法;

#import "ImagesDownloadManager.h"
#import "SDWebImageDownloader.h"

@implementation ImagesDownloadManager

/**
 批量下载图片
 保持顺序;
 全部下载完成后才进行回调;
 回调结果中,下载正确和失败的状态保持与原先一致的顺序;
 
 @return resultArray 中包含两类对象:UIImage , NSError
 */
+ (void)downloadImages:(NSArray<NSString *> *)imgsArray completion:(void(^)(NSArray *resultArray))completionBlock {
    SDWebImageDownloader *manager = [SDWebImageDownloader sharedDownloader];
    manager.downloadTimeout = 20;
    __block NSMutableDictionary *resultDict = [NSMutableDictionary new];
    for(int i=0;i<imgsArray.count;i++) {
        NSString *imgUrl = [imgsArray objectAtIndex:i];
        [manager downloadImageWithURL:[NSURL URLWithString:imgUrl]
                              options:SDWebImageDownloaderUseNSURLCache|SDWebImageDownloaderScaleDownLargeImages
                             progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
                                 
                             } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, BOOL finished) {
                                 if(finished){
                                     if(error){
                                        //在对应的位置放一个error对象
                                         [resultDict setObject:error forKey:@(i)];
                                     }else{
                                         [resultDict setObject:image forKey:@(i)];
                                     }
                                     if(resultDict.count == imgsArray.count) {
                                         //全部下载完成
                                         NSArray *resultArray = [ImagesDownloadManager createDownloadResultArray:resultDict count:imgsArray.count];
                                         if(completionBlock){
                                             completionBlock(resultArray);
                                         }
                                     }
                                 }
                                 
                             }];
    }
}

+ (NSArray *)createDownloadResultArray:(NSDictionary *)dict count:(NSInteger)count {
    NSMutableArray *resultArray = [NSMutableArray new];
    for(int i=0;i<count;i++) {
        NSObject *obj = [dict objectForKey:@(i)];
        [resultArray addObject:obj];
    }
    return resultArray;
}

@end


调用方法:

                //下载图片
                [ImagesDownloadManager downloadImages:imgs completion:^(NSArray *resultArray) {
                    NSMutableArray *items = [NSMutableArray new];
                    for(int i=0;i<resultArray.count;i++) {
                        NSObject *obj = [resultArray objectAtIndex:i];
                        if([obj isKindOfClass:[UIImage class]]) {
                            //只取UIImage对象,其他类型忽略之
                            [items addObject:obj];
                        }
                    }
                    //调用系统自带的分享功能,把选中的图片们分享出去
                    UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:items applicationActivities:nil];
                    [self presentViewController:activityVC animated:YES completion:nil];
                }];

相关文章

网友评论

  • Buger123:最多下载五张啊,怎么解决
    zhangyin:调用方法前限制一下呗~
  • Buger123:顺序下载图片保存在哪里
    Buger123:@zhangyin 嗯,明白了,我是把图片保存到相册中去,已经解决了
    zhangyin:放在内存当中,可以直接使用哦,就是下面这段:
    NSMutableArray *items = [NSMutableArray new];
    for(int i=0;i<resultArray.count;i++) {
    NSObject *obj = [resultArray objectAtIndex:i];
    if([obj isKindOfClass:[UIImage class]]) {
    //只取UIImage对象,其他类型忽略之
    [items addObject:obj];
    }
    }
  • PGOne爱吃饺子:楼主,标题下载多张图片保持原始顺序是什么意思
    zhangyin:@PGOne爱吃饺子 sd是异步下载的,下载完成后,在本地拼装成顺序的。 代码比较简单粗暴。
    使用循环变量 i 作为 一个dictionary的key,用来保存每个异步回来的结果;
    最后使用循环把图片按照顺序循环出来;

    另外,i 被包含进block中, 当sd的异步返回时,i的值是安全的,仍然是它刚被包含进去时值;
    PGOne爱吃饺子:那你写的这个方法应该不是按照顺序下载的吧,SDWebImageDownloader这个类里面下载图片的时候就是异步的
    zhangyin:我的本意是:如果打算批量下载图片A,B,C,那么批量下载完成后,返回的图片顺序还是A、B、C这样的顺序,保持与下载前的顺序相同。
    由于网络及各种灵异的原因,当多个线程同时开启下载,返回的图片顺序可能会乱序,例如C、B、A这样;(假设C线程中的任务跑的最快)
  • llq_31da:有没有碰到,多张图片,有时候其中某张不下载的情况???
    llq_31da:@zhangyin 找到原因了,是后台返回的图片URL不规范,带有其他字符:sweat:
    zhangyin:因为我觉得,无论做多么努力的尝试,总是会遇见各种网络问题,这是无法克服的障碍,与其在重试的方案上花费很多精力去优化,不如简单处理。相信用户是可以理解和接受的。
    zhangyin:有的,这种情况非常常见,我现在的处理方法就是简单粗暴的丢弃它。

本文标题:iOS 批量下载多张图片,保持原始顺序

本文链接:https://www.haomeiwen.com/subject/zizbxftx.html