|
@@ -18,29 +18,47 @@
|
|
#import "VLCMediaFileDiscoverer.h"
|
|
#import "VLCMediaFileDiscoverer.h"
|
|
#import "VLC-Swift.h"
|
|
#import "VLC-Swift.h"
|
|
|
|
|
|
-@interface VLCHTTPFileDownloader () <NSURLSessionDelegate>
|
|
|
|
|
|
+@interface VLCHTTPFileDownloaderTask: NSObject
|
|
|
|
+@property (nonatomic) NSURLSessionTask *sessionTask;
|
|
|
|
+@property (nonatomic, copy) NSURL *url;
|
|
|
|
+@property (nonatomic, copy) NSString *fileName;
|
|
|
|
+@property (nonatomic, copy) NSURL *fileURL;
|
|
|
|
+@end
|
|
|
|
+
|
|
|
|
+@implementation VLCHTTPFileDownloaderTask
|
|
|
|
+
|
|
|
|
+- (NSMutableURLRequest *)buildRequest
|
|
{
|
|
{
|
|
- NSString *_filePath;
|
|
|
|
- long long _expectedDownloadSize;
|
|
|
|
- NSUInteger _receivedDataSize;
|
|
|
|
- NSString *_fileName;
|
|
|
|
- NSURLSessionTask *_sessionTask;
|
|
|
|
- NSMutableURLRequest *_originalRequest;
|
|
|
|
- NSUInteger _statusCode;
|
|
|
|
|
|
+ NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:self.url];
|
|
|
|
+ [theRequest addValue:[NSString stringWithFormat:@"Mozilla/5.0 (%@; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/%@ Safari/9537.53 VLC for iOS/%@", UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? @"iPad" : @"iPhone", [[UIDevice currentDevice] systemVersion], [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]] forHTTPHeaderField:@"User-Agent"];
|
|
|
|
+ return theRequest;
|
|
}
|
|
}
|
|
|
|
+@end
|
|
|
|
+
|
|
|
|
+@interface VLCHTTPFileDownloader () <NSURLSessionDelegate>
|
|
|
|
|
|
|
|
+@property (nonatomic) NSURLSession *urlSession;
|
|
|
|
+@property (nonatomic) NSMutableDictionary *downloads;
|
|
|
|
+@property (nonatomic) dispatch_queue_t downloadsAccessQueue;
|
|
@end
|
|
@end
|
|
|
|
|
|
@implementation VLCHTTPFileDownloader
|
|
@implementation VLCHTTPFileDownloader
|
|
|
|
|
|
-- (NSString *)userReadableDownloadName
|
|
|
|
|
|
+- (instancetype)init
|
|
{
|
|
{
|
|
- return _fileName;
|
|
|
|
|
|
+ if (self = [super init]) {
|
|
|
|
+ _urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
|
|
|
|
+ delegate:self
|
|
|
|
+ delegateQueue:nil];
|
|
|
|
+ _downloads = [[NSMutableDictionary alloc] init];
|
|
|
|
+ _downloadsAccessQueue = dispatch_queue_create("VLCHTTPFileDownloader.downloadsQueue", DISPATCH_QUEUE_SERIAL);
|
|
|
|
+ }
|
|
|
|
+ return self;
|
|
}
|
|
}
|
|
|
|
|
|
-- (void)downloadFileFromURL:(NSURL *)url
|
|
|
|
|
|
+- (NSString *)downloadFileFromURL:(NSURL *)url
|
|
{
|
|
{
|
|
- [self downloadFileFromURL:url withFileName:nil];
|
|
|
|
|
|
+ return [self downloadFileFromURL:url withFileName:nil];
|
|
}
|
|
}
|
|
|
|
|
|
- (NSString *)createPotentialNameFromName:(NSString *)name
|
|
- (NSString *)createPotentialNameFromName:(NSString *)name
|
|
@@ -75,120 +93,94 @@
|
|
return path;
|
|
return path;
|
|
}
|
|
}
|
|
|
|
|
|
-- (void)downloadFileFromURL:(NSURL *)url withFileName:(NSString*)fileName
|
|
|
|
|
|
+- (NSString *)downloadFileFromURL:(NSURL *)url withFileName:(NSString*)fileName
|
|
{
|
|
{
|
|
- NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
|
|
|
- NSString *basePath = [searchPaths.firstObject stringByAppendingPathComponent:@"Upload"];
|
|
|
|
|
|
+ NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
|
|
|
+ NSString *libraryPath = [searchPaths firstObject];
|
|
|
|
|
|
- if (fileName)
|
|
|
|
- _fileName = [self createPotentialNameFromName:fileName];
|
|
|
|
- else
|
|
|
|
- _fileName = [url.lastPathComponent stringByRemovingPercentEncoding];
|
|
|
|
|
|
+ VLCHTTPFileDownloaderTask *downloadTask = [[VLCHTTPFileDownloaderTask alloc] init];
|
|
|
|
+ downloadTask.url = url;
|
|
|
|
+ NSString *downloadFileName;
|
|
|
|
+ if (fileName) {
|
|
|
|
+ downloadFileName = [self createPotentialNameFromName:fileName];
|
|
|
|
+ } else {
|
|
|
|
+ downloadFileName = [url.lastPathComponent stringByRemovingPercentEncoding];
|
|
|
|
+ }
|
|
|
|
|
|
- if (_fileName.pathExtension.length == 0 || ![_fileName isSupportedFormat]) {
|
|
|
|
- _fileName = [_fileName stringByAppendingPathExtension:@"vlc"];
|
|
|
|
|
|
+ if (downloadFileName.pathExtension.length == 0 || ![downloadFileName isSupportedFormat]) {
|
|
|
|
+ NSString *urlExtension = url.pathExtension;
|
|
|
|
+ NSString *extension = urlExtension.length != 0 ? urlExtension : @"vlc";
|
|
|
|
+ downloadFileName = [fileName stringByAppendingPathExtension:extension];
|
|
}
|
|
}
|
|
|
|
+ downloadTask.fileName = downloadFileName;
|
|
|
|
+ downloadTask.fileURL = [NSURL fileURLWithPath:[libraryPath stringByAppendingPathComponent:downloadFileName]];
|
|
|
|
|
|
- _filePath = [basePath stringByAppendingPathComponent:_fileName];
|
|
|
|
- NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
- if (![fileManager fileExistsAtPath:basePath])
|
|
|
|
- [fileManager createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:nil error:nil];
|
|
|
|
- _expectedDownloadSize = _receivedDataSize = 0;
|
|
|
|
- NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
|
|
|
|
- [theRequest addValue:[NSString stringWithFormat:@"Mozilla/5.0 (%@; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/%@ Mobile/11A465 Safari/9537.53 VLC for iOS/%@", UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? @"iPad" : @"iPhone", [[UIDevice currentDevice] systemVersion], [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]] forHTTPHeaderField:@"User-Agent"];
|
|
|
|
- _originalRequest = [theRequest mutableCopy];
|
|
|
|
-
|
|
|
|
- NSURLSession *urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
|
|
|
|
- _sessionTask = [urlSession dataTaskWithRequest:theRequest];
|
|
|
|
- [_sessionTask resume];
|
|
|
|
- if (!_sessionTask) {
|
|
|
|
|
|
+ NSString *identifier = [[NSUUID UUID] UUIDString];
|
|
|
|
+
|
|
|
|
+ NSURLSessionTask *sessionTask = [self.urlSession downloadTaskWithRequest:[downloadTask buildRequest]];
|
|
|
|
+ sessionTask.taskDescription = identifier;
|
|
|
|
+ [sessionTask resume];
|
|
|
|
+
|
|
|
|
+ if (!sessionTask) {
|
|
APLog(@"failed to establish connection");
|
|
APLog(@"failed to establish connection");
|
|
- _downloadInProgress = NO;
|
|
|
|
|
|
+ return nil;
|
|
} else {
|
|
} else {
|
|
- _downloadInProgress = YES;
|
|
|
|
VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
|
|
VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
|
|
[activityManager networkActivityStarted];
|
|
[activityManager networkActivityStarted];
|
|
[activityManager disableIdleTimer];
|
|
[activityManager disableIdleTimer];
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
-- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse
|
|
|
|
-{
|
|
|
|
- if (redirectResponse) {
|
|
|
|
- NSURL *URL = [request URL];
|
|
|
|
-
|
|
|
|
- NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
-
|
|
|
|
- if ([fileManager fileExistsAtPath:_filePath])
|
|
|
|
- [fileManager removeItemAtPath:_filePath error:nil];
|
|
|
|
-
|
|
|
|
- NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
|
|
|
- NSString *basePath = [searchPaths[0] stringByAppendingPathComponent:@"Upload"];
|
|
|
|
- _fileName = [[URL lastPathComponent] stringByRemovingPercentEncoding];
|
|
|
|
- _filePath = [basePath stringByAppendingPathComponent:_fileName];
|
|
|
|
- if (![fileManager fileExistsAtPath:basePath])
|
|
|
|
- [fileManager createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:nil error:nil];
|
|
|
|
-
|
|
|
|
- NSMutableURLRequest *newRequest = [_originalRequest mutableCopy];
|
|
|
|
- [newRequest setURL:URL];
|
|
|
|
- return newRequest;
|
|
|
|
- } else
|
|
|
|
- return request;
|
|
|
|
|
|
+ downloadTask.sessionTask = sessionTask;
|
|
|
|
+ [self _addDownloadTask:downloadTask identifier:identifier];
|
|
|
|
+
|
|
|
|
+ return identifier;
|
|
}
|
|
}
|
|
|
|
|
|
-- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
|
|
|
|
|
|
+- (void)URLSession:(NSURLSession *)session
|
|
|
|
+ task:(NSURLSessionTask *)task
|
|
|
|
+willPerformHTTPRedirection:(NSHTTPURLResponse *)response
|
|
|
|
+ newRequest:(NSURLRequest *)request
|
|
|
|
+ completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler
|
|
{
|
|
{
|
|
- completionHandler(NSURLSessionResponseAllow);
|
|
|
|
- NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
|
|
|
|
- _statusCode = [httpResponse statusCode];
|
|
|
|
- if (_statusCode == 200) {
|
|
|
|
- _expectedDownloadSize = [response expectedContentLength];
|
|
|
|
- APLog(@"expected download size: %lli", _expectedDownloadSize);
|
|
|
|
- if (_expectedDownloadSize > [[UIDevice currentDevice] VLCFreeDiskSpace].longLongValue) { //handle too big a download
|
|
|
|
- [VLCAlertViewController alertViewManagerWithTitle:NSLocalizedString(@"DISK_FULL", nil)
|
|
|
|
- errorMessage:[NSString stringWithFormat:NSLocalizedString(@"DISK_FULL_FORMAT", nil), _fileName, [[UIDevice currentDevice] model]]
|
|
|
|
- viewController:self.delegate];
|
|
|
|
- [_sessionTask cancel];
|
|
|
|
- [self _downloadEnded];
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- [self.delegate downloadStarted];
|
|
|
|
- } else {
|
|
|
|
- APLog(@"unhandled status code %lu", (unsigned long)_statusCode);
|
|
|
|
- if ([self.delegate respondsToSelector:@selector(downloadFailedWithErrorDescription:)])
|
|
|
|
- [self.delegate downloadFailedWithErrorDescription:[NSString stringWithFormat:NSLocalizedString(@"HTTP_DOWNLOAD_FAILED",nil), _statusCode]];
|
|
|
|
|
|
+ VLCHTTPFileDownloaderTask *downloadTask = [self _downloadTaskWithIdentifier:task.taskDescription];
|
|
|
|
+ NSURL *newUrl = request.URL;
|
|
|
|
+ NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
+
|
|
|
|
+ if ([fileManager fileExistsAtPath:[downloadTask.fileURL path]])
|
|
|
|
+ [fileManager removeItemAtURL:downloadTask.fileURL error:nil];
|
|
|
|
+
|
|
|
|
+ NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
|
|
|
+ NSString *basePath = [[searchPaths firstObject] stringByAppendingPathComponent:@"Upload"];
|
|
|
|
+ downloadTask.fileName = [[newUrl lastPathComponent] stringByRemovingPercentEncoding];
|
|
|
|
+ downloadTask.fileURL = [NSURL fileURLWithPath:[basePath stringByAppendingPathComponent:downloadTask.fileName]];
|
|
|
|
+
|
|
|
|
+ if (![fileManager fileExistsAtPath:basePath]) {
|
|
|
|
+ [fileManager createDirectoryAtPath:basePath withIntermediateDirectories:YES attributes:nil error:nil];
|
|
}
|
|
}
|
|
|
|
+ completionHandler(nil);
|
|
}
|
|
}
|
|
|
|
|
|
-- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
|
|
|
|
-{
|
|
|
|
- NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:_filePath];
|
|
|
|
- if (!fileHandle && _statusCode != 404) {
|
|
|
|
- // create file
|
|
|
|
- [[NSFileManager defaultManager] createFileAtPath:_filePath contents:nil attributes:nil];
|
|
|
|
- fileHandle = [NSFileHandle fileHandleForWritingAtPath:_filePath];
|
|
|
|
-
|
|
|
|
- if (!fileHandle) {
|
|
|
|
- APLog(@"file creation failed, no data was saved");
|
|
|
|
- if ([self.delegate respondsToSelector:@selector(downloadFailedWithErrorDescription:)])
|
|
|
|
- [self.delegate downloadFailedWithErrorDescription:NSLocalizedString(@"HTTP_FILE_CREATION_FAILED",nil)];
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
|
|
+- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
|
|
|
|
+ if ([self.delegate respondsToSelector:@selector(progressUpdatedTo:receivedDataSize:expectedDownloadSize:identifier:)]) {
|
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
+ [self.delegate progressUpdatedTo: (float)totalBytesWritten / (float)totalBytesExpectedToWrite receivedDataSize:bytesWritten expectedDownloadSize:totalBytesExpectedToWrite identifier:downloadTask.taskDescription];
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
|
|
- @try {
|
|
|
|
- [fileHandle seekToEndOfFile];
|
|
|
|
- [fileHandle writeData:data];
|
|
|
|
|
|
+- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
|
|
|
|
+{
|
|
|
|
+ VLCHTTPFileDownloaderTask *task = [self _downloadTaskWithIdentifier:downloadTask.taskDescription];
|
|
|
|
|
|
- _receivedDataSize = _receivedDataSize + [data length];
|
|
|
|
- if ([self.delegate respondsToSelector:@selector(progressUpdatedTo:receivedDataSize:expectedDownloadSize:)])
|
|
|
|
- [self.delegate progressUpdatedTo: (float)_receivedDataSize / (float)_expectedDownloadSize receivedDataSize:_receivedDataSize expectedDownloadSize:_expectedDownloadSize];
|
|
|
|
- }
|
|
|
|
- @catch (NSException * e) {
|
|
|
|
- APLog(@"exception when writing to file %@", _filePath);
|
|
|
|
|
|
+ NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
|
|
+ if (![fileManager fileExistsAtPath:[task.fileURL path]]) {
|
|
|
|
+ if (@available(iOS 10.3, *)) {
|
|
|
|
+ //The copy should be instant iOS 10.3+ with AFS
|
|
|
|
+ [fileManager copyItemAtURL:location toURL:task.fileURL error:nil];
|
|
|
|
+ } else {
|
|
|
|
+ [fileManager moveItemAtURL:location toURL:task.fileURL error:nil];
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
- [fileHandle closeFile];
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
|
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
|
|
@@ -196,55 +188,88 @@
|
|
if (error.code != -999) {
|
|
if (error.code != -999) {
|
|
if (error) {
|
|
if (error) {
|
|
APLog(@"http file download failed (%li)", (long)error.code);
|
|
APLog(@"http file download failed (%li)", (long)error.code);
|
|
- if ([self.delegate respondsToSelector:@selector(downloadFailedWithErrorDescription:)])
|
|
|
|
- [self.delegate downloadFailedWithErrorDescription:error.description];
|
|
|
|
|
|
+
|
|
|
|
+ if ([self.delegate respondsToSelector:@selector(downloadFailedWithIdentifier:errorDescription:)]) {
|
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
+ [self.delegate downloadFailedWithIdentifier:task.taskDescription errorDescription:error.description];
|
|
|
|
+ });
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
APLog(@"http file download complete");
|
|
APLog(@"http file download complete");
|
|
}
|
|
}
|
|
- [self _downloadEnded];
|
|
|
|
|
|
+ [self _downloadEndedWithIdentifier:task.taskDescription];
|
|
} else {
|
|
} else {
|
|
APLog(@"http file download canceled");
|
|
APLog(@"http file download canceled");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-- (void)cancelDownload
|
|
|
|
|
|
+- (void)cancelDownloadWithIdentifier:(NSString *)identifier
|
|
{
|
|
{
|
|
- [_sessionTask cancel];
|
|
|
|
|
|
+ VLCHTTPFileDownloaderTask *downloadTask = [self _downloadTaskWithIdentifier:identifier];
|
|
|
|
+ [downloadTask.sessionTask cancel];
|
|
/* remove partially downloaded content */
|
|
/* remove partially downloaded content */
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
- if ([fileManager fileExistsAtPath:_filePath])
|
|
|
|
- [fileManager removeItemAtPath:_filePath error:nil];
|
|
|
|
|
|
+ if ([fileManager fileExistsAtPath:downloadTask.fileURL.path])
|
|
|
|
+ [fileManager removeItemAtURL:downloadTask.fileURL error:nil];
|
|
|
|
|
|
- if ([self.delegate respondsToSelector:@selector(downloadFailedWithErrorDescription:)])
|
|
|
|
- [self.delegate downloadFailedWithErrorDescription:NSLocalizedString(@"HTTP_DOWNLOAD_CANCELLED",nil)];
|
|
|
|
|
|
+ if ([self.delegate respondsToSelector:@selector(downloadFailedWithIdentifier:errorDescription:)]) {
|
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
+ [self.delegate downloadFailedWithIdentifier:identifier errorDescription:NSLocalizedString(@"HTTP_DOWNLOAD_CANCELLED",nil)];
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
|
|
- [self _downloadEnded];
|
|
|
|
|
|
+ [self _downloadEndedWithIdentifier:identifier];
|
|
}
|
|
}
|
|
|
|
|
|
-- (void)_downloadEnded
|
|
|
|
|
|
+- (void)_downloadEndedWithIdentifier:(NSString *)identifier
|
|
{
|
|
{
|
|
- _downloadInProgress = NO;
|
|
|
|
|
|
+ VLCHTTPFileDownloaderTask *task = [self _downloadTaskWithIdentifier:identifier];
|
|
|
|
+
|
|
VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
|
|
VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
|
|
[activityManager networkActivityStopped];
|
|
[activityManager networkActivityStopped];
|
|
[activityManager activateIdleTimer];
|
|
[activityManager activateIdleTimer];
|
|
|
|
|
|
- NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
|
|
|
- NSString *libraryPath = searchPaths[0];
|
|
|
|
-
|
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
|
- NSString *finalFilePath = [libraryPath stringByAppendingPathComponent:_fileName];
|
|
|
|
-
|
|
|
|
- if ([fileManager fileExistsAtPath:_filePath]) {
|
|
|
|
- [fileManager moveItemAtPath:_filePath toPath:finalFilePath error:nil];
|
|
|
|
|
|
+ if ([fileManager fileExistsAtPath:[task.fileURL path]]) {
|
|
[[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
|
|
[[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
|
|
#if TARGET_OS_IOS
|
|
#if TARGET_OS_IOS
|
|
- // FIXME: Replace notifications by cleaner observers
|
|
|
|
- [[NSNotificationCenter defaultCenter] postNotificationName:NSNotification.VLCNewFileAddedNotification
|
|
|
|
- object:self];
|
|
|
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
+ // FIXME: Replace notifications by cleaner observers
|
|
|
|
+ [[NSNotificationCenter defaultCenter] postNotificationName:NSNotification.VLCNewFileAddedNotification
|
|
|
|
+ object:self];
|
|
|
|
+ });
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
- [self.delegate downloadEnded];
|
|
|
|
|
|
+ [self _removeDownloadWithIdentifier:identifier];
|
|
|
|
+
|
|
|
|
+ dispatch_async(dispatch_get_main_queue(), ^{
|
|
|
|
+ [self.delegate downloadEndedWithIdentifier:identifier];
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+- (void)_removeDownloadWithIdentifier:(NSString *)identifier
|
|
|
|
+{
|
|
|
|
+ dispatch_async(_downloadsAccessQueue, ^{
|
|
|
|
+ [self.downloads removeObjectForKey:identifier];
|
|
|
|
+ });
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+- (VLCHTTPFileDownloaderTask *)_downloadTaskWithIdentifier:(NSString *)identifier
|
|
|
|
+{
|
|
|
|
+ __block VLCHTTPFileDownloaderTask *task;
|
|
|
|
+ dispatch_sync(_downloadsAccessQueue, ^{
|
|
|
|
+ task = [self.downloads objectForKey:identifier];
|
|
|
|
+ });
|
|
|
|
+ return task;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+- (void)_addDownloadTask:(VLCHTTPFileDownloaderTask *)task identifier:(NSString *)identifier
|
|
|
|
+{
|
|
|
|
+ dispatch_async(_downloadsAccessQueue, ^{
|
|
|
|
+ [self.downloads setObject:task forKey:identifier];
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
@end
|
|
@end
|