Bladeren bron

rework box for correct navigation on ATV

auto layout fixes, etc.
Felix Paul Kühne 9 jaren geleden
bovenliggende
commit
62d18f1e58

+ 2 - 1
Sources/VLCBoxController.h

@@ -14,10 +14,11 @@
 #import "VLCCloudStorageController.h"
 #import "VLCBoxConstants.h"
 
+#define VLCBoxControllerSessionUpdated @"VLCBoxControllerSessionUpdated"
+
 @interface VLCBoxController : VLCCloudStorageController
 
 - (void)stopSession;
-- (void)streamFile:(BoxFile *)file;
 - (void)downloadFileToDocumentFolder:(BoxFile *)file;
 - (BOOL)hasMoreFiles;
 

+ 24 - 41
Sources/VLCBoxController.m

@@ -16,7 +16,7 @@
 #import "VLCMediaFileDiscoverer.h"
 #import <SSKeychain/SSKeychain.h>
 
-@interface VLCBoxController () <NSURLConnectionDataDelegate>
+@interface VLCBoxController ()
 {
     BoxCollection *_fileList;
     BoxAPIJSONOperation *_operation;
@@ -53,8 +53,24 @@
     return sharedInstance;
 }
 
+- (void)dealloc
+{
+    [[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
 - (void)startSession
 {
+    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
+    [defaultCenter addObserver:self
+                      selector:@selector(boxApiTokenDidRefresh)
+                          name:BoxOAuth2SessionDidRefreshTokensNotification
+                        object:[BoxSDK sharedSDK].OAuth2Session];
+
+    [defaultCenter addObserver:self
+                      selector:@selector(boxApiTokenDidRefresh)
+                          name:BoxOAuth2SessionDidBecomeAuthenticatedNotification
+                        object:[BoxSDK sharedSDK].OAuth2Session];
+
     [BoxSDK sharedSDK].OAuth2Session.clientID = kVLCBoxClientID;
     [BoxSDK sharedSDK].OAuth2Session.clientSecret = kVLCBoxClientSecret;
     NSString *token = [SSKeychain passwordForService:kVLCBoxService account:kVLCBoxAccount];
@@ -87,6 +103,12 @@
         [self.delegate mediaListUpdated];
 }
 
+- (void)boxApiTokenDidRefresh
+{
+    NSLog(@"%s", __PRETTY_FUNCTION__);
+    [[NSNotificationCenter defaultCenter] postNotificationName:VLCBoxControllerSessionUpdated object:nil];
+}
+
 - (BOOL)isAuthorized
 {
     return [[BoxSDK sharedSDK].OAuth2Session isAuthorized];
@@ -129,46 +151,6 @@
     _operation = [[BoxSDK sharedSDK].foldersManager folderItemsWithID:_folderId requestBuilder:nil success:success failure:failure];
 }
 
-- (void)streamFile:(BoxFile *)file
-{
-    /* the Box API requires us to set an HTTP header to get the actual URL:
-     * curl -L https://api.box.com/2.0/files/FILE_ID/content -H "Authorization: Bearer ACCESS_TOKEN"
-     *
-     * ... however, libvlc does not support setting custom HTTP headers, so we are resolving the redirect ourselves with a NSURLConnection
-     * and pass the final location to libvlc, which does not require a custom HTTP header */
-
-    NSURL *baseURL = [[[BoxSDK sharedSDK] filesManager] URLWithResource:@"files"
-                                                                     ID:file.modelID
-                                                            subresource:@"content"
-                                                                  subID:nil];
-
-    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:baseURL
-                                                              cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
-                                                          timeoutInterval:60];
-
-    [urlRequest setValue:[NSString stringWithFormat:@"Bearer %@", [BoxSDK sharedSDK].OAuth2Session.accessToken] forHTTPHeaderField:@"Authorization"];
-
-    NSURLConnection *theTestConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
-    [theTestConnection start];
-}
-
-- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
-{
-    if (response != nil) {
-        /* we have 1 redirect from the original URL, so as soon as we'd do that,
-         * we grab the URL and cancel the connection */
-        NSURL *theActualURL = request.URL;
-
-        [connection cancel];
-
-        /* now ask VLC to stream the URL we were just passed */
-        VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
-        [vpc playURL:theActualURL successCallback:nil errorCallback:nil];
-    }
-
-    return request;
-}
-
 #if TARGET_OS_IOS
 
 - (void)downloadFileToDocumentFolder:(BoxItem *)file
@@ -229,6 +211,7 @@
     NSMutableArray *listOfGoodFilesAndFolders = [NSMutableArray new];
     _maxOffset = _fileList.totalCount.intValue;
     _offset += _fileList.numberOfEntries;
+
     NSUInteger numberOfEntries = _fileList.numberOfEntries;
     for (int i = 0; i < numberOfEntries; i++)
     {

+ 2 - 0
Sources/VLCBoxTableViewController.h

@@ -22,6 +22,8 @@
 
 @interface VLCBoxTableViewController : VLCCloudStorageTVTableViewController
 
+- (instancetype)initWithPath:(NSString *)path;
+
 @end
 
 #endif

+ 105 - 18
Sources/VLCBoxTableViewController.m

@@ -15,37 +15,49 @@
 #import "VLCBoxController.h"
 #import <SSKeychain/SSKeychain.h>
 #import "UIDevice+VLC.h"
+#import "VLCPlaybackController.h"
 
 #if TARGET_OS_IOS
-@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, BoxAuthorizationViewControllerDelegate, VLCCloudStorageDelegate>
+@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, BoxAuthorizationViewControllerDelegate, VLCCloudStorageDelegate, NSURLConnectionDataDelegate>
 #else
-@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, VLCCloudStorageDelegate>
+@interface VLCBoxTableViewController () <VLCCloudStorageTableViewCell, VLCCloudStorageDelegate, NSURLConnectionDataDelegate>
 #endif
 {
     BoxFile *_selectedFile;
     VLCBoxController *_boxController;
+    NSArray *_listOfFiles;
 }
 
 @end
 
 @implementation VLCBoxTableViewController
 
+- (instancetype)initWithPath:(NSString *)path
+{
+    self = [super init];
+    if (self) {
+        self.currentPath = path;
+    }
+    return self;
+}
+
 - (void)viewDidLoad
 {
     [super viewDidLoad];
 
-    _boxController = (VLCBoxController *)[VLCBoxController sharedInstance];
-    [_boxController startSession];
+    _boxController = [VLCBoxController sharedInstance];
     self.controller = _boxController;
     self.controller.delegate = self;
 
+#if TARGET_OS_IOS
     self.navigationItem.titleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Box"]];
 
-#if TARGET_OS_IOS
     [self.cloudStorageLogo setImage:[UIImage imageNamed:@"Box"]];
 
     [self.cloudStorageLogo sizeToFit];
     self.cloudStorageLogo.center = self.view.center;
+#else
+    self.title = @"Box";
 #endif
 
     // Handle logged in
@@ -93,8 +105,12 @@
 - (void)viewWillAppear:(BOOL)animated
 {
     [super viewWillAppear:animated];
-    self.currentPath = @"";
-    if([_boxController.currentListFiles count] == 0)
+
+    _boxController = [VLCBoxController sharedInstance];
+    self.controller = _boxController;
+    self.controller.delegate = self;
+
+    if (!_listOfFiles || _listOfFiles.count == 0)
         [self requestInformationForCurrentPath];
 }
 
@@ -109,6 +125,12 @@
 
 #pragma mark - Table view data source
 
+- (void)mediaListUpdated
+{
+    _listOfFiles = [[VLCBoxController sharedInstance].currentListFiles copy];
+    [self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
+}
+
 - (VLCCloudStorageTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
     static NSString *CellIdentifier = @"BoxCell";
@@ -117,37 +139,102 @@
     if (cell == nil)
         cell = [VLCCloudStorageTableViewCell cellWithReuseIdentifier:CellIdentifier];
 
-    cell.boxFile = _boxController.currentListFiles[indexPath.row];
-    cell.delegate = self;
+    NSUInteger index = indexPath.row;
+    if (_listOfFiles) {
+        if (index < _listOfFiles.count) {
+            cell.boxFile = _listOfFiles[index];
+            cell.delegate = self;
+        }
+    }
 
     return cell;
 }
 
+- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
+{
+    return _listOfFiles.count;
+}
+
 #pragma mark - Table view delegate
 
 
 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
 {
     [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
-    if (indexPath.row >= _boxController.currentListFiles.count)
+    if (indexPath.row >= _listOfFiles.count)
         return;
 
-    _selectedFile = _boxController.currentListFiles[indexPath.row];
+    _selectedFile = _listOfFiles[indexPath.row];
     if (![_selectedFile.type isEqualToString:@"folder"])
-        [_boxController streamFile:(BoxFile *)_selectedFile];
+        [self streamFile:(BoxFile *)_selectedFile];
     else {
         /* dive into subdirectory */
-        if (![self.currentPath isEqualToString:@""])
-            self.currentPath = [self.currentPath stringByAppendingString:@"/"];
-        self.currentPath = [self.currentPath stringByAppendingString:_selectedFile.modelID];
+        NSString *path = self.currentPath;
+        if (![path isEqualToString:@""])
+            path = [path stringByAppendingString:@"/"];
+        path = [path stringByAppendingString:_selectedFile.modelID];
+
+#if TARGET_OS_TV
+        VLCBoxTableViewController *targetViewController = [[VLCBoxTableViewController alloc] initWithPath:path];
+        [self.navigationController pushViewController:targetViewController animated:YES];
+#else
+        self.currentPath = path;
         [self requestInformationForCurrentPath];
+#endif
     }
 }
 
+- (void)streamFile:(BoxFile *)file
+{
+    /* the Box API requires us to set an HTTP header to get the actual URL:
+     * curl -L https://api.box.com/2.0/files/FILE_ID/content -H "Authorization: Bearer ACCESS_TOKEN"
+     *
+     * ... however, libvlc does not support setting custom HTTP headers, so we are resolving the redirect ourselves with a NSURLConnection
+     * and pass the final location to libvlc, which does not require a custom HTTP header */
+
+    NSURL *baseURL = [[[BoxSDK sharedSDK] filesManager] URLWithResource:@"files"
+                                                                     ID:file.modelID
+                                                            subresource:@"content"
+                                                                  subID:nil];
+
+    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:baseURL
+                                                              cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
+                                                          timeoutInterval:60];
+
+    [urlRequest setValue:[NSString stringWithFormat:@"Bearer %@", [BoxSDK sharedSDK].OAuth2Session.accessToken] forHTTPHeaderField:@"Authorization"];
+
+    NSURLConnection *theTestConnection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
+    [theTestConnection start];
+}
+
+- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
+{
+    if (response != nil) {
+        /* we have 1 redirect from the original URL, so as soon as we'd do that,
+         * we grab the URL and cancel the connection */
+        NSURL *theActualURL = request.URL;
+
+        [connection cancel];
+
+        /* now ask VLC to stream the URL we were just passed */
+        VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
+        [vpc playURL:theActualURL successCallback:nil errorCallback:nil];
+
+#if TARGET_OS_TV
+        VLCFullscreenMovieTVViewController *movieVC = [VLCFullscreenMovieTVViewController fullscreenMovieTVViewController];
+        [self presentViewController:movieVC
+                           animated:YES
+                         completion:nil];
+#endif
+    }
+
+    return request;
+}
+
 #if TARGET_OS_IOS
 - (void)triggerDownloadForCell:(VLCCloudStorageTableViewCell *)cell
 {
-    _selectedFile = _boxController.currentListFiles[[self.tableView indexPathForCell:cell].row];
+    _selectedFile = _listOfFiles[[self.tableView indexPathForCell:cell].row];
 
     if (_selectedFile.size.longLongValue < [[UIDevice currentDevice] freeDiskspace].longLongValue) {
         /* selected item is a proper file, ask the user if s/he wants to download it */
@@ -203,7 +290,7 @@
 
 - (void)boxDidGetLoggedOut
 {
-    [self showLoginPanel];
+    [self performSelectorOnMainThread:@selector(showLoginPanel) withObject:nil waitUntilDone:NO];
 }
 
 - (void)boxAPIAuthenticationDidFail
@@ -213,7 +300,7 @@
 
 - (void)boxAPIInitiateLogin
 {
-    [self showLoginPanel];
+    [self performSelectorOnMainThread:@selector(showLoginPanel) withObject:nil waitUntilDone:NO];
 }
 
 - (void)authorizationViewControllerDidCancel:(BoxAuthorizationViewController *)authorizationViewController

+ 2 - 0
Sources/VLCCloudServicesTableViewController.m

@@ -15,6 +15,7 @@
 #import "VLCDropboxTableViewController.h"
 #import "VLCGoogleDriveTableViewController.h"
 #import "VLCBoxTableViewController.h"
+#import "VLCBoxController.h"
 #import "VLCOneDriveTableViewController.h"
 #import "VLCOneDriveController.h"
 #import "VLCDocumentPickerController.h"
@@ -48,6 +49,7 @@
 
     self.dropboxTableViewController = [[VLCDropboxTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
     self.googleDriveTableViewController = [[VLCGoogleDriveTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
+    [[VLCBoxController sharedInstance] startSession];
     self.boxTableViewController = [[VLCBoxTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
     self.oneDriveTableViewController = [[VLCOneDriveTableViewController alloc] initWithNibName:@"VLCCloudStorageTableViewController" bundle:nil];
     self.documentPickerController = [VLCDocumentPickerController new];

+ 4 - 0
VLC for Apple TV/VLCCloudServicesTVViewController.h

@@ -14,9 +14,13 @@
 @interface VLCCloudServicesTVViewController : UIViewController
 
 @property (readwrite, nonatomic, weak) IBOutlet UIButton *oneDriveButton;
+@property (readwrite, nonatomic, weak) IBOutlet UIButton *boxButton;
+@property (readwrite, nonatomic, weak) IBOutlet UIButton *gDriveButton;
+@property (readwrite, nonatomic, weak) IBOutlet UIButton *dropboxButton;
 
 - (IBAction)dropbox:(id)sender;
 - (IBAction)onedrive:(id)sender;
 - (IBAction)box:(id)sender;
+- (IBAction)gdrive:(id)sender;
 
 @end

+ 28 - 24
VLC for Apple TV/VLCCloudServicesTVViewController.m

@@ -18,10 +18,12 @@
 #import "VLCOneDriveController.h"
 #import "VLCOneDriveTableViewController2.h"
 #import "VLCBoxTableViewController.h"
+#import "VLCBoxController.h"
 
 @interface VLCCloudServicesTVViewController ()
 {
     VLCOneDriveController *_oneDriveController;
+    VLCBoxController *_boxController;
 }
 
 @property (nonatomic) VLCDropboxTableViewController *dropboxTableViewController;
@@ -36,12 +38,19 @@
 
     NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
     [center addObserver:self selector:@selector(oneDriveSessionUpdated:) name:VLCOneDriveControllerSessionUpdated object:nil];
+    [center addObserver:self selector:@selector(boxSessionUpdated:) name:VLCBoxControllerSessionUpdated object:nil];
 
     _oneDriveController = [VLCOneDriveController sharedInstance];
+    _boxController = [VLCBoxController sharedInstance];
+    [_boxController startSession];
+
     self.dropboxTableViewController = [[VLCDropboxTableViewController alloc] initWithNibName:nil bundle:nil];
-    self.boxTableViewController = [[VLCBoxTableViewController alloc] initWithNibName:nil bundle:nil];
 
+    self.dropboxButton.enabled = self.gDriveButton.enabled = NO;
     [self oneDriveSessionUpdated:nil];
+    [self boxSessionUpdated:nil];
+
+    [self performSelector:@selector(updateDropbox) withObject:nil afterDelay:0.1];
 }
 
 - (void)dealloc
@@ -56,28 +65,12 @@
 
 - (IBAction)dropbox:(id)sender
 {
-    if ([[VLCDropboxController sharedInstance] restoreFromSharedCredentials]) {
-        [self.navigationController pushViewController:self.dropboxTableViewController animated:YES];
-        return;
-    }
-
-    UIAlertController *alert = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"LOGIN_FAIL", nil)
-                                                                   message:[NSString stringWithFormat:NSLocalizedString(@"CLOUD_LOGIN_FAIL_LONG", nil), @"Dropbox", @"Dropbox"]
-                                                            preferredStyle:UIAlertControllerStyleAlert];
-
-    UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_OK", nil)
-                                                            style:UIAlertActionStyleDestructive
-                                                          handler:^(UIAlertAction * action) {
-                                                          }];
-
-    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_RETRY", nil)
-                                                           style:UIAlertActionStyleDefault
-                                                         handler:^(UIAlertAction * action) {
-                                                             [self dropbox:nil];
-                                                         }];
-    [alert addAction:defaultAction];
-    [alert addAction:cancelAction];
-    [self presentViewController:alert animated:YES completion:nil];
+    [self.navigationController pushViewController:self.dropboxTableViewController animated:YES];
+}
+
+- (void)updateDropbox
+{
+    self.dropboxButton.enabled = [[VLCDropboxController sharedInstance] restoreFromSharedCredentials];
 }
 
 - (void)oneDriveSessionUpdated:(NSNotification *)aNotification
@@ -85,6 +78,11 @@
     self.oneDriveButton.enabled = _oneDriveController.activeSession;
 }
 
+- (void)boxSessionUpdated:(NSNotification *)aNotification
+{
+    self.boxButton.enabled = YES;
+}
+
 - (IBAction)onedrive:(id)sender
 {
     VLCOneDriveTableViewController2 *newKid = [[VLCOneDriveTableViewController2 alloc] initWithOneDriveObject:nil];
@@ -93,7 +91,13 @@
 
 - (IBAction)box:(id)sender
 {
-    [self.navigationController pushViewController:self.boxTableViewController animated:YES];
+    VLCBoxTableViewController *targetViewController = [[VLCBoxTableViewController alloc] initWithPath:@""];
+    [self.navigationController pushViewController:targetViewController animated:YES];
+}
+
+- (IBAction)gdrive:(id)sender
+{
+    // TODO
 }
 
 @end

+ 6 - 0
VLC for Apple TV/VLCCloudServicesTVViewController.xib

@@ -6,6 +6,9 @@
     <objects>
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="VLCCloudServicesTVViewController">
             <connections>
+                <outlet property="boxButton" destination="HPy-k8-PTt" id="FcV-v2-CVw"/>
+                <outlet property="dropboxButton" destination="hdP-Dp-Mn0" id="K7o-9U-5hB"/>
+                <outlet property="gDriveButton" destination="uaI-5Z-SJq" id="Etu-VC-Z2o"/>
                 <outlet property="oneDriveButton" destination="gFm-4V-QFs" id="eWx-9Y-RDg"/>
                 <outlet property="view" destination="iN0-l3-epB" id="Eym-vH-oyN"/>
             </connections>
@@ -27,6 +30,9 @@
                     <rect key="frame" x="810" y="445" width="301" height="86"/>
                     <inset key="contentEdgeInsets" minX="40" minY="20" maxX="40" maxY="20"/>
                     <state key="normal" title="Google Drive"/>
+                    <connections>
+                        <action selector="gdrive:" destination="-1" eventType="primaryActionTriggered" id="150-FC-FlB"/>
+                    </connections>
                 </button>
                 <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HPy-k8-PTt">
                     <rect key="frame" x="810" y="561" width="301" height="86"/>