Browse Source

more App Delegate cleanup

Felix Paul Kühne 10 years ago
parent
commit
8bb0d9b0dc

+ 26 - 0
Sources/VLCActivityManager.h

@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * VLCActivityManager.h
+ * VLC for iOS
+ *****************************************************************************
+ * Copyright (c) 2015 VideoLAN. All rights reserved.
+ * $Id$
+ *
+ * Authors: Felix Paul Kühne <fkuehne # videolan.org>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
+
+#import <Foundation/Foundation.h>
+
+@interface VLCActivityManager : NSObject
+
++ (instancetype)defaultManager;
+
+- (void)activateIdleTimer;
+- (void)disableIdleTimer;
+
+- (void)networkActivityStarted;
+- (BOOL)haveNetworkActivity;
+- (void)networkActivityStopped;
+
+@end

+ 69 - 0
Sources/VLCActivityManager.m

@@ -0,0 +1,69 @@
+/*****************************************************************************
+ * VLCActivityManager.m
+ * VLC for iOS
+ *****************************************************************************
+ * Copyright (c) 2015 VideoLAN. All rights reserved.
+ * $Id$
+ *
+ * Authors: Felix Paul Kühne <fkuehne # videolan.org>
+ *
+ * Refer to the COPYING file of the official project for license.
+ *****************************************************************************/
+
+#import "VLCActivityManager.h"
+
+@interface VLCActivityManager ()
+{
+    int _idleCounter;
+    int _networkActivityCounter;
+}
+@end
+
+@implementation VLCActivityManager
+
++ (instancetype)defaultManager
+{
+    static VLCActivityManager *sharedInstance = nil;
+    static dispatch_once_t pred;
+
+    dispatch_once(&pred, ^{
+        sharedInstance = [VLCActivityManager new];
+    });
+
+    return sharedInstance;
+}
+
+- (void)activateIdleTimer
+{
+    _idleCounter--;
+    if (_idleCounter < 1)
+        [UIApplication sharedApplication].idleTimerDisabled = NO;
+}
+
+- (void)disableIdleTimer
+{
+    _idleCounter++;
+    if ([UIApplication sharedApplication].idleTimerDisabled == NO)
+        [UIApplication sharedApplication].idleTimerDisabled = YES;
+}
+
+- (void)networkActivityStarted
+{
+    _networkActivityCounter++;
+    if ([UIApplication sharedApplication].networkActivityIndicatorVisible == NO)
+        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
+}
+
+- (BOOL)haveNetworkActivity
+{
+    return _networkActivityCounter >= 1;
+}
+
+- (void)networkActivityStopped
+{
+    _networkActivityCounter--;
+    if (_networkActivityCounter < 1)
+        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
+}
+
+@end

+ 0 - 10
Sources/VLCAppDelegate.h

@@ -24,16 +24,6 @@ extern NSString *const VLCDropboxSessionWasAuthorized;
 
 @interface VLCAppDelegate : UIResponder <UIApplicationDelegate>
 
-- (void)updateMediaList;
-- (void)disableIdleTimer;
-- (void)activateIdleTimer;
-
-- (void)networkActivityStarted;
-- (BOOL)haveNetworkActivity;
-- (void)networkActivityStopped;
-
-- (void)cleanCache;
-
 @property (nonatomic, readonly) VLCPlaylistViewController *playlistViewController;
 
 @property (nonatomic, readonly) VLCPlayerDisplayController *playerDisplayController;

+ 7 - 113
Sources/VLCAppDelegate.m

@@ -34,6 +34,7 @@
 #import <HockeySDK/HockeySDK.h>
 #import "VLCSidebarController.h"
 #import "VLCKeychainCoordinator.h"
+#import "VLCActivityManager.h"
 
 NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorized";
 
