Giter Site home page Giter Site logo

guowilling / srdownloadmanager Goto Github PK

View Code? Open in Web Editor NEW
230.0 6.0 37.0 1.7 MB

Powerful and easy-to-use file download manager based on NSURLSession. Provide download status, progress and completion callback block.

License: MIT License

Objective-C 99.65% Ruby 0.35%
file-download breakpoint-download download-manager multitasking progress waiting queue

srdownloadmanager's People

Contributors

guowilling avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

srdownloadmanager's Issues

友情提示:两个问题和解决方案

@guowilling 我在公司项目中使用了SRDownloadManager,感觉还是不错的,目前发现两个问题:

问题1. 下载过程中的plist写入操作崩溃:

在批量下载多个文件时,在这里会出现崩溃,原因是Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSCFDictionary: 0x2815d2680> was mutated while being enumerated.'

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
    ...
    // 崩溃在这里
    [self.filesTotalLengthPlist writeToFile:SRFilesTotalLengthPlistPath atomically:YES];
    ...
}

分析原因:

下载开始时会从主线程里对这个字典进行读写操作,下载回调代理didReceiveResponse也会对字典进行读写操作,但是发生其他线程中;而批量下载很容易导致同时在多个线程中对该字典进行读写,造成冲突。

解决方案:

  1. 建议对可能在多线程中使用的集合属性使用atomic关键字
  2. 只用atomic还不够,因为该关键字只是用来保护set和get方法,不包含其他读写操作,所以我选择在[filesTotalLengthPlist writeToFile:]方法前后再进行锁操作,由于源码中两次分别在不同线程中使用了writeToFile,考虑到NSLock对线程也会敏感,因此使用了两个NSLock对象来做保护。
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler {
    ...
    [self.lock1 lock];
    self.filesTotalLengthPlist[SRFileName(downloadModel.URL)] = @(totalLength);
    [self.filesTotalLengthPlist writeToFile:SRFilesTotalLengthPlistPath atomically:YES];
    [self.lock1 unlock];
    ...
}

- (void)deleteDownloadedFileOfURL:(NSURL *)URL {
    ...    
    [self.lock2 lock];
    [self.filesTotalLengthPlist removeObjectForKey:SRFileName(URL)];
    [self.filesTotalLengthPlist writeToFile:SRFilesTotalLengthPlistPath atomically:YES];
    [self.lock2 unlock];
    ...
}

问题2. 我们项目中使用了自己定义的下载目录,由于其他清理文件的操作导致了下载目录被删除,但是SRDownloadManager并不知情,所以下次下载文件时,总是出现file download incomplete的问题。

分析原因:

由于下载目录的缺失,执行到[outputStream open]会因为找不到目录而导致出错,这时候outputStream.streamError会出现Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory" UserInfo={_kCFStreamErrorCodeKey=2, _kCFStreamErrorDomainKey=1}的问题

解决方案:

  1. 执行[outputStream open]后,建议检查下outputSteamstreamError或者streamStatus,可能这时候会有错误,需要重视
  2. 执行[outputStream write:maxLength:]时建议拿到方法return的数据,如果返回0或者-1的话,说明写入出错,需要重视
  3. 每次下载前,还是要确保下载目录一定得存在,如果没有还是要[fileManager createDirectoryAtPath:]

最后我解释一下为什么自己说了这么多,确没有帮你改掉并且提交PR呢?

  1. 我的分析也不一定是标准答案,如果有问题,欢迎回复交流
  2. 我的解决方案只是为了给自己的项目打补丁,我相信你的解决方案也许会比我的更好
  3. 推荐使用单元测试来进一步提升代码质量

正好今天是程序员节, So thanks for open source. Wish for the best!

多任务进度

支持Pod,赞一个。
请问怎么获取多个任务的进度。一个课程有多个课件
可能需要一个获取单个任务大小的接口。

Download in UITableView

When download through tableview SRDownloadManager is reduce it's accuracy and downloading url in other TableView row so how can fix this, i think this library no longer maintain.

文件下载失败

下载进度100%,也可以正常播放。但是状态判断有问题。

把所有下载都暂停之后过几分钟会都失败

把所有的下载都暂停了, 等待一段时间, 会走代理方法 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
报错: Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo={NSUnderlyingError=0x610000054cd0 {Error Domain=kCFErrorDomainCFNetwork Code=-1001 "(null)" UserInfo={_kCFStreamErrorCodeKey=-2102, _kCFStreamErrorDomainKey=4}}, NSErrorFailingURLStringKey=http://yxfile.idealsee.com/9f6f64aca98f90b91d260555d3b41b97_mp4.mp4, NSErrorFailingURLKey=http://yxfile.idealsee.com/9f6f64aca98f90b91d260555d3b41b97_mp4.mp4, _kCFStreamErrorDomainKey=4, _kCFStreamErrorCodeKey=-2102, NSLocalizedDescription=The request timed out.}

Feature request: Prioritize a download

Would be really good if I could prioritize a URL, then it should be the first to pick (even on FIFO or FILO)

Use case: I'm downloading a lot of videos, but i want to download the video I need first, even if the URL is in the middle of waiting array

To get the status of download if not in same page where the download starts

Hi my use case is like this

I start a download and show a status of that download in that page, now I go back to my home page and there I want to show the download status of that particular element. The main approach is to get the download progress of the file by its unique identifier. Do you have that kind of thing?

求指教

我测试的时候发现了些问题,表示很不解:
1、APP在下载过程中突然崩溃了,如何去保存completionHandler()?

2、在- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler 中,好像并不需要创建参照? 我发现没创建也是OK的,不知道和创建了有什么区别

3、如果我创建了多个NSURLSession,到后台后是不是要保存多份completionHandler()?

4、我重新进入APP的时候,创建NSURLSession就自动给我继续下载了,导致我在逻辑处理出了问题,怎么让它不自动下载?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.