1

I have to download file from server on respective button click in UITableViewCell.When user taps Button to download in one cell download should be started.After completion of downloading I'm saving in core data.Up to this All went well.But while downloading current file if user taps to download another file in Cell it also should download then save to core data and make available to play.And i have different url's in each table cell.If user taps multiple buttons should download them and save to core data.Here my code.

            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];

Here I managed to download only one file at a time and after completion of that if user taps another cell then only I'm downloading it.But I have to download multiple files on multiple button taps in Cell. I have been struggling lot to implement this.Please give some suggestions.
Thanks in advance.

Uday Kumar Eega
  • 164
  • 1
  • 15
  • Possible duplicate of [How to download files and save to local using AFNetworking 3.0?](http://stackoverflow.com/questions/35137749/how-to-download-files-and-save-to-local-using-afnetworking-3-0) –  Feb 13 '17 at 06:29
  • You will pass url to one method, let's say openurl(NSUrl*) mypicUrl :(Int) cellrow. So you know at the end of downloading which cell must be reloaded. – ares777 Feb 13 '17 at 06:40

1 Answers1

0

In MVC patterns, cell is a view and should not handle data parse and downloading things. It's better to do it in your model. But for simple it is often put in controller.

  1. holding your model arrays in controller and pass data to cell
  2. configure your cell's button action to controller (delegate or block or notification ...)
  3. put downloading code in your controller and update your model status and reload tableView after completion.

cell.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

cell.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

controller.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];
}
Jing
  • 536
  • 3
  • 12