@@ -41,8 +42,6 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
 
 @interface VLCAppDelegate () <VLCMediaFileDiscovererDelegate>
 {
-    int _idleCounter;
-    int _networkActivityCounter;
     BOOL _passcodeValidated;
     BOOL _isRunningMigration;
     BOOL _isComingFromHandoff;
@@ -115,13 +114,8 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
 
     [[UISwitch appearance] setOnTintColor:[UIColor VLCOrangeTintColor]];
 
-    /* clean caches on launch (since those are used for wifi upload only) */
-    [self cleanCache];
-
-    [VLCLibrary sharedLibrary];
-
-    // Init the HTTP Server
-    [VLCHTTPUploaderController sharedInstance];
+    // Init the HTTP Server and clean its cache
+    [[VLCHTTPUploaderController sharedInstance] cleanCache];
 
     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
     // enable crash preventer
@@ -143,7 +137,7 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
 
         VLCMediaFileDiscoverer *discoverer = [VLCMediaFileDiscoverer sharedInstance];
         [discoverer addObserver:self];
-        [discoverer startDiscovering:[self directoryPath]];
+        [discoverer startDiscovering];
     };
 
     NSError *error = nil;
@@ -158,7 +152,7 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
             setupBlock();
             _isRunningMigration = NO;
             [[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
-            [self updateMediaList];
+            [[VLCMediaFileDiscoverer sharedInstance] updateMediaList];
         };
 
         self.window.rootViewController = migrationController;
@@ -252,7 +246,7 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
             if (theError.code != noErr)
                 APLog(@"saving the file failed (%li): %@", (long)theError.code, theError.localizedDescription);
 
-            [self updateMediaList];
+            [[VLCMediaFileDiscoverer sharedInstance] updateMediaList];
         } else if ([url.scheme isEqualToString:@"vlc-x-callback"] || [url.host isEqualToString:@"x-callback-url"]) {
             // URL confirmes to the x-callback-url specification
             // vlc-x-callback://x-callback-url/action?param=value&x-success=callback
@@ -346,7 +340,7 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
 {
     if (!_isRunningMigration && !_isComingFromHandoff) {
         [[MLMediaLibrary sharedMediaLibrary] updateMediaDatabase];
-        [self updateMediaList];
+        [[VLCMediaFileDiscoverer sharedInstance] updateMediaList];
     } else if(_isComingFromHandoff) {
         _isComingFromHandoff = NO;
     }
@@ -382,72 +376,6 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
     [_playlistViewController updateViewContents];
 }
 
-- (void)cleanCache
-{
-    if ([self haveNetworkActivity])
-        return;
-
-    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-    NSString* uploadDirPath = [searchPaths[0] stringByAppendingPathComponent:@"Upload"];
-    NSFileManager *fileManager = [NSFileManager defaultManager];
-    if ([fileManager fileExistsAtPath:uploadDirPath])
-        [fileManager removeItemAtPath:uploadDirPath error:nil];
-}
-
-#pragma mark - media list methods
-
-- (NSString *)directoryPath
-{
-    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
-    NSString *directoryPath = searchPaths[0];
-    return directoryPath;
-}
-
-- (void)updateMediaList
-{
-    NSString *directoryPath = [self directoryPath];
-    NSMutableArray *foundFiles = [NSMutableArray arrayWithArray:[[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:nil]];
-    NSMutableArray *filePaths = [NSMutableArray array];
-    NSURL *fileURL;
-    while (foundFiles.count) {
-        NSString *fileName = foundFiles.firstObject;
-        NSString *filePath = [directoryPath stringByAppendingPathComponent:fileName];
-        [foundFiles removeObject:fileName];
-
-        if ([fileName isSupportedMediaFormat] || [fileName isSupportedAudioMediaFormat]) {
-            [filePaths addObject:filePath];
-
-            /* exclude media files from backup (QA1719) */
-            fileURL = [NSURL fileURLWithPath:filePath];
-            [fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
-        } else {
-            BOOL isDirectory = NO;
-            BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory];
-
-            // add folders
-            if (exists && isDirectory) {
-                NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:filePath error:nil];
-                for (NSString* file in files) {
-                    NSString *fullFilePath = [directoryPath stringByAppendingPathComponent:file];
-                    isDirectory = NO;
-                    exists = [[NSFileManager defaultManager] fileExistsAtPath:fullFilePath isDirectory:&isDirectory];
-                    //only add folders or files in folders
-                    if ((exists && isDirectory) || ![filePath.lastPathComponent isEqualToString:@"Documents"]) {
-                        NSString *folderpath = [filePath stringByReplacingOccurrencesOfString:directoryPath withString:@""];
-                        if (![folderpath isEqualToString:@""]) {
-                            folderpath = [folderpath stringByAppendingString:@"/"];
-                        }
-                        NSString *path = [folderpath stringByAppendingString:file];
-                        [foundFiles addObject:path];
-                    }
-                }
-            }
-        }
-    }
-    [[MLMediaLibrary sharedMediaLibrary] addFilePaths:filePaths];
-    [_playlistViewController updateViewContents];
-}
-
 #pragma mark - pass code validation
 
 - (void)passcodeWasValidated:(NSNotification *)aNotifcation
@@ -471,40 +399,6 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
         _passcodeValidated = YES;
 }
 
