I am building an app that will allow users to download and read issues of a journal. I am using the Download Manager framework created by Robert Ryan
and I modified the test project that came with the framework to have it work in my project (there are no issues with the framework). On each row in the table there is a Issue Cover Image (UIImageView
), Download/Read label (UILabel
), Issue Date label (UILabel), and a progress bar (UIProgressView
) all are properties of a UITableViewCell
. When a user taps the row, it initiates the download process of the issue which is reflected in the progress bar; after the download completes, the progress bar becomes hidden and the Download title of the label changes to Read, and when the user taps the row again to read the downloaded journal it opens a PDF viewer in a viewcontroller
. I haven't added the Read functionality as yet. All this works fine except as a test I have 2 issues of the journal in the table each in a row with its ``. When I tap the first row, the progress bar reflects the download progress and it works fine. However, when I tap the second row, the download progress is reflected in the progress bar of the first row not the second row as expected (the progress bar remains static). It does download the second journal and everything works fine. It's just this unexpected behavior where the download progress of the second row is reflected in the progress bar in the first row. I still have to streamline the code and clean it up but the relevant code sections are below:
// optional method to indicate progress of individual download
//
// In this view controller, I'll update progress indicator for the download.
- (void)downloadManager:(DownloadManager *)downloadManager downloadDidReceiveData: (Download *)download;
{
for (NSInteger row = 0; row < [downloadManager.downloads count]; row++)
{
if (download == downloadManager.downloads[row])
{
[self updateProgressViewForIndexPath:[NSIndexPath indexPathForRow:row inSection:0] download:download];
break;
}
}
}
#pragma mark - Table View delegate and data source methods
// our table view will simply display a list of files being downloaded
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return[jitsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"DownloadCell";
DownloadCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[DownloadCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
jits * jitsInstance = nil;
jitsInstance = [jitsArray objectAtIndex:indexPath.row];
cell.issue.text = jitsInstance.issue;
NSString * myCoverURL = [NSString stringWithFormat:@"%@", jitsInstance.coverimage];
UIImage* myImage = [UIImage imageWithData:
[NSData dataWithContentsOfURL:
[NSURL URLWithString: myCoverURL]]];
cell.coverimage.image = myImage;
[cell.progressView setProgress:0];
NSString * myURL = [NSString stringWithFormat:@"%@", jitsInstance.url];
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *downloadFolder = [documentsPath stringByAppendingPathComponent:@"downloads"];
NSString * fileName = [[NSString alloc]initWithFormat:@"%@", [myURL lastPathComponent]];
NSString* foofile = [downloadFolder stringByAppendingPathComponent:fileName];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];
NSLog(@"Search file path: %@", foofile);
if (!fileExists) {
[cell.downloadButton setTitle:@"Download" forState:normal];
[cell.progressView setHidden:NO];
NSLog(@"File does not exist!");
}
else if (fileExists){
NSLog(@"File exist!");
[cell.downloadButton setTitle:@"Read" forState:normal];
[cell.progressView setHidden:YES];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *downloadFolder = [documentsPath stringByAppendingPathComponent:@"downloads"];
jits * jitsInstance = nil;
jitsInstance = [jitsArray objectAtIndex:indexPath.row];
NSString * myURL = [NSString stringWithFormat:@"%@", jitsInstance.url];
self.downloadManager = [[DownloadManager alloc] initWithDelegate:self];
self.downloadManager.maxConcurrentDownloads = 4;
NSString *downloadFilename = [downloadFolder stringByAppendingPathComponent:[myURL lastPathComponent]];
NSURL *url = [NSURL URLWithString:myURL];
[self.downloadManager addDownloadWithFilename:downloadFilename URL:url];
self.cancelButton.enabled = YES;
self.startDate = [NSDate date];
[self.downloadManager start];
}
#pragma mark - Table view utility methods
- (void)updateProgressViewForIndexPath:(NSIndexPath *)indexPath download:(Download *)download
{
DownloadCell *cell = (DownloadCell *)[self.tableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:indexPath.row inSection:0]];
// if the cell is not visible, we can return
if (!cell)
return;
if (download.expectedContentLength >= 0)
{
// if the server was able to tell us the length of the file, then update progress view appropriately
// to reflect what % of the file has been downloaded
cell.progressView.progress = (double) download.progressContentLength / (double) download.expectedContentLength;
}
else
{
// if the server was unable to tell us the length of the file, we'll change the progress view, but
// it will just spin around and around, not really telling us the progress of the complete download,
// but at least we get some progress update as bytes are downloaded.
//
// This progress view will just be what % of the current megabyte has been downloaded
cell.progressView.progress = (double) (download.progressContentLength % 1000000L) / 1000000.0;
}
}