【发布时间】:2014-03-24 03:55:46
【问题描述】:
我有一个 ViewController,用户可以点击一个按钮并开始一个相对较大的下载(大约 200mb)。我有所有正确的 NSUrlSession 委托,只要用户不离开 ViewController,UIProgressView 就会完美更新,一切下载都很好。我的问题是,在下载文件时,我希望用户能够转到其他 ViewController,但仍然能够回来查看下载进度。
但是,在导航到不同的 ViewController 并返回后,委托方法不会为下载任务触发。我可以通过 NSLog 知道该文件仍在下载,但 UIProgressView 不再更新,因为没有调用委托方法。当返回页面时,如何获取当前正在运行的下载任务并触发其委托方法以正确更新进度视图?
当我导航到“下载文件”页面时,我设置了 NSUrlSession。
- (void)viewDidLoad
{
[super viewDidLoad];
// Create a session with the custom configuration
self.session = [self backgroundSession];
}
- (NSURLSession *)backgroundSession
{
static NSURLSession *session = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken,
^{
// Session Configuration
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.NSUrlSession.app"];
// Initialize Session
session = [NSURLSession sessionWithConfiguration:sessionConfiguration
delegate:self
delegateQueue:nil];
});
return session;
}
然后我有一个创建下载任务并开始下载的按钮。
- (IBAction)downloadMovie:(id)sender
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:LARGE_MOVIE]];
NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
[task resume];
}
这里是更新 UIProgressView 的委托方法
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
double progress = (double) (totalBytesWritten/1024) / (double) (totalBytesExpectedToWrite/1024);
dispatch_async(dispatch_get_main_queue(),
^{
[self.progressView setProgress:progress animated:NO];
NSLog(@"%f", progress);
});
}
就像我说的,只要用户不导航到不同的视图控制器,一切都会完美下载,并且 UIProgressView 会正确更新。但是,如果用户离开并返回,新实例化的视图控制器与分配给会话的委托的原始视图控制器不同,因此委托方法不会触发并且它不会更新 UIProgressView,即使文件仍在后台下载,您可以从 NSLog 更新中看出。
【问题讨论】:
-
哪些委托功能?你能检查委托人还活着吗?
-
@NeverHopeless 在 URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: 委托函数中,我更新了 UIProgressview 并有一条 NSLog 消息显示(totalBytesWritten / totalBytesExpectedToWrite)。当我转到另一个视图控制器时,NSLog 消息仍在触发,显示当前进度,所以我知道文件仍在某个后台进程中下载。但是,当我回到视图控制器时,如果我在那个委托方法上有一个断点,程序不会停止并且 NSLog 消息仍然会触发。
-
@NeverHopeless 我猜如果我可以获取活动下载任务并将其委托作为新实例化的视图控制器,它将再次开始正确更新 UIProgressView,但我不知道如何这样做。
-
您是否可以在显示文件仍在下载的同一 NSLog 中打印 NSURLSession 的委托?
-
另外,您能否检查一下您是否没有在某处设置delegate = nil,例如
viewDidDisappear等。您能告诉我们一些代码吗?
标签: ios objective-c nsurlsession