- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 code from here下载 mp3 文件。我已将代码复制到我的一个 View Controller 中,它工作正常。但是,在我按下“返回”按钮并再次返回 View 后,进度 View 未更新(即 UI 未更新/UI 线程不工作)。我是 iOS 新手。任何帮助深表感谢。
用户界面已更新
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
//
// ViewController.m
// BGTransferDemo
//
// Created by Gabriel Theodoropoulos on 25/3/14.
// Copyright (c) 2014 Appcoda. All rights reserved.
//
#import "ViewController.h"
#import "FileDownloadInfo.h"
#import "AppDelegate.h"
// Define some constants regarding the tag values of the prototype cell's subviews.
#define CellLabelTagValue 10
#define CellStartPauseButtonTagValue 20
#define CellStopButtonTagValue 30
#define CellProgressBarTagValue 40
#define CellLabelReadyTagValue 50
@interface ViewController ()
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSMutableArray *arrFileDownloadData;
@property (nonatomic, strong) NSURL *docDirectoryURL;
-(void)initializeFileDownloadDataArray;
-(int)getFileDownloadInfoIndexWithTaskIdentifier:(unsigned long)taskIdentifier;
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self initializeFileDownloadDataArray];
NSArray *URLs = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask];
self.docDirectoryURL = [URLs objectAtIndex:0];
// Make self the delegate and datasource of the table view.
self.tblFiles.delegate = self;
self.tblFiles.dataSource = self;
// Disable scrolling in table view.
self.tblFiles.scrollEnabled = NO;
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.BGTransferDemo"];
sessionConfiguration.HTTPMaximumConnectionsPerHost = 5;
self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
delegate:self
delegateQueue:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Private method implementation
-(void)initializeFileDownloadDataArray{
self.arrFileDownloadData = [[NSMutableArray alloc] init];
[self.arrFileDownloadData addObject:[[FileDownloadInfo alloc] initWithFileTitle:@"iOS Programming Guide" andDownloadSource:@"https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/iphoneappprogrammingguide.pdf"]];
[self.arrFileDownloadData addObject:[[FileDownloadInfo alloc] initWithFileTitle:@"Human Interface Guidelines" andDownloadSource:@"https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/MobileHIG.pdf"]];
[self.arrFileDownloadData addObject:[[FileDownloadInfo alloc] initWithFileTitle:@"Networking Overview" andDownloadSource:@"https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/NetworkingOverview.pdf"]];
[self.arrFileDownloadData addObject:[[FileDownloadInfo alloc] initWithFileTitle:@"AV Foundation" andDownloadSource:@"https://developer.apple.com/library/ios/documentation/AudioVideo/Conceptual/AVFoundationPG/AVFoundationPG.pdf"]];
[self.arrFileDownloadData addObject:[[FileDownloadInfo alloc] initWithFileTitle:@"iPhone User Guide" andDownloadSource:@"http://manuals.info.apple.com/MANUALS/1000/MA1565/en_US/iphone_user_guide.pdf"]];
}
-(int)getFileDownloadInfoIndexWithTaskIdentifier:(unsigned long)taskIdentifier{
int index = 0;
for (int i=0; i<[self.arrFileDownloadData count]; i++) {
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:i];
if (fdi.taskIdentifier == taskIdentifier) {
index = i;
break;
}
}
return index;
}
#pragma mark - UITableView Delegate and Datasource method implementation
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.arrFileDownloadData.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"idCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"idCell"];
}
// Get the respective FileDownloadInfo object from the arrFileDownloadData array.
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:indexPath.row];
// Get all cell's subviews.
UILabel *displayedTitle = (UILabel *)[cell viewWithTag:10];
UIButton *startPauseButton = (UIButton *)[cell viewWithTag:CellStartPauseButtonTagValue];
UIButton *stopButton = (UIButton *)[cell viewWithTag:CellStopButtonTagValue];
UIProgressView *progressView = (UIProgressView *)[cell viewWithTag:CellProgressBarTagValue];
UILabel *readyLabel = (UILabel *)[cell viewWithTag:CellLabelReadyTagValue];
NSString *startPauseButtonImageName;
// Set the file title.
displayedTitle.text = fdi.fileTitle;
// Depending on whether the current file is being downloaded or not, specify the status
// of the progress bar and the couple of buttons on the cell.
if (!fdi.isDownloading) {
// Hide the progress view and disable the stop button.
progressView.hidden = YES;
stopButton.enabled = NO;
// Set a flag value depending on the downloadComplete property of the fdi object.
// Using it will be shown either the start and stop buttons, or the Ready label.
BOOL hideControls = (fdi.downloadComplete) ? YES : NO;
startPauseButton.hidden = hideControls;
stopButton.hidden = hideControls;
readyLabel.hidden = !hideControls;
startPauseButtonImageName = @"play-25";
}
else{
// Show the progress view and update its progress, change the image of the start button so it shows
// a pause icon, and enable the stop button.
progressView.hidden = NO;
progressView.progress = fdi.downloadProgress;
stopButton.enabled = YES;
startPauseButtonImageName = @"pause-25";
}
// Set the appropriate image to the start button.
[startPauseButton setImage:[UIImage imageNamed:startPauseButtonImageName] forState:UIControlStateNormal];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 60.0;
}
#pragma mark - IBAction method implementation
- (IBAction)startOrPauseDownloadingSingleFile:(id)sender {
// Check if the parent view of the sender button is a table view cell.
if ([[[sender superview] superview] isKindOfClass:[UITableViewCell class]]) {
// Get the container cell.
UITableViewCell *containerCell = (UITableViewCell *)[[sender superview] superview];
// Get the row (index) of the cell. We'll keep the index path as well, we'll need it later.
NSIndexPath *cellIndexPath = [self.tblFiles indexPathForCell:containerCell];
int cellIndex = cellIndexPath.row;
// Get the FileDownloadInfo object being at the cellIndex position of the array.
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:cellIndex];
// The isDownloading property of the fdi object defines whether a downloading should be started
// or be stopped.
if (!fdi.isDownloading) {
// This is the case where a download task should be started.
// Create a new task, but check whether it should be created using a URL or resume data.
if (fdi.taskIdentifier == -1) {
// If the taskIdentifier property of the fdi object has value -1, then create a new task
// providing the appropriate URL as the download source.
fdi.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:fdi.downloadSource]];
// Keep the new task identifier.
fdi.taskIdentifier = fdi.downloadTask.taskIdentifier;
// Start the task.
[fdi.downloadTask resume];
}
else{
// Create a new download task, which will use the stored resume data.
fdi.downloadTask = [self.session downloadTaskWithResumeData:fdi.taskResumeData];
[fdi.downloadTask resume];
// Keep the new download task identifier.
fdi.taskIdentifier = fdi.downloadTask.taskIdentifier;
}
}
else{
// Pause the task by canceling it and storing the resume data.
[fdi.downloadTask cancelByProducingResumeData:^(NSData *resumeData) {
if (resumeData != nil) {
fdi.taskResumeData = [[NSData alloc] initWithData:resumeData];
}
}];
}
// Change the isDownloading property value.
fdi.isDownloading = !fdi.isDownloading;
// Reload the table view.
[self.tblFiles reloadRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationNone];
}
}
- (IBAction)stopDownloading:(id)sender {
if ([[[sender superview] superview] isKindOfClass:[UITableViewCell class]]) {
// Get the container cell.
UITableViewCell *containerCell = (UITableViewCell *)[[sender superview] superview];
// Get the row (index) of the cell. We'll keep the index path as well, we'll need it later.
NSIndexPath *cellIndexPath = [self.tblFiles indexPathForCell:containerCell];
int cellIndex = cellIndexPath.row;
// Get the FileDownloadInfo object being at the cellIndex position of the array.
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:cellIndex];
// Cancel the task.
[fdi.downloadTask cancel];
// Change all related properties.
fdi.isDownloading = NO;
fdi.taskIdentifier = -1;
fdi.downloadProgress = 0.0;
// Reload the table view.
[self.tblFiles reloadRowsAtIndexPaths:@[cellIndexPath] withRowAnimation:UITableViewRowAnimationNone];
}
}
- (IBAction)startAllDownloads:(id)sender {
// Access all FileDownloadInfo objects using a loop.
for (int i=0; i<[self.arrFileDownloadData count]; i++) {
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:i];
// Check if a file is already being downloaded or not.
if (!fdi.isDownloading) {
// Check if should create a new download task using a URL, or using resume data.
if (fdi.taskIdentifier == -1) {
fdi.downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:fdi.downloadSource]];
}
else{
fdi.downloadTask = [self.session downloadTaskWithResumeData:fdi.taskResumeData];
}
// Keep the new taskIdentifier.
fdi.taskIdentifier = fdi.downloadTask.taskIdentifier;
// Start the download.
[fdi.downloadTask resume];
// Indicate for each file that is being downloaded.
fdi.isDownloading = YES;
}
}
// Reload the table view.
[self.tblFiles reloadData];
}
- (IBAction)stopAllDownloads:(id)sender {
// Access all FileDownloadInfo objects using a loop.
for (int i=0; i<[self.arrFileDownloadData count]; i++) {
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:i];
// Check if a file is being currently downloading.
if (fdi.isDownloading) {
// Cancel the task.
[fdi.downloadTask cancel];
// Change all related properties.
fdi.isDownloading = NO;
fdi.taskIdentifier = -1;
fdi.downloadProgress = 0.0;
fdi.downloadTask = nil;
}
}
// Reload the table view.
[self.tblFiles reloadData];
}
- (IBAction)initializeAll:(id)sender {
// Access all FileDownloadInfo objects using a loop and give all properties their initial values.
for (int i=0; i<[self.arrFileDownloadData count]; i++) {
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:i];
if (fdi.isDownloading) {
[fdi.downloadTask cancel];
}
fdi.isDownloading = NO;
fdi.downloadComplete = NO;
fdi.taskIdentifier = -1;
fdi.downloadProgress = 0.0;
fdi.downloadTask = nil;
}
// Reload the table view.
[self.tblFiles reloadData];
NSFileManager *fileManager = [NSFileManager defaultManager];
// Get all files in documents directory.
NSArray *allFiles = [fileManager contentsOfDirectoryAtURL:self.docDirectoryURL
includingPropertiesForKeys:nil
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
for (int i=0; i<[allFiles count]; i++) {
[fileManager removeItemAtURL:[allFiles objectAtIndex:i] error:nil];
}
}
#pragma mark - NSURLSession Delegate method implementation
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *destinationFilename = downloadTask.originalRequest.URL.lastPathComponent;
NSURL *destinationURL = [self.docDirectoryURL URLByAppendingPathComponent:destinationFilename];
if ([fileManager fileExistsAtPath:[destinationURL path]]) {
[fileManager removeItemAtURL:destinationURL error:nil];
}
BOOL success = [fileManager copyItemAtURL:location
toURL:destinationURL
error:&error];
if (success) {
// Change the flag values of the respective FileDownloadInfo object.
int index = [self getFileDownloadInfoIndexWithTaskIdentifier:downloadTask.taskIdentifier];
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:index];
fdi.isDownloading = NO;
fdi.downloadComplete = YES;
// Set the initial value to the taskIdentifier property of the fdi object,
// so when the start button gets tapped again to start over the file download.
fdi.taskIdentifier = -1;
// In case there is any resume data stored in the fdi object, just make it nil.
fdi.taskResumeData = nil;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Reload the respective table view row using the main thread.
[self.tblFiles reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]]
withRowAnimation:UITableViewRowAnimationNone];
}];
}
else{
NSLog(@"Unable to copy temp file. Error: %@", [error localizedDescription]);
}
}
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
if (error != nil) {
NSLog(@"Download completed with error: %@", [error localizedDescription]);
}
else{
NSLog(@"Download finished successfully.");
}
}
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
if (totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown) {
NSLog(@"Unknown transfer size");
}
else{
// Locate the FileDownloadInfo object among all based on the taskIdentifier property of the task.
int index = [self getFileDownloadInfoIndexWithTaskIdentifier:downloadTask.taskIdentifier];
FileDownloadInfo *fdi = [self.arrFileDownloadData objectAtIndex:index];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Calculate the progress.
fdi.downloadProgress = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
// Get the progress view of the appropriate cell and update its progress.
UITableViewCell *cell = [self.tblFiles cellForRowAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
UIProgressView *progressView = (UIProgressView *)[cell viewWithTag:CellProgressBarTagValue];
progressView.progress = fdi.downloadProgress;
}];
}
}
-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
// Check if all download tasks have been finished.
[self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
if ([downloadTasks count] == 0) {
if (appDelegate.backgroundTransferCompletionHandler != nil) {
// Copy locally the completion handler.
void(^completionHandler)() = appDelegate.backgroundTransferCompletionHandler;
// Make nil the backgroundTransferCompletionHandler.
appDelegate.backgroundTransferCompletionHandler = nil;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Call the completion handler to tell the system that there are no other background transfers.
completionHandler();
// Show a local notification when all downloads are over.
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = @"All files have been downloaded!";
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}];
}
}
}];
}
@end
最佳答案
进度不工作的原因,因为您需要记住哪些项目开始下载,并再次创建相应的下载任务并在该任务上调用恢复。
为了避免这种情况,您需要将下载逻辑分离到不同的类中,例如您可以创建 DownloadManager 类,该类将启动下载并提供有关进度、完成、错误的反馈。 DownloadManager 可以是单例的,因此您可以从任何地方访问下载进度。
更新
这是示例的链接:
https://github.com/hovox/downloading-file-example
关于ios - UITableview 在 background-transfer-service-ios7/中没有更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28655891/
I made an example , 我直接从 jQuery website 复制了它然而,它不会转移.. HTML: BLAHHHH
所以我对名字有一些误解STATE TRANSFER在 REPRESENTATIONAL STATE TRANSFER. 是 state transfer意味着传输当前时间实例中服务器中存在的资源的表示
我的代码将文件从远程服务器下载到我们的服务器。 通常,一个文件最多需要一分钟左右的时间才能完成下载。但有时下载时间会超过 5 分钟。 如果当前下载时间超过 5 分钟,是否可以重新开始下载? Tamir
Representational State Transfer中的State Transfer是指什么? 找到了一些关于这个的解释(例如 here )但我还是不明白。例如文章中说 The repres
在阅读 C# 时,我遇到了“数据传输类型”和“数据传输对象”这两个术语。这显示在匿名类型周围,其中动态创建类型以保存结果,例如来自 LINQ。这两个术语指的是同一件事吗? 谢谢, 斯科特 最佳答案 我
以下代码: public string add_button_tooltip_markup { get { return add_button.get_tooltip_markup (); }
您可以在下面看到外部测试人员的测试已关闭: 内部测试相同: 但是当我转移应用程序时,不满足其中一个条件: 为什么? 最佳答案 我遇到了完全相同的问题,通过如上所述从 TestFlight 中删除所有
我对 Java 和 REST/REST 很陌生。我正在尝试创建一个设置了“Transfer-Encoding: chunked”的 POST 请求(通过 header ),但出现异常“org.apac
我是 mysql 新手,想知道我在代码中会怎么说。如果 Narrive = "transfer"则将 AccountID 更改为 2001 请有人给我一步一步的说明,并请解释一下我会将这段代码放在哪里
我有一个对象是数据库查询的结果,看起来像这样(var_dump 输出): object(stdClass)#17 (6) { ["id"]=> string(1) "1" ["title"
使用方法 Server.Transfer("default.aspx")以获得更好的在网站内导航的性能。当我使用它时,它不会更改地址栏中的 url。如何通过 server.transfer 获取新 u
我正在使用 lftp 将文件从本地传输到仅允许 SFTP 访问的远程服务器。 我使用以下语法来传输文件: lftp -c "open -u $UN,$Pass sftp://$Server ; mir
使用我编写的FTP客户端,有时上传完成后,有时会从FileZilla服务器收到226 Transfer OK消息,有时我什么也收不到。并不是在收到226 Transfer OK之前客户端已断开连接,因
我的 Chrome 应用程序和一个简单的设备之间没有发生任何类型的传输,只是等待数据进入其 uart rx 线路。设备接口(interface)的端点类型为bulk,尽管我已经尝试了所有可用的传输类型
我正在通过 SFTP 和 FileZilla 传输一个非常大的 (35GB) 文件。 现在传输已完成59.7%,但我不断收到此错误,并且几个小时内该数字都没有更改。 Error: File t
经过大量研究,我仍然没有答案。 我使用 WebForm 应用程序 VS 2013。 我的代码相当简单: Server.Transfer("~/Success.aspx",true); 此后,执行 Su
抱歉,标题令人困惑;然而,描述和插图应该可以解决这个问题。 本质上,我有表 A 表示表 B 的行之间“金额”转移的实例。 我希望加入 A 和 B 以便我可以显示转帐的详细信息: ===========
我正在使用 iOS 版 Plaid API 编写一个程序,该程序在身份验证后访问银行帐户并显示交易数据。 我需要知道是否可以在帐户之间转移资金(支票到储蓄)以及如何转移。 我知道 acorns 使用相
我需要通过同一网络在不同计算机之间复制/传输一些文件。经过一些阅读和搜索后,我认为尝试 Java 的 jsch 可能是一个不错的选择。令人痛苦的事实是,可能没有针对 jsch 的好的文档。但据我所知,
我正在使用 XMLHttpRequest 读取 json 文件,发现“通过网络传输”明显大于资源大小。 xmlhttp.open("GET", "resources.json", true); 而其他
我是一名优秀的程序员,十分优秀!