一个基于 NSURLSession 的现代 iOS (Objective C) 下载管理器,用于处理多个文件的非同步下载、管理和持久化。
TWRDownloadManager 是一个单例实例,因此可以从代码中的任何位置安全地调用它。编写另一个下载管理器库的想法源于当时(现在也是如此)没有可用的开源项目基于苹果在 iOS 7 中提供的新的 NSURLSession
API。
TWRDownloadManager 利用 NSURLSession
和 NSURLSessionDownloadTask
的功能,使得文件的下载和进度跟踪变得简单易行。
2014年9月22日 - 更新!!!
版本 1.0.0 的 TWRDownloadManager
现在支持后台模式。由于 API 已更改,因此不向后兼容,因此其版本号提升到 1.0.0。有关更多信息,请参阅下面的文档。
还添加了一个示例项目,以展示下载管理器的最简单使用方式。
版本 1.1.0 的 TWRDownloadManager
添加了在创建下载时传递一个块来跟踪估计剩余下载时间的功能。该算法肯定可以改进,但它已经可以工作了。
更新示例项目。
要使用此库,只需将依赖项添加到您的 Podfile
platform :ios
pod 'TWRDownloadManager'
运行 pod install
以安装依赖项。
然后,在任何需要使用管理器的地方导入头文件
#import <TWRDownloadManager/TWRDownloadManager.h>
由于 TWRDownloadManager 是一个单例,因此您可以在项目的 .pch
文件中导入它,以便在需要的地方访问和使用它,而无需在每个类中导入它。
TWRDownloadManager
提供以下任务的功能
以下所有实例方法都可以直接在 [TWRDownloadManager sharedManager]
上调用。
- (void)downloadFileForURL:(NSString *)url
withName:(NSString *)fileName
inDirectoryNamed:(NSString *)directory
progressBlock:(void(^)(CGFloat progress))progressBlock
completionBlock:(void(^)(BOOL completed))completionBlock
enableBackgroundMode:(BOOL)backgroundMode;
- (void)downloadFileForURL:(NSString *)url
inDirectoryNamed:(NSString *)directory
progressBlock:(void(^)(CGFloat progress))progressBlock
completionBlock:(void(^)(BOOL completed))completionBlock
enableBackgroundMode:(BOOL)backgroundMode;
- (void)downloadFileForURL:(NSString *)url
progressBlock:(void(^)(CGFloat progress))progressBlock
completionBlock:(void(^)(BOOL completed))completionBlock
enableBackgroundMode:(BOOL)backgroundMode;
开始使用最简单的方法是将需要下载的文件的URL字符串传递给上述方法中的最后一个方法。你可以传入两个块来帮助你跟踪下载进度(一个从0到1的浮点数)以及任务的完成情况。
所有下载的文件一旦下载完毕,将被从设备的/tmp
目录移动到Caches目录,这是出于两个原因:
/tmp
目录可以偶尔清理,以确保任何部分下载、取消或失败的下载都得到适当的处理,以免占用设备和iTunes备份的空间;如果提供了目录名,将在Cached目录中创建一个新的子目录。
一旦文件下载完成,如果用户提供了文件名,该文件名将用于在最终目的地存储文件。如果没有提供名称,管理器将默认使用URL字符串的最后部分作为文件名(例如,对于http://www.example.com/files/my_file.zip
,最终文件名将是my_file.zip
)。
要检查文件是否正在下载,可以使用以下方法之一:
- (BOOL)isFileDownloadingForUrl:(NSString *)url withProgressBlock:(void(^)(CGFloat progress))block;
- (BOOL)isFileDownloadingForUrl:(NSString *)url withProgressBlock:(void(^)(CGFloat progress))block completionBlock:(void(^)(BOOL completed))completionBlock;
与之前的下载方法一样,你可以有机会被回调以获取进度和完成情况。
要获取当前正在下载的文件列表,可以使用以下方法:
- (NSArray *)currentDownloads;
此方法返回一个包含当前正在执行的下载的URL的NSString
对象数组。
下载,由提供者通过URL唯一引用,可以通过以下两种方法中的任何一个单独取消或全部取消:
- (void)cancelAllDownloads;
- (void)cancelDownloadForUrl:(NSString *)urlString;
TWRDownloadManager还提供了一些处理下载文件的功能。
你可以检查是否存在...
- (BOOL)fileExistsForUrl:(NSString *)urlString;
- (BOOL)fileExistsForUrl:(NSString *)urlString inDirectory:(NSString *)directoryName;
- (BOOL)fileExistsWithName:(NSString *)fileName;
- (BOOL)fileExistsWithName:(NSString *)fileName inDirectory:(NSString *)directoryName;
……并使用以下方法检索文件位置:
- (NSString *)localPathForFile:(NSString *)fileIdentifier;
- (NSString *)localPathForFile:(NSString *)fileIdentifier inDirectory:(NSString *)directoryName;
可以通过以下方法删除下载的文件:
- (BOOL)deleteFileForUrl:(NSString *)urlString;
- (BOOL)deleteFileForUrl:(NSString *)urlString inDirectory:(NSString *)directoryName;
- (BOOL)deleteFileWithName:(NSString *)fileName;
- (BOOL)deleteFileWithName:(NSString *)fileName inDirectory:(NSString *)directoryName;
要在iOS 7+中启用背景下载,请按照以下步骤操作:
Capabilities
标签,最后启用背景模式- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler{
[TWRDownloadManager sharedManager].backgroundTransferCompletionHandler = completionHandler;
}
application:didFinishLaunchingWithOptions:
中注册本地通知,以便在下载完成时向用户显示一条消息if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
}
TWRDownloadManager
能够同时跟踪多个下载,因此可以用来在一個網格視圖中显示当前下载的列表。
这只是使用TWRDownloadManager
实现的一些建议。
在你的UITableViewCell
子类中,导入<TWRDownloadManager/TWRDownloadObject.h>
。
定义你的进度和完成块作为两个属性
@property (strong, nonatomic) TWRDownloadProgressBlock progressBlock;
@property (strong, nonatomic) TWRDownloadCompletionBlock completionBlock;
在你的实现(.m)文件中,定义它们的块获取器
- (TWRDownloadProgressBlock)progressBlock {
__weak typeof(self)weakSelf = self;
return ^void(CGFloat progress){
dispatch_async(dispatch_get_main_queue(), ^(void) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
// do something with the progress on the cell!
});
};
}
- (TWRDownloadCompletionBlock)completionBlock {
__weak typeof(self)weakSelf = self;
return ^void(BOOL completed){
dispatch_async(dispatch_get_main_queue(), ^(void) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
// do something
});
};
}
最后,别忘了在单元格可以重用之前将块设置为nil
-(void)prepareForReuse {
self.progressBlock = nil;
}
现在,在您的代码中,每当您创建一个新的单元格时,您都可以获取单元格的进度和完成模块,并将它们传递给下载管理器。哇!
TWRDownloadManager
需要iOS 7.x或更高版本。
使用是在MIT许可证下提供的。有关详细信息,请参阅LICENSE文件。
欢迎所有贡献。请复制该项目以添加功能,并在下一个版本中通过提交拉取请求使其合并到主分支中。