Ver código fonte

This is a migration of the Dropbox API v1 to v2.
For now It uses temporarily a fork of the official library to bypass the podspec for iOS 7.0.
When the support of iOS 7.0 is dropped, the can be modify to use the official library.

Soomin Lee 8 anos atrás
pai
commit
2e32c4d968

+ 5 - 7
Podfile

@@ -19,11 +19,10 @@ pod 'GoogleAPIClient/Drive'
 pod 'VLC-LXReorderableCollectionViewFlowLayout', '0.1.3v'
 pod 'VLC-WhiteRaccoon'
 pod 'VLC-LiveSDK', '5.7.0x'
-pod 'VLC-Dropbox-v1-SDK', '1.3.14w'
 pod 'MediaLibraryKit-unstable'
 pod 'MobileVLCKit-unstable', '3.0.0a31'
 pod 'GTMAppAuth'
-
+pod 'ObjectiveDropboxOfficial', :git => 'git@github.com:TheHungryBu/dropbox-sdk-obj-c.git' #update ios platform version
 end
 
 target 'VLC-iOS-no-watch' do
@@ -41,11 +40,10 @@ pod 'GoogleAPIClient/Drive'
 pod 'VLC-LXReorderableCollectionViewFlowLayout', '0.1.3v'
 pod 'VLC-WhiteRaccoon'
 pod 'VLC-LiveSDK', '5.7.0x'
-pod 'VLC-Dropbox-v1-SDK', '1.3.14w'
 pod 'MediaLibraryKit-unstable'
 pod 'MobileVLCKit-unstable', '3.0.0a31'
+pod 'ObjectiveDropboxOfficial', :git => 'git@github.com:TheHungryBu/dropbox-sdk-obj-c.git' #update ios platform version
 pod 'GTMAppAuth'
-
 end
 
 target 'VLC-iOS-no-watch-Debug' do
@@ -63,7 +61,7 @@ pod 'GoogleAPIClient/Drive'
 pod 'VLC-LXReorderableCollectionViewFlowLayout', '0.1.3v'
 pod 'VLC-WhiteRaccoon'
 pod 'VLC-LiveSDK', '5.7.0x'
-pod 'VLC-Dropbox-v1-SDK', '1.3.14w'
+pod 'ObjectiveDropboxOfficial', :git => 'git@github.com:TheHungryBu/dropbox-sdk-obj-c.git' #update ios platform version
 
 end
 
@@ -78,7 +76,7 @@ pod "OROpenSubtitleDownloader", :git => 'https://github.com/orta/OROpenSubtitleD
 pod 'GRKArrayDiff', '~> 2.1'
 pod 'VLC-WhiteRaccoon'
 pod 'VLC-LiveSDK', '5.7.0x'
-pod 'VLC-Dropbox-v1-SDK', '1.3.14w'
+pod 'ObjectiveDropboxOfficial', :git => 'git@github.com:TheHungryBu/dropbox-sdk-obj-c.git' #update ios platform version
 pod 'HockeySDK-tvOS', '4.1.0-beta.1'
 pod 'TVVLCKit-unstable', '3.0.0a31'
 
@@ -95,7 +93,7 @@ pod "OROpenSubtitleDownloader", :git => 'https://github.com/orta/OROpenSubtitleD
 pod 'GRKArrayDiff', '~> 2.1'
 pod 'VLC-WhiteRaccoon'
 pod 'VLC-LiveSDK', '5.7.0x'
-pod 'VLC-Dropbox-v1-SDK', '1.3.14w'
+pod 'ObjectiveDropboxOfficial', :git => 'git@github.com:TheHungryBu/dropbox-sdk-obj-c.git' #update ios platform version
 pod 'HockeySDK-tvOS', '4.1.0-beta.1'
 
 end

+ 3 - 4
SharedSources/Clouds/VLCDropboxCollectionViewController.m

@@ -12,14 +12,13 @@
 #import "VLCDropboxCollectionViewController.h"
 #import "VLCDropboxController.h"
 #import "UIDevice+VLC.h"
-#import <DropboxTVSDK/DBKeychain.h>
 #import "VLCRemoteBrowsingTVCell.h"
 #import "VLCRemoteBrowsingTVCell+CloudStorage.h"
 
 @interface VLCDropboxCollectionViewController () <VLCCloudStorageDelegate>
 {
     VLCDropboxController *_dropboxController;
-    DBMetadata *_selectedFile;
+    DBFILESMetadata *_selectedFile;
     NSArray *_mediaList;
 }
 @end
@@ -79,11 +78,11 @@
 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
 {
     _selectedFile = _mediaList[indexPath.row];
-    if (!_selectedFile.isDirectory)
+    if (![_selectedFile isKindOfClass:[DBFILESFolderMetadata class]])
         [_dropboxController streamFile:_selectedFile currentNavigationController:self.navigationController];
     else {
         /* dive into subdirectory */
-        NSString *futurePath = [self.currentPath stringByAppendingFormat:@"/%@", _selectedFile.filename];
+        NSString *futurePath = [self.currentPath stringByAppendingFormat:@"/%@", _selectedFile.name];
         [_dropboxController reset];
         VLCDropboxCollectionViewController *targetViewController = [[VLCDropboxCollectionViewController alloc] initWithNibName:@"VLCRemoteBrowsingCollectionViewController" bundle:nil];
         targetViewController.currentPath = futurePath;

+ 1 - 0
Sources/VLC for iOS-Info.plist

@@ -252,6 +252,7 @@
 	<key>LSApplicationQueriesSchemes</key>
 	<array>
 		<string>dbapi-2</string>
+		<string>dbapi-8-emm</string>
 	</array>
 	<key>LSRequiresIPhoneOS</key>
 	<true/>

+ 11 - 4
Sources/VLCAppDelegate.m

@@ -29,12 +29,13 @@
 #import "VLCPlaybackController+MediaLibrary.h"
 #import "VLCPlayerDisplayController.h"
 #import <MediaPlayer/MediaPlayer.h>
-#import <DropboxSDK/DropboxSDK.h>
 #import <HockeySDK/HockeySDK.h>
 #import "VLCSidebarController.h"
 #import "VLCKeychainCoordinator.h"
 #import "VLCActivityManager.h"
 #import "GTScrollNavigationBar.h"
+#import "VLCDropboxConstants.h"
+#import <ObjectiveDropboxOfficial/ObjectiveDropboxOfficial.h>
 
 NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorized";
 
@@ -101,6 +102,9 @@ NSString *const VLCDropboxSessionWasAuthorized = @"VLCDropboxSessionWasAuthorize
                                 liveIdentifier:@"c95f4227dff96c61f8b3a46a25edc584"
                                       delegate:nil];
 
+    // Configure Dropbox
+    [DBClientsManager setupWithAppKey:kVLCDropboxAppKey];
+
     // Configure the SDK in here only!
     [hockeyManager startManager];
     [hockeyManager.authenticator authenticateInstallation];
@@ -292,9 +296,12 @@ didFailToContinueUserActivityWithType:(NSString *)userActivityType
   sourceApplication:(NSString *)sourceApplication
          annotation:(id)annotation
 {
-    if ([[DBSession sharedSession] handleOpenURL:url]) {
-        [[NSNotificationCenter defaultCenter] postNotificationName:VLCDropboxSessionWasAuthorized object:nil];
-        return YES;
+    //Handles Dropbox Authorization flow.
+    DBOAuthResult *authResult = [DBClientsManager handleRedirectURL:url];
+    if (authResult != nil) {
+        if ([authResult isSuccess]) {
+            return YES;
+        }
     }
 
     //Handles Google Authorization flow.

+ 0 - 1
Sources/VLCCloudServicesTableViewController.m

@@ -21,7 +21,6 @@
 #import "VLCDocumentPickerController.h"
 #import "VLCCloudServiceCell.h"
 
-#import <DropboxSDK/DropboxSDK.h>
 #import <BoxSDK/BoxSDK.h>
 #import "VLCGoogleDriveController.h"
 

+ 1 - 1
Sources/VLCCloudStorageTableViewCell.h

@@ -30,7 +30,7 @@
 @property (nonatomic, strong) IBOutlet VLCNetworkImageView *thumbnailView;
 @property (nonatomic, strong) IBOutlet UIButton *downloadButton;
 
-@property (nonatomic, retain) DBMetadata *dropboxFile;
+@property (nonatomic, retain) DBFILESMetadata *dropboxFile;
 @property (nonatomic, retain) VLCOneDriveObject *oneDriveFile;
 @property (nonatomic, retain) BoxItem *boxFile;
 #if TARGET_OS_IOS

+ 10 - 20
Sources/VLCCloudStorageTableViewCell.m

@@ -30,7 +30,7 @@
     return cell;
 }
 
-- (void)setDropboxFile:(DBMetadata *)dropboxFile
+- (void)setDropboxFile:(DBFILESMetadata *)dropboxFile
 {
     if (dropboxFile != _dropboxFile)
         _dropboxFile = dropboxFile;
@@ -71,31 +71,21 @@
 - (void)_updatedDisplayedInformation
 {
     if (_dropboxFile != nil) {
-        if (self.dropboxFile.isDirectory) {
-            self.folderTitleLabel.text = self.dropboxFile.filename;
+        if ([_dropboxFile isKindOfClass:[DBFILESFolderMetadata class]]) {
+            self.folderTitleLabel.text = self.dropboxFile.name;
             self.titleLabel.hidden = self.subtitleLabel.hidden = YES;
             self.folderTitleLabel.hidden = NO;
-        } else {
-            NSString *title = self.dropboxFile.filename;
+            self.downloadButton.hidden = YES;
+            self.thumbnailView.image = [UIImage imageNamed:@"folder"];
+        } else if ([_dropboxFile isKindOfClass:[DBFILESFileMetadata class]]) {
+            DBFILESFileMetadata *file = (DBFILESFileMetadata *)_dropboxFile;
+            NSString *title = file.name;
             self.titleLabel.text = title;
-            self.subtitleLabel.text = (self.dropboxFile.totalBytes > 0) ? self.dropboxFile.humanReadableSize : @"";
+            self.subtitleLabel.text = (file.size.integerValue > 0) ? [NSByteCountFormatter stringFromByteCount:file.size.longLongValue countStyle:NSByteCountFormatterCountStyleFile] : @"";
             self.titleLabel.hidden = self.subtitleLabel.hidden = NO;
             self.folderTitleLabel.hidden = YES;
-        }
-
-        NSString *iconName = self.dropboxFile.icon;
-        if ([iconName isEqualToString:@"folder_user"] || [iconName isEqualToString:@"folder"] || [iconName isEqualToString:@"folder_public"] || [iconName isEqualToString:@"folder_photos"] || [iconName isEqualToString:@"package"]) {
-            self.thumbnailView.image = [UIImage imageNamed:@"folder"];
-            self.downloadButton.hidden = YES;
-        } else if ([iconName isEqualToString:@"page_white"] || [iconName isEqualToString:@"page_white_text"])
-            self.thumbnailView.image = [UIImage imageNamed:@"blank"];
-        else if ([iconName isEqualToString:@"page_white_film"])
-            self.thumbnailView.image = [UIImage imageNamed:@"movie"];
-        else if ([iconName isEqualToString:@"page_white_sound"])
-            self.thumbnailView.image = [UIImage imageNamed:@"audio"];
-        else {
+            self.downloadButton.hidden = NO;
             self.thumbnailView.image = [UIImage imageNamed:@"blank"];
-            APLog(@"missing icon for type '%@'", self.dropboxFile.icon);
         }
     }
 #if TARGET_OS_IOS

+ 2 - 2
Sources/VLCCloudStorageTableViewController.m

@@ -197,8 +197,8 @@
 
     if(_authorizationInProgress || [self.controller isAuthorized]) {
         if (self.loginToCloudStorageView.superview) {
-        [self.loginToCloudStorageView removeFromSuperview];
-            }
+            [self.loginToCloudStorageView removeFromSuperview];
+        }
     }
 
     if (![self.controller isAuthorized]) {

+ 4 - 8
Sources/VLCDropboxController.h

@@ -10,14 +10,10 @@
  * Refer to the COPYING file of the official project for license.
  *****************************************************************************/
 
-#if TARGET_OS_IOS
-#import <DropboxSDK/DropboxSDK.h>
-#else
-#import <DropboxTVSDK/DropboxSDK.h>
-#endif
 #import "VLCCloudStorageController.h"
+#import <ObjectiveDropboxOfficial/ObjectiveDropboxOfficial.h>
 
-@interface VLCDropboxController : VLCCloudStorageController <DBRestClientDelegate, DBSessionDelegate, DBNetworkRequestDelegate>
+@interface VLCDropboxController : VLCCloudStorageController
 
 @property (nonatomic, readonly) NSInteger numberOfFilesWaitingToBeDownloaded;
 
@@ -26,8 +22,8 @@
 - (void)shareCredentials;
 - (BOOL)restoreFromSharedCredentials;
 
-- (void)downloadFileToDocumentFolder:(DBMetadata *)file;
-- (void)streamFile:(DBMetadata *)file currentNavigationController:(UINavigationController *)navigationController;
+- (void)downloadFileToDocumentFolder:(DBFILESMetadata *)file;
+- (void)streamFile:(DBFILESMetadata *)file currentNavigationController:(UINavigationController *)navigationController;
 
 - (void)reset;
 

+ 126 - 127
Sources/VLCDropboxController.m

@@ -15,26 +15,18 @@
 #import "NSString+SupportedMedia.h"
 #import "VLCPlaybackController.h"
 #import "VLCActivityManager.h"
-#if !TARGET_OS_TV
 #import "VLCMediaFileDiscoverer.h"
-#import <DropboxSDK/DBKeychain.h>
-#else
-#import <DropboxTVSDK/DBKeychain.h>
-#endif
 #import "VLCDropboxConstants.h"
 
 @interface VLCDropboxController ()
 {
-    DBRestClient *_restClient;
+    DBUserClient *_client;
     NSArray *_currentFileList;
 
     NSMutableArray *_listOfDropboxFilesToDownload;
     BOOL _downloadInProgress;
 
-    NSInteger _outstandingNetworkRequests;
-
     CGFloat _averageSpeed;
-    CGFloat _fileSize;
     NSTimeInterval _startDL;
     NSTimeInterval _lastStatsUpdate;
 
@@ -55,10 +47,6 @@
     dispatch_once(&pred, ^{
         sharedInstance = [VLCDropboxController new];
         [sharedInstance shareCredentials];
-
-        DBSession* dbSession = [[DBSession alloc] initWithAppKey:kVLCDropboxAppKey appSecret:kVLCDropboxPrivateKey root:kDBRootDropbox];
-        [DBSession setSharedSession:dbSession];
-        [DBRequest setNetworkRequestDelegate:sharedInstance];
     });
 
     return sharedInstance;
@@ -67,12 +55,12 @@
 - (void)shareCredentials
 {
     /* share our credentials */
-    NSDictionary *credentials = [DBKeychain credentials];
+    NSArray *credentials = [DBSDKKeychain retrieveAllTokenIds];
     if (credentials == nil)
         return;
 
     NSUbiquitousKeyValueStore *ubiquitousStore = [NSUbiquitousKeyValueStore defaultStore];
-    [ubiquitousStore setDictionary:credentials forKey:kVLCStoreDropboxCredentials];
+    [ubiquitousStore setArray:credentials forKey:kVLCStoreDropboxCredentials];
     [ubiquitousStore synchronize];
 }
 
@@ -80,39 +68,69 @@
 {
     NSUbiquitousKeyValueStore *ubiquitousStore = [NSUbiquitousKeyValueStore defaultStore];
     [ubiquitousStore synchronize];
-    NSDictionary *credentials = [ubiquitousStore dictionaryForKey:kVLCStoreDropboxCredentials];
+    NSArray *credentials = [ubiquitousStore arrayForKey:kVLCStoreDropboxCredentials];
     if (!credentials)
         return NO;
-
-    [DBKeychain setCredentials:credentials];
+    for (NSString *tmp in credentials) {
+        [DBSDKKeychain storeValueWithKey:kVLCStoreDropboxCredentials value:tmp];
+    }
     return YES;
 }
 
 - (void)startSession
 {
-    [[DBSession sharedSession] isLinked];
+    [DBClientsManager authorizedClient];
 }
 
 - (void)logout
 {
-    [[DBSession sharedSession] unlinkAll];
+    [DBClientsManager unlinkAndResetClients];
 }
 
 - (BOOL)isAuthorized
 {
-    return [[DBSession sharedSession] isLinked];
+    return [DBClientsManager authorizedClient];
 }
 
-- (DBRestClient *)restClient {
-    if (!_restClient) {
-        _restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
-        _restClient.delegate = self;
+- (DBUserClient *)client {
+    if (!_client) {
+        _client = [DBClientsManager authorizedClient];
     }
-    return _restClient;
+    return _client;
 }
 
+
 #pragma mark - file management
 
+- (BOOL)_supportedFileExtension:(NSString *)filename
+{
+    if ([filename isSupportedMediaFormat] || [filename isSupportedAudioMediaFormat] || [filename isSupportedSubtitleFormat])
+        return YES;
+
+    return NO;
+}
+
+- (NSString *)_createPotentialNameFrom:(NSString *)path
+{
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+
+    NSString *fileName = [path lastPathComponent];
+    NSString *finalFilePath = [path stringByDeletingLastPathComponent];
+
+    if ([fileManager fileExistsAtPath:path]) {
+        NSString *potentialFilename;
+        NSString *fileExtension = [fileName pathExtension];
+        NSString *rawFileName = [fileName stringByDeletingPathExtension];
+        for (NSUInteger x = 1; x < 100; x++) {
+            potentialFilename = [NSString stringWithFormat:@"%@_%lu.%@", rawFileName, (unsigned long)x, fileExtension];
+            if (![fileManager fileExistsAtPath:[finalFilePath stringByAppendingPathComponent:potentialFilename]])
+                break;
+        }
+        return [finalFilePath stringByAppendingPathComponent:potentialFilename];
+    }
+    return path;
+}
+
 - (BOOL)canPlayAll
 {
     return NO;
@@ -121,12 +139,12 @@
 - (void)requestDirectoryListingAtPath:(NSString *)path
 {
     if (self.isAuthorized)
-        [[self restClient] loadMetadata:path];
+        [self listFiles:path];
 }
 
-- (void)downloadFileToDocumentFolder:(DBMetadata *)file
+- (void)downloadFileToDocumentFolder:(DBFILESMetadata *)file
 {
-    if (!file.isDirectory) {
+    if (![file isKindOfClass:[DBFILESFolderMetadata class]]) {
         if (!_listOfDropboxFilesToDownload)
             _listOfDropboxFilesToDownload = [[NSMutableArray alloc] init];
         [_listOfDropboxFilesToDownload addObject:file];
@@ -138,16 +156,6 @@
     }
 }
 
-- (void)streamFile:(DBMetadata *)file currentNavigationController:(UINavigationController *)navigationController
-{
-    if (!file.isDirectory) {
-        _lastKnownNavigationController = navigationController;
-        NSString *path = file.path;
-        if (path != nil)
-            [[self restClient] loadStreamableURLForFile:path];
-    }
-}
-
 - (void)_triggerNextDownload
 {
     if (_listOfDropboxFilesToDownload.count > 0 && !_downloadInProgress) {
@@ -159,13 +167,13 @@
     }
 }
 
-- (void)_reallyDownloadFileToDocumentFolder:(DBMetadata *)file
+- (void)_reallyDownloadFileToDocumentFolder:(DBFILESFileMetadata *)file
 {
     NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
-    NSString *filePath = [searchPaths[0] stringByAppendingFormat:@"/%@", file.filename];
+    NSString *filePath = [searchPaths[0] stringByAppendingFormat:@"/%@", file.name];
     _startDL = [NSDate timeIntervalSinceReferenceDate];
-    _fileSize = file.totalBytes;
-    [[self restClient] loadFile:file.path intoPath:filePath];
+
+    [self downloadFileFrom:file.pathDisplay to:filePath];
 
     if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStarted)])
         [self.delegate operationWithProgressInformationStarted];
@@ -173,111 +181,103 @@
     _downloadInProgress = YES;
 }
 
-#pragma mark - restClient delegate
-- (BOOL)_supportedFileExtension:(NSString *)filename
-{
-    if ([filename isSupportedMediaFormat] || [filename isSupportedAudioMediaFormat] || [filename isSupportedSubtitleFormat])
-        return YES;
 
-    return NO;
+- (void)streamFile:(DBFILESMetadata *)file currentNavigationController:(UINavigationController *)navigationController
+{
+    if (![file isKindOfClass:[DBFILESFolderMetadata class]]) {
+        _lastKnownNavigationController = navigationController;
+        NSString *path = file.pathLower;
+        if (path != nil)
+            [self loadStreamFrom:path];
+    }
 }
 
-- (void)restClient:(DBRestClient *)client loadedMetadata:(DBMetadata *)metadata
-{
-    _currentFileList = [NSArray arrayWithArray:metadata.contents];
 
-    APLog(@"found filtered metadata for %lu files", (unsigned long)_currentFileList.count);
-    if ([self.delegate respondsToSelector:@selector(mediaListUpdated)])
-        [self.delegate mediaListUpdated];
-}
+# pragma mark - Dropbox API Request
 
-- (void)restClient:(DBRestClient *)client loadMetadataFailedWithError:(NSError *)error
+- (void)listFiles:(NSString *)path
 {
-    APLog(@"DBMetadata download failed with error %li", (long)error.code);
-    [self _handleError:error];
+    // DropBox API prefers an empty path than a '/'
+    if ([path isEqualToString:@"/"]) {
+        path = @"";
+    }
+    [[[self client].filesRoutes listFolder:path] setResponseBlock:^(DBFILESListFolderResult * _Nullable result, DBFILESListFolderError * _Nullable routeError, DBRequestError * _Nullable networkError) {
+        if (result) {
+            _currentFileList = [NSArray arrayWithArray:result.entries];
+            APLog(@"found filtered metadata for %lu files", (unsigned long)_currentFileList.count);
+            if ([self.delegate respondsToSelector:@selector(mediaListUpdated)])
+                [self.delegate mediaListUpdated];
+        } else {
+            APLog(@"listFiles failed with network error %li and error tag %li", (long)networkError.statusCode, (long)networkError.tag);
+            [self _handleError:[NSError errorWithDomain:networkError.description code:networkError.statusCode.integerValue userInfo:nil]];
+        }
+    }];
 }
 
-- (void)restClient:(DBRestClient*)client loadedFile:(NSString*)localPath
+- (void)downloadFileFrom:(NSString *)path to:(NSString *)destination
 {
-#if TARGET_OS_IOS
-    /* update library now that we got a file */
-    [[VLCMediaFileDiscoverer sharedInstance] performSelectorOnMainThread:@selector(updateMediaList) withObject:nil waitUntilDone:NO];
+    if (![self _supportedFileExtension:[path lastPathComponent]]) {
+        [self _handleError:[NSError errorWithDomain:NSLocalizedString(@"FILE_NOT_SUPPORTED", nil) code:415 userInfo:nil]];
+        return;
+    }
 
-    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
-        [self.delegate operationWithProgressInformationStopped];
-    _downloadInProgress = NO;
 
-    [self _triggerNextDownload];
-#endif
-}
-
-- (void)restClient:(DBRestClient*)client loadFileFailedWithError:(NSError*)error
-{
-    APLog(@"DBFile download failed with error %li", (long)error.code);
-    [self _handleError:error];
-    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
-        [self.delegate operationWithProgressInformationStopped];
-    _downloadInProgress = NO;
-    [self _triggerNextDownload];
-}
+    // Need to replace all ' ' by '_' because it causes a `NSInvalidArgumentException ... destination path is nil` in the dropbox library.
+    if ([destination containsString:@" "])
+        destination = [destination stringByReplacingOccurrencesOfString:@" " withString:@"_"];
 
-- (void)restClient:(DBRestClient*)client loadProgress:(CGFloat)progress forFile:(NSString*)destPath
-{
-    if ((_lastStatsUpdate > 0 && ([NSDate timeIntervalSinceReferenceDate] - _lastStatsUpdate > .5)) || _lastStatsUpdate <= 0) {
-        [self calculateRemainingTime:progress * _fileSize expectedDownloadSize:_fileSize];
-        _lastStatsUpdate = [NSDate timeIntervalSinceReferenceDate];
-    }
+    destination = [self _createPotentialNameFrom:destination];
 
-    if ([self.delegate respondsToSelector:@selector(currentProgressInformation:)])
-        [self.delegate currentProgressInformation:progress];
-}
+    [[[_client.filesRoutes downloadUrl:path overwrite:YES destination:[NSURL URLWithString:destination]]
+        setResponseBlock:^(DBFILESFileMetadata * _Nullable result, DBFILESDownloadError * _Nullable routeError, DBRequestError * _Nullable networkError, NSURL * _Nonnull destination) {
 
-- (void)restClient:(DBRestClient*)restClient loadedStreamableURL:(NSURL*)url forFile:(NSString*)path
-{
-    VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
-    [vpc playURL:url successCallback:nil errorCallback:nil];
-#if TARGET_OS_TV
-    if (_lastKnownNavigationController) {
-        VLCFullscreenMovieTVViewController *movieVC = [VLCFullscreenMovieTVViewController fullscreenMovieTVViewController];
-        [_lastKnownNavigationController presentViewController:movieVC
-                                                     animated:YES
-                                                   completion:nil];
-    }
-#endif
-}
+            if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)]) {
+                [self.delegate operationWithProgressInformationStopped];
+            }
 
-- (void)restClient:(DBRestClient*)restClient loadStreamableURLFailedWithError:(NSError*)error
-{
-    APLog(@"loadStreamableURL failed with error %li", (long)error.code);
-    [self _handleError:error];
-}
+            _downloadInProgress = NO;
+            [self _triggerNextDownload];
+            if (!result) {
+                APLog(@"downloadFile failed with network error %li and error tag %li", (long)networkError.statusCode, (long)networkError.tag);
+                [self _handleError:[NSError errorWithDomain:networkError.description code:networkError.statusCode.integerValue userInfo:nil]];
+            }
+        }] setProgressBlock:^(int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite) {
+            if ((_lastStatsUpdate > 0 && ([NSDate timeIntervalSinceReferenceDate] - _lastStatsUpdate > .5)) || _lastStatsUpdate <= 0) {
+                [self calculateRemainingTime:(CGFloat)totalBytesWritten expectedDownloadSize:(CGFloat)totalBytesExpectedToWrite];
+                _lastStatsUpdate = [NSDate timeIntervalSinceReferenceDate];
+            }
 
-#pragma mark - DBSession delegate
+            if ([self.delegate respondsToSelector:@selector(currentProgressInformation:)])
+                [self.delegate currentProgressInformation:(CGFloat)totalBytesWritten / (CGFloat)totalBytesExpectedToWrite];
+        }];
 
-- (void)sessionDidReceiveAuthorizationFailure:(DBSession *)session userId:(NSString *)userId
-{
-    APLog(@"DBSession received authorization failure with user ID %@", userId);
 }
 
-#pragma mark - DBNetworkRequest delegate
-- (void)networkRequestStarted
+- (void)loadStreamFrom:(NSString *)path
 {
-    _outstandingNetworkRequests++;
-    if (_outstandingNetworkRequests == 1) {
-        VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
-        [activityManager networkActivityStarted];
-        [activityManager disableIdleTimer];
+    if (![self _supportedFileExtension:[path lastPathComponent]]) {
+        [self _handleError:[NSError errorWithDomain:NSLocalizedString(@"FILE_NOT_SUPPORTED", nil) code:415 userInfo:nil]];
+        return;
     }
-}
 
-- (void)networkRequestStopped
-{
-    _outstandingNetworkRequests--;
-    if (_outstandingNetworkRequests == 0) {
-        VLCActivityManager *activityManager = [VLCActivityManager defaultManager];
-        [activityManager networkActivityStopped];
-        [activityManager activateIdleTimer];
-    }
+    [[_client.filesRoutes getTemporaryLink:path] setResponseBlock:^(DBFILESGetTemporaryLinkResult * _Nullable result, DBFILESGetTemporaryLinkError * _Nullable routeError, DBRequestError * _Nullable networkError) {
+
+        if (result) {
+            VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
+            [vpc playURL:[NSURL URLWithString:result.link ] successCallback:nil errorCallback:nil];
+            #if TARGET_OS_TV
+            if (_lastKnownNavigationController) {
+                VLCFullscreenMovieTVViewController *movieVC = [VLCFullscreenMovieTVViewController fullscreenMovieTVViewController];
+                [_lastKnownNavigationController presentViewController:movieVC
+                                                             animated:YES
+                                                           completion:nil];
+            }
+            #endif
+        } else {
+            APLog(@"loadStream failed with network error %li and error tag %li", (long)networkError.statusCode, (long)networkError.tag);
+            [self _handleError:[NSError errorWithDomain:networkError.description code:networkError.statusCode.integerValue userInfo:nil]];
+        }
+    }];
 }
 
 #pragma mark - VLC internal communication and delegate
@@ -341,7 +341,6 @@
 
 - (void)reset
 {
-    [_restClient cancelAllRequests];
     _currentFileList = nil;
 }
 

+ 13 - 13
Sources/VLCDropboxTableViewController.m

@@ -18,18 +18,12 @@
 #import "VLCDropboxController.h"
 #import "VLCCloudStorageTableViewCell.h"
 #import "UIDevice+VLC.h"
-#if TARGET_OS_IOS
-#import <DropboxSDK/DBKeychain.h>
 #import "VLCAppDelegate.h"
-#else
-#import "DBKeychain.h"
-#endif
-
 
 @interface VLCDropboxTableViewController () <VLCCloudStorageTableViewCell, VLCCloudStorageDelegate>
 {
     VLCDropboxController *_dropboxController;
-    DBMetadata *_selectedFile;
+    DBFILESMetadata *_selectedFile;
     NSArray *_mediaList;
 }
 
@@ -87,6 +81,7 @@
         self.title = self.currentPath.lastPathComponent;
 
     [self updateViewAfterSessionChange];
+    [self.tableView reloadData];
 }
 
 #pragma mark - interface interaction
@@ -132,11 +127,11 @@
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
     _selectedFile = _mediaList[indexPath.row];
-    if (!_selectedFile.isDirectory)
+    if (![_selectedFile isKindOfClass:[DBFILESFolderMetadata class]])
         [_dropboxController streamFile:_selectedFile currentNavigationController:self.navigationController];
     else {
         /* dive into subdirectory */
-        NSString *futurePath = [self.currentPath stringByAppendingFormat:@"/%@", _selectedFile.filename];
+        NSString *futurePath = [self.currentPath stringByAppendingFormat:@"/%@", _selectedFile.name];
         self.currentPath = futurePath;
         [self requestInformationForCurrentPath];
     }
@@ -151,7 +146,12 @@
 {
     if (!_dropboxController.isAuthorized) {
         self.authorizationInProgress = YES;
-        [[DBSession sharedSession] linkFromController:self];
+
+        [DBClientsManager authorizeFromController:[UIApplication sharedApplication]
+                                       controller:self
+                                          openURL:^(NSURL *url) {
+                                              [[UIApplication sharedApplication] openURL:url];
+                                          }];
     } else
         [_dropboxController logout];
 }
@@ -171,17 +171,17 @@
 {
     _selectedFile = _mediaList[[self.tableView indexPathForCell:cell].row];
 
-    if (_selectedFile.totalBytes < [[UIDevice currentDevice] VLCFreeDiskSpace].longLongValue) {
+    if (((DBFILESFileMetadata *)_selectedFile).size.longLongValue < [[UIDevice currentDevice] VLCFreeDiskSpace].longLongValue) {
         /* selected item is a proper file, ask the user if s/he wants to download it */
         VLCAlertView *alert = [[VLCAlertView alloc] initWithTitle:NSLocalizedString(@"DROPBOX_DOWNLOAD", nil)
-                                                          message:[NSString stringWithFormat:NSLocalizedString(@"DROPBOX_DL_LONG", nil), _selectedFile.filename, [[UIDevice currentDevice] model]]
+                                                          message:[NSString stringWithFormat:NSLocalizedString(@"DROPBOX_DL_LONG", nil), _selectedFile.name, [[UIDevice currentDevice] model]]
                                                          delegate:self
                                                 cancelButtonTitle:NSLocalizedString(@"BUTTON_CANCEL", nil)
                                                 otherButtonTitles:NSLocalizedString(@"BUTTON_DOWNLOAD", nil), nil];
         [alert show];
     } else {
         VLCAlertView *alert = [[VLCAlertView alloc] initWithTitle:NSLocalizedString(@"DISK_FULL", nil)
-                                                          message:[NSString stringWithFormat:NSLocalizedString(@"DISK_FULL_FORMAT", nil), _selectedFile.filename, [[UIDevice currentDevice] model]]
+                                                          message:[NSString stringWithFormat:NSLocalizedString(@"DISK_FULL_FORMAT", nil), _selectedFile.name, [[UIDevice currentDevice] model]]
                                                          delegate:self
                                                 cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
                                                 otherButtonTitles:nil];