AFNetworking 2.0.0在后台下载
我正在使用'AFNetworking', '2.0.0'
下载数据。AFNetworking 2.0.0在后台下载
我需要下载大文件。当用户锁定屏幕或按Home键时,应该暂停(或继续在后台下载),如果我返回到应用程序,它应该恢复。
此外我需要显示下载的进度。
我搜索了很多例子,但是没有找到任何东西'AFNetworking', '2.0.0'
。
我为iOS 6.0+版本创建应用程序,因此我无法使用AFHTTPSessionManager
或AFURLSessionManager
。
也许你使用DTDownload会更好: https://github.com/Cocoanetics/DTDownload
据我所知,它并没有什么报告进度。
编辑:有一个很好的教程超过在AppCoda,关于使用NSURLSessionTask: http://www.appcoda.com/background-transfer-service-ios7/
当你的应用程序切换到后台暂停/停止下载操作,并配备在前台时恢复中的NSOperation队列已暂停下载操作。 阅读这些代码可以帮助你:
AFDownloadRequestOperation *operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:filePath shouldResume:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//handel completion
[operations removeObjectForKey:audioItem.filename];
}failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//handel failure
operation = [operations objectForKey:audioItem.filename];
[operation cancel];
[operations removeObjectForKey:audioItem.filename];
if (error.code != NSURLErrorCancelled) {
[self showErrorAlert];
NSLog(@"Error: %@", error);
}
}];
[operation setProgressiveDownloadProgressBlock:^(NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
//handel progress
NSNumber *progress = [NSNumber numberWithFloat:((float)totalBytesReadForFile/(float)totalBytesExpectedToReadForFile)];
float progress=progress.floatValue;
[self performSelectorOnMainThread:@selector(updateProgressBar:) withObject:[NSArray arrayWithObjects:audioItem, progress, nil] waitUntilDone: YES];
}];
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
// TODO: Clean up operations
NSLog(@"App has been in background too long, need to clean up any connections!");
}];
[operations setValue:operation forKey:@"key"]; // store the NSOperation for further use in application to track its status.
[downloadQueue addOperation:operation];//here downloadQueue is NSOperationQueue instance that manages NSOperations.
要暂停下载操作使用本:
[operation pause];
要继续使用该行的类别:
[operation resume];
什么是'操作'? – Siriss
“操作”在这里是NSMutableDictionary,将文件名存储为键并将NSOperation对象存储为值。 –
对于后台下载在iOS 7或更高版本上,我使用NSURLSession
和NSURLSessionDownloadTask
。在ProjectNavigator-> YourProject-> YourTarget->功能上BackgroundMode
开关(标签) - >背景模式
加入您的AppDelegate方法- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
为NSURLSessin
与下一个代码的初始化剂:
NSURLSessionConfiguration *sessionConfiguration;
NSString *someUniqieIdentifierForSession = @"com.etbook.background.DownloadManager";
if ([[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."] firstObject] integerValue] >= 8) {
//This code for iOS 8 and greater
sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:someUniqieIdentifierForSession];
} else {
this code for iOS 7
sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfiguration:someUniqieIdentifierForSession];
}
sessionConfiguration.HTTPMaximumConnectionsPerHost = 5;
self.session = [NSURLSession sessionWithConfiguration:sessionConfiguration
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
当然,不要忘了申报session
属性搭配:
@property (nonatomic, strong) NSURLSession session;
另外补充完成处理特性(它会需要,如果你想申请终止或崩溃后获得后台下载程序的回调):
@property (nonatomic, copy) void(^backgroundTransferCompletionHandler)();
添加委托方法中的AppDelegate:
-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
NSError *error;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *destinationFilename = downloadTask.originalRequest.URL.lastPathComponent;
NSURL *destinationURL = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:destinationFilename];
if ([fileManager fileExistsAtPath:[destinationURL path]]) {
[fileManager removeItemAtURL:destinationURL error:nil];
}
[fileManager copyItemAtURL:location
toURL:destinationURL
error:&error];
}
-(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{
NSLog(@"progress = %lld Mb of %lld Mb", totalBytesWritten/1024/1024, totalBytesExpectedToWrite/1024/1024);
}
}
-(void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session{
ETBAppDelegate *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];
}];
}
}
}];
}
//Background download support (THIS IMPORTANT METHOD APPLICABLE ONLY IN YOUR AppDelegate.m FILE!!!)
-(void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
self.backgroundTransferCompletionHandler = completionHandler;
}
并声明你的类(在AppDelegate中。在我的例子.h文件)符合协议NSURLSessionDelegate
喜欢这里:
NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:[NSURL URLWithString:urlString]];
task.taskDescription = [NSString stringWithFormat:@"Downloading file %@", [urlString lastPathComponent]];
[task resume];
所以,当你的应用程序结束后开始,您的会话将被恢复并委托方法:
@interface AppDelegate : UIResponder <UIApplicationDelegate, NSURLSessionDelegate>
然后再添加下载任务将被解雇。此外,如果您的应用程序将从后台唤醒到前台,您的应用程序委托方法也会被触发。
也许你可以在这里找到解决方案:http://*.com/questions/12563753/afnetworking-not-resuming-download – Weizhi