从服务器一个一个下载文件

Posted

技术标签:

【中文标题】从服务器一个一个下载文件【英文标题】:Download file from server one by one 【发布时间】:2017-02-13 06:20:42 【问题描述】:

我必须在 UITableViewCell 中单击相应按钮时从服务器下载文件。当用户点击按钮以在一个单元格中下载时,应该开始下载。下载完成后,我将保存核心数据。到目前为止一切顺利。但是在下载当前文件时,如果用户点击以在 Cell 中下载另一个文件,它也应该下载然后保存到核心数据并可供播放。而且我在每个表格单元格中有不同的 url。如果用户点击多个按钮应该下载它们并保存到核心数据。这是我的代码。

            NSString *url=[[chatHistoryArr objectAtIndex:sender.tag]valueForKey:@"voice"];
        NSLog(@"%@",url);
        //NSURL *voiceUrl=[NSURL URLWithString:url];

        tempDict=[[NSMutableDictionary alloc]init];

        [tempDict setValue:[[chatHistoryArr objectAtIndex:sender.tag]valueForKey:@"msg_id"] forKey:@"msg_id"];
        [tempDict setValue:[[chatHistoryArr objectAtIndex:sender.tag]valueForKey:@"to"] forKey:@"to"];
        [tempDict setValue:[[chatHistoryArr objectAtIndex:sender.tag]valueForKey:@"from"] forKey:@"from"];
        [tempDict setValue:[[chatHistoryArr objectAtIndex:sender.tag]valueForKey:@"time"] forKey:@"time"];

        UIImageView* animatedImageView = [[UIImageView alloc] initWithFrame:cell.playButton.bounds];
        animatedImageView.animationImages = [NSArray arrayWithObjects:
                                             [UIImage imageNamed:@"1.png"],
                                             [UIImage imageNamed:@"2.png"],
                                             [UIImage imageNamed:@"3.png"],
                                             [UIImage imageNamed:@"4.png"], nil];
        animatedImageView.animationDuration = 3.0f;
        animatedImageView.animationRepeatCount = 10;
        [animatedImageView startAnimating];
        [cell1.playButton addSubview: animatedImageView];

        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
        AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
        [manager setResponseSerializer:[AFHTTPResponseSerializer serializer]];
        // manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/octet-stream",@"video/3gpp",@"audio/mp4",nil];
        NSURL *URL = [NSURL URLWithString:url];
        NSURLRequest *request = [NSURLRequest requestWithURL:URL];

        NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) 
            if (error)
            
                NSLog(@"Error: %@", error);
             else
            

                NSData *data=[[NSData alloc]initWithData:responseObject];

            //Here I'm saving file to local storage then updating UI.
                    [self sentMsgSaveWithData:data orUrl:@"" withBool:YES withMsg_ID:@"" withDict:tempDict];

            
        ];
        [dataTask resume];

在这里,我设法一次只下载一个文件,完成后,如果用户点击另一个单元格,那么只有我正在下载它。但是我必须在单元格中的多个按钮点击上下载多个文件。 我一直在努力实现这一点。请提出一些建议。 提前致谢。

【问题讨论】:

How to download files and save to local using AFNetworking 3.0?的可能重复 您会将 url 传递给一种方法,比如说 openurl(NSUrl*) mypicUrl :(Int) cellrow。所以你知道在下载结束时必须重新加载哪个单元格。 【参考方案1】:

在 MVC 模式中,单元格是一个视图,不应处理数据解析和下载内容。最好在您的模型中执行此操作。但为简单起见,它通常放在控制器中。

    将模型数组保存在控制器中并将数据传递到单元格 将单元格的按钮操作配置到控制器(委托或阻止或通知...) 将下载代码放入控制器并更新模型状态并在完成后重新加载 tableView。

细胞.h

#import <UIKit/UIKit.h>
#import "YourCellProtocol.h"

typedef NS_ENUM(NSInteger, YourCellStatus) 
    YourCellStatusNormal,
    YourCellStatusDownloading,
    YourCellStatusCompleted
;

@interface YourCell : UITableViewCell

@property (nonatomic, weak) id<YourCellProtocol> delegate;

@property (nonatomic, assign) YourCellStatus status;

@property (nonatomic, weak) id yourDataUsedToShownInUI;

@end

细胞.m

#import "YourCell.h"

@interface YourCell ()

@property (nonatomic, strong) UIButton *myButton;

@end

@implementation YourCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) 
        // init all your buttons etc
        _myButton = [UIButton buttonWithType:UIButtonTypeSystem];
        [_myButton addTarget:self action:@selector(myButtonPressed) forControlEvents:UIControlEventTouchUpInside];
        [self.contentView addSubview:_myButton];
    
    return self;


- (void)setStatus:(YourCellStatus)status 
    //update your cell UI here


- (void)myButtonPressed 
    // tell your controller to start downloading
    if (self.status != YourCellStatusNormal) 
        [self.delegate didPressedButtonInYourCell:self];
    


@end

控制器.m

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    static NSString *CellID = @"YourCellID";
    YourCell *cell = (YourCell *)[tableView dequeueReusableCellWithIdentifier:CellID];

    if (cell == nil) 
        cell = [[YourCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellID];
    

    cell.delegate = self;

    YourModel *model = self.yourDataArray[indexPath.row];
    cell.yourDataUsedToShownInUI = model.dataToShownInUI;
    if (model.downloading) 
        cell.status = YourCellStatusDownloading;
     else if (model.completed) 
        cell.status = YourCellStatusCompleted;
     else 
        cell.status = YourCellStatusNormal;
    

    //other configs ...

    return cell;


- (void)didPressedButtonInYourCell:(id)sender 
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    YourModel *model = self.yourDataArray[indexPath.row];
    model.downloading = YES;

    //start downloading
    //...
    // in download completion handler, update your model status, and call
    //[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

【讨论】:

以上是关于从服务器一个一个下载文件的主要内容,如果未能解决你的问题,请参考以下文章

从服务器下载文件时进度条卡在 0%?

用c#怎样从服务器下载文件,并保存为相应的类型

PHP:从服务器下载时保持相同的文件名

.exe 文件从服务器下载时损坏

从 FTP 服务器检查和下载多个文件

从页面到服务器,node实现文件下载