-#pragma mark - idle timer preventer
-- (void)disableIdleTimer
-{
-    _idleCounter++;
-    if ([UIApplication sharedApplication].idleTimerDisabled == NO)
-        [UIApplication sharedApplication].idleTimerDisabled = YES;
-}
-
-- (void)activateIdleTimer
-{
-    _idleCounter--;
-    if (_idleCounter < 1)
-        [UIApplication sharedApplication].idleTimerDisabled = NO;
-}
-
-- (void)networkActivityStarted
-{
-    _networkActivityCounter++;
-    if ([UIApplication sharedApplication].networkActivityIndicatorVisible == NO)
-        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
-}
-
-- (BOOL)haveNetworkActivity
-{
-    return _networkActivityCounter >= 1;
-}
-
-- (void)networkActivityStopped
-{
-    _networkActivityCounter--;
-    if (_networkActivityCounter < 1)
-        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
-}
-
 #pragma mark - download handling
 
 - (void)downloadMovieFromURL:(NSURL *)url

+ 2 - 3
Sources/VLCBoxController.m

@@ -13,7 +13,7 @@
 #import "VLCBoxController.h"
 #import "NSString+SupportedMedia.h"
 #import "VLCPlaybackController.h"
-#import "VLCAppDelegate.h"
+#import "VLCMediaFileDiscoverer.h"
 #import <SSKeychain/SSKeychain.h>
 
 @interface VLCBoxController () <NSURLConnectionDataDelegate>
@@ -306,8 +306,7 @@
 {
     /* update library now that we got a file */
     APLog(@"BoxFile download was successful");
-    VLCAppDelegate *appDelegate = (VLCAppDelegate *) [UIApplication sharedApplication].delegate;
-    [appDelegate performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+    [[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
 
     if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
         [self.delegate operationWithProgressInformationStopped];

+ 4 - 5
Sources/VLCDocumentPickerController.m

@@ -12,7 +12,7 @@
 
 #import "VLCDocumentPickerController.h"
 #import <MobileCoreServices/MobileCoreServices.h>
-#import "VLCAppDelegate.h"
+#import "VLCMediaFileDiscoverer.h"
 #import "VLCPlaylistViewController.h"
 
 @interface VLCDocumentPickerController () <UIDocumentMenuDelegate, UIDocumentPickerDelegate>
@@ -74,11 +74,10 @@
 
     if (![fileManager fileExistsAtPath:filePath]) {
         NSError *error = nil;
-        BOOL succes = [fileManager moveItemAtPath:[url path] toPath:filePath error:&error];
+        BOOL success = [fileManager moveItemAtPath:[url path] toPath:filePath error:&error];
 
-        if (succes) {
-            VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-            [appDelegate updateMediaList];
+        if (success) {
+            [[VLCMediaFileDiscoverer sharedInstance] updateMediaList];
         }
     }
 }

+ 7 - 5
Sources/VLCDownloadViewController.m

@@ -14,7 +14,7 @@
 
 #import "VLCDownloadViewController.h"
 #import "VLCHTTPFileDownloader.h"
-#import "VLCAppDelegate.h"
+#import "VLCActivityManager.h"
 #import "WhiteRaccoon.h"
 #import "NSString+SupportedMedia.h"
 #import "VLCHTTPFileDownloader.h"
@@ -241,9 +241,11 @@
 - (void)downloadStarted
 {
     [self.activityIndicator stopAnimating];
-    VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-    [appDelegate networkActivityStopped];
-    [appDelegate networkActivityStarted];
+
+    VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
+    [activityManager networkActivityStopped];
+    [activityManager networkActivityStarted];
+
     self.currentDownloadLabel.text = _humanReadableFilename;
     self.progressView.progress = 0.;
     [self.progressPercent setText:@"0%%"];
@@ -257,7 +259,7 @@
 
 - (void)downloadEnded
 {
-    [(VLCAppDelegate*)[UIApplication sharedApplication].delegate networkActivityStopped];
+    [[VLCActivityManager defaultManager] networkActivityStopped];
     _currentDownloadType = 0;
     APLog(@"download ended");
     self.progressContainer.hidden = YES;

+ 9 - 7
Sources/VLCDropboxController.m

@@ -14,7 +14,8 @@
 #import "VLCDropboxController.h"
 #import "NSString+SupportedMedia.h"
 #import "VLCPlaybackController.h"
-#import "VLCAppDelegate.h"
+#import "VLCActivityManager.h"
+#import "VLCMediaFileDiscoverer.h"
 
 @interface VLCDropboxController ()
 {
@@ -163,8 +164,7 @@
 - (void)restClient:(DBRestClient*)client loadedFile:(NSString*)localPath
 {
     /* update library now that we got a file */
-    VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-    [appDelegate performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+    [[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
 
     if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
         [self.delegate operationWithProgressInformationStopped];
@@ -218,8 +218,9 @@
 {
     _outstandingNetworkRequests++;
     if (_outstandingNetworkRequests == 1) {
-        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate networkActivityStarted];
-        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate disableIdleTimer];
+        VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
+        [activityManager networkActivityStarted];
+        [activityManager disableIdleTimer];
     }
 }
 
@@ -227,8 +228,9 @@
 {
     _outstandingNetworkRequests--;
     if (_outstandingNetworkRequests == 0) {
-        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate networkActivityStopped];
-        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate activateIdleTimer];
+        VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
+        [activityManager networkActivityStopped];
+        [activityManager activateIdleTimer];
     }
 }
 

+ 4 - 3
Sources/VLCFTPServerListViewController.m

@@ -13,11 +13,12 @@
 
 #import "VLCFTPServerListViewController.h"
 #import "VLCNetworkListCell.h"
-#import "VLCAppDelegate.h"
+#import "VLCActivityManager.h"
 #import "NSString+SupportedMedia.h"
 #import "UIDevice+VLC.h"
 #import "VLCStatusLabel.h"
 #import "VLCPlaybackController.h"
+#import "VLCDownloadViewController.h"
 
 #import "WhiteRaccoon.h"
 
@@ -78,7 +79,7 @@
     _FTPListDirRequest.path = _ftpServerPath;
     _FTPListDirRequest.passive = YES;
 
-    [(VLCAppDelegate*)[UIApplication sharedApplication].delegate networkActivityStarted];
+    [[VLCActivityManager defaultManager] networkActivityStarted];
     [_FTPListDirRequest start];
 }
 
@@ -219,7 +220,7 @@
     [super tableView:tableView willDisplayCell:cell forRowAtIndexPath:indexPath];
 
     if([indexPath row] == ((NSIndexPath*)[[tableView indexPathsForVisibleRows] lastObject]).row)
-        [(VLCAppDelegate*)[UIApplication sharedApplication].delegate networkActivityStopped];
+        [[VLCActivityManager defaultManager] networkActivityStopped];
 }
 
 

+ 2 - 3
Sources/VLCGoogleDriveController.m

@@ -14,7 +14,7 @@
 #import "VLCGoogleDriveController.h"
 #import "NSString+SupportedMedia.h"
 #import "VLCPlaybackController.h"
-#import "VLCAppDelegate.h"
+#import "VLCMediaFileDiscoverer.h"
 
 @interface VLCGoogleDriveController ()
 {
@@ -293,8 +293,7 @@
 {
     /* update library now that we got a file */
     APLog(@"DriveFile download was successful");
-    VLCAppDelegate *appDelegate = (VLCAppDelegate *) [UIApplication sharedApplication].delegate;
-    [appDelegate performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+    [[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
 
     if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
         [self.delegate operationWithProgressInformationStopped];

+ 5 - 4
Sources/VLCHTTPConnection.m

@@ -13,7 +13,7 @@
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
 
-#import "VLCAppDelegate.h"
+#import "VLCActivityManager.h"
 #import "VLCHTTPConnection.h"
 #import "MultipartFormDataParser.h"
 #import "HTTPMessage.h"
@@ -440,9 +440,10 @@
         APLog(@"Could not create file at path: %@", _filepath);
 
     _storeFile = [NSFileHandle fileHandleForWritingAtPath:_filepath];
-    VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-    [appDelegate networkActivityStarted];
-    [appDelegate disableIdleTimer];
+
+    VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
+    [activityManager networkActivityStarted];
+    [activityManager disableIdleTimer];
 }
 
 - (void)notifyUserAboutEndOfFreeStorage:(NSString *)filename

+ 9 - 8
Sources/VLCHTTPFileDownloader.m

@@ -13,8 +13,9 @@
 
 #import "VLCHTTPFileDownloader.h"
 #import "NSString+SupportedMedia.h"
-#import "VLCAppDelegate.h"
+#import "VLCActivityManager.h"
 #import "UIDevice+VLC.h"
+#import "VLCMediaFileDiscoverer.h"
 
 @interface VLCHTTPFileDownloader ()
 {
@@ -63,9 +64,9 @@
         _downloadInProgress = NO;
     } else {
         _downloadInProgress = YES;
-        VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-        [appDelegate networkActivityStarted];
-        [appDelegate disableIdleTimer];
+        VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
+        [activityManager networkActivityStarted];
+        [activityManager disableIdleTimer];
     }
 }
 
@@ -199,9 +200,9 @@
 - (void)_downloadEnded
 {
     _downloadInProgress = NO;
-    VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-    [appDelegate networkActivityStopped];
-    [appDelegate activateIdleTimer];
+    VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
+    [activityManager networkActivityStopped];
+    [activityManager activateIdleTimer];
 
     NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
     NSString *libraryPath = searchPaths[0];
@@ -211,7 +212,7 @@
 
     if ([fileManager fileExistsAtPath:_filePath]) {
         [fileManager moveItemAtPath:_filePath toPath:finalFilePath error:nil];
-        [appDelegate performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+        [[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
     }
 
     [self.delegate downloadEnded];

+ 1 - 0
Sources/VLCHTTPUploaderController.h

@@ -27,5 +27,6 @@
 - (NSString *)hostname;
 
 - (void)moveFileFrom:(NSString *)filepath;
+- (void)cleanCache;
 
 @end

+ 19 - 7
Sources/VLCHTTPUploaderController.m

@@ -13,10 +13,10 @@
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
 
-#import "VLCAppDelegate.h"
 #import "VLCHTTPUploaderController.h"
 #import "VLCHTTPConnection.h"
-
+#import "VLCActivityManager.h"
+#import "VLCMediaFileDiscoverer.h"
 #import "HTTPServer.h"
 
 #import <ifaddrs.h>
@@ -88,7 +88,7 @@
         return true;
     }
     // clean cache before accepting new stuff
-    [(VLCAppDelegate *)[UIApplication sharedApplication].delegate cleanCache];
+    [self cleanCache];
 
     // Initialize our http server
     _httpServer = [[HTTPServer alloc] init];
@@ -206,10 +206,22 @@
     }
 
     /* update media library when file upload was completed */
-    VLCAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
-    [appDelegate networkActivityStopped];
-    [appDelegate activateIdleTimer];
-    [appDelegate performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+    VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
+    [activityManager networkActivityStopped];
+    [activityManager activateIdleTimer];
+    [[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+}
+
+- (void)cleanCache
+{
+    if ([[VLCActivityManager defaultManager] haveNetworkActivity])
+        return;
+
+    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+    NSString* uploadDirPath = [searchPaths[0] stringByAppendingPathComponent:@"Upload"];
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    if ([fileManager fileExistsAtPath:uploadDirPath])
+        [fileManager removeItemAtPath:uploadDirPath error:nil];
 }
 
 @end

+ 0 - 1
Sources/VLCKeychainCoordinator.m

@@ -41,7 +41,6 @@ NSString *const VLCPasscode = @"org.videolan.vlc-ios.passcode";
     return sharedInstance;
 }
 
-
 - (NSString *)_obtainPasscode
 {
     NSString *passcode = [SSKeychain passwordForService:VLCPasscode account:VLCPasscode];

+ 3 - 1
Sources/VLCMediaFileDiscoverer.h

@@ -28,9 +28,11 @@
 - (void)addObserver:(id<VLCMediaFileDiscovererDelegate>)delegate;
 - (void)removeObserver:(id<VLCMediaFileDiscovererDelegate>)delegate;
 
-- (void)startDiscovering:(NSString *)directoryPath;
+- (void)startDiscovering;
 - (void)stopDiscovering;
 
+- (void)updateMediaList;
+
 + (instancetype)sharedInstance;
 
 @end

+ 58 - 4
Sources/VLCMediaFileDiscoverer.m

@@ -12,6 +12,8 @@
 
 #import "VLCMediaFileDiscoverer.h"
 #import "NSString+SupportedMedia.h"
+#import "VLCAppDelegate.h"
+#import "VLCPlaylistViewController.h"
 
 const float MediaTimerInterval = 2.f;
 
@@ -92,12 +94,12 @@ const float MediaTimerInterval = 2.f;
 
 #pragma mark - discovering
 
-- (void)startDiscovering:(NSString *)directoryPath
+- (void)startDiscovering
 {
-    _directoryPath = directoryPath;
-     _directoryFiles = [self directoryFiles];
+    _directoryPath = [self directoryPath];
+    _directoryFiles = [self directoryFiles];
 
-    int const folderDescriptor = open([directoryPath fileSystemRepresentation], O_EVTONLY);
+    int const folderDescriptor = open([_directoryPath fileSystemRepresentation], O_EVTONLY);
     _directorySource = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE, folderDescriptor,
                                               DISPATCH_VNODE_WRITE, DISPATCH_TARGET_QUEUE_DEFAULT);
 
@@ -246,4 +248,56 @@ const float MediaTimerInterval = 2.f;
     _addMediaTimer = nil;
 }
 
+#pragma mark - media list management
+
+- (void)updateMediaList
+{
+    if (![NSThread isMainThread]) {
+        [self performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+        return;
+    }
+
+    NSString *directoryPath = [self directoryPath];
+    NSMutableArray *foundFiles = [NSMutableArray arrayWithArray:[[NSFileManager defaultManager] contentsOfDirectoryAtPath:directoryPath error:nil]];
+    NSMutableArray *filePaths = [NSMutableArray array];
+    NSURL *fileURL;
+    while (foundFiles.count) {
+        NSString *fileName = foundFiles.firstObject;
+        NSString *filePath = [directoryPath stringByAppendingPathComponent:fileName];
+        [foundFiles removeObject:fileName];
+
+        if ([fileName isSupportedMediaFormat] || [fileName isSupportedAudioMediaFormat]) {
+            [filePaths addObject:filePath];
+
+            /* exclude media files from backup (QA1719) */
+            fileURL = [NSURL fileURLWithPath:filePath];
+            [fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
+        } else {
+            BOOL isDirectory = NO;
+            BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&isDirectory];
+
+            // add folders
+            if (exists && isDirectory) {
+                NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:filePath error:nil];
+                for (NSString* file in files) {
+                    NSString *fullFilePath = [directoryPath stringByAppendingPathComponent:file];
+                    isDirectory = NO;
+                    exists = [[NSFileManager defaultManager] fileExistsAtPath:fullFilePath isDirectory:&isDirectory];
+                    //only add folders or files in folders
+                    if ((exists && isDirectory) || ![filePath.lastPathComponent isEqualToString:@"Documents"]) {
+                        NSString *folderpath = [filePath stringByReplacingOccurrencesOfString:directoryPath withString:@""];
+                        if (![folderpath isEqualToString:@""]) {
+                            folderpath = [folderpath stringByAppendingString:@"/"];
+                        }
+                        NSString *path = [folderpath stringByAppendingString:file];
+                        [foundFiles addObject:path];
+                    }
+                }
+            }
+        }
+    }
+    [[MLMediaLibrary sharedMediaLibrary] addFilePaths:filePaths];
+    [[(VLCAppDelegate *)[UIApplication sharedApplication].delegate playlistViewController] updateViewContents];
+}
+
 @end

+ 9 - 3
VLC for iOS.xcodeproj/project.pbxproj

@@ -80,6 +80,7 @@
 		7D15168B194773630086FB8C /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D15168A194773630086FB8C /* MobileCoreServices.framework */; };
 		7D168F7118D4A21B003FAF59 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7D168F7018D4A21B003FAF59 /* Accelerate.framework */; };
 		7D168F7418D4A33F003FAF59 /* UIImage+Blur.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D168F7318D4A33F003FAF59 /* UIImage+Blur.m */; };
+		7D18F0A21B34522000651A30 /* VLCActivityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 7D18F0A11B34522000651A30 /* VLCActivityManager.m */; };
 		7D27EB9419DEE11900EF0370 /* Launch Screen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D27EB9319DEE11900EF0370 /* Launch Screen.xib */; };
 		7D27EC2B19DF310300EF0370 /* VLCFirstStepsSecondPageViewController~ipad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D27EC2919DF310300EF0370 /* VLCFirstStepsSecondPageViewController~ipad.xib */; };
 		7D27EC2C19DF310300EF0370 /* VLCFirstStepsSecondPageViewController~iphone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7D27EC2A19DF310300EF0370 /* VLCFirstStepsSecondPageViewController~iphone.xib */; };
@@ -413,6 +414,8 @@
 		7D168F7018D4A21B003FAF59 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; };
 		7D168F7218D4A317003FAF59 /* UIImage+Blur.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Blur.h"; path = "Sources/UIImage+Blur.h"; sourceTree = SOURCE_ROOT; };
 		7D168F7318D4A33F003FAF59 /* UIImage+Blur.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Blur.m"; path = "Sources/UIImage+Blur.m"; sourceTree = SOURCE_ROOT; };
+		7D18F0A01B34522000651A30 /* VLCActivityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VLCActivityManager.h; path = Sources/VLCActivityManager.h; sourceTree = SOURCE_ROOT; };
+		7D18F0A11B34522000651A30 /* VLCActivityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VLCActivityManager.m; path = Sources/VLCActivityManager.m; sourceTree = SOURCE_ROOT; };
 		7D19492B17C661A300959800 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = "<group>"; };
 		7D1AB27C179C98BF004CC271 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = "<group>"; };
 		7D1AB281179C98CD004CC271 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -1292,7 +1295,7 @@
 				7D6B08BB174A72A900A05173 /* VLCConstants.h */,
 				7DBBF180183AB3B80009A339 /* VLCAppDelegate.h */,
 				7DBBF181183AB3B80009A339 /* VLCAppDelegate.m */,
-				7DBB788E1B305D8300894467 /* Keychain */,
+				7DBB788E1B305D8300894467 /* Keychain & random singletons */,
 				A7D03A4817A4249F0022C16F /* MediaDiscovering */,
 				7D2339AB176DE70E008D223C /* Menu */,
 				7D5F7ABA175265CB006CCCFA /* HTTP Connectivity */,
@@ -1379,13 +1382,15 @@
 			name = "Server browsing";
 			sourceTree = "<group>";
 		};
-		7DBB788E1B305D8300894467 /* Keychain */ = {
+		7DBB788E1B305D8300894467 /* Keychain & random singletons */ = {
 			isa = PBXGroup;
 			children = (
 				7DBB78881B30423B00894467 /* VLCKeychainCoordinator.h */,
 				7DBB78891B30423B00894467 /* VLCKeychainCoordinator.m */,
+				7D18F0A01B34522000651A30 /* VLCActivityManager.h */,
+				7D18F0A11B34522000651A30 /* VLCActivityManager.m */,
 			);
-			name = Keychain;
+			name = "Keychain & random singletons";
 			sourceTree = "<group>";
 		};
 		7DC19AEB1868C91400810BF7 /* First Steps */ = {
@@ -1992,6 +1997,7 @@
 				493B1A1D195D06B1000A491A /* BasicUPnPDevice+VLC.m in Sources */,
 				265D511D1922746C00E38383 /* VLCPlexParser.m in Sources */,
 				2640FAE61B01477A00E359D6 /* VLCPlexWebAPI.m in Sources */,
+				7D18F0A21B34522000651A30 /* VLCActivityManager.m in Sources */,
 				7DB847D71A5871570002DC30 /* VLCOneDriveObject.m in Sources */,
 				7DAE0C2E1B2EDF7A00C53996 /* VLCNetworkListViewController.m in Sources */,
 				7D1052E91A4DCC1100295F08 /* VLCOneDriveTableViewController.m in Sources */,