Browse Source

OneDrive: implement file downloading

Note that we don't use the Live SDK for this, but the existing HTTP downloading class for simplicity and performance reasons
Felix Paul Kühne 10 years ago
parent
commit
a53e2d1dd9

+ 2 - 0
Sources/VLCCloudStorageTableViewCell.m

@@ -146,11 +146,13 @@
         }
         }
     } else if(_oneDriveFile != nil) {
     } else if(_oneDriveFile != nil) {
         if (_oneDriveFile.isFolder) {
         if (_oneDriveFile.isFolder) {
+            self.downloadButton.hidden = YES;
             self.folderTitleLabel.text = self.oneDriveFile.name;
             self.folderTitleLabel.text = self.oneDriveFile.name;
             self.titleLabel.hidden = self.subtitleLabel.hidden = YES;
             self.titleLabel.hidden = self.subtitleLabel.hidden = YES;
             self.folderTitleLabel.hidden = NO;
             self.folderTitleLabel.hidden = NO;
             self.thumbnailView.image = [UIImage imageNamed:@"folder"];
             self.thumbnailView.image = [UIImage imageNamed:@"folder"];
         } else {
         } else {
+            self.downloadButton.hidden = NO;
             self.titleLabel.text = self.oneDriveFile.name;
             self.titleLabel.text = self.oneDriveFile.name;
             NSMutableString *subtitle = [[NSMutableString alloc] init];
             NSMutableString *subtitle = [[NSMutableString alloc] init];
             if (self.oneDriveFile.size > 0) {
             if (self.oneDriveFile.size > 0) {

+ 3 - 3
Sources/VLCOneDriveController.h

@@ -31,7 +31,7 @@
 
 
 @interface VLCOneDriveController : NSObject
 @interface VLCOneDriveController : NSObject
 
 
-@property (nonatomic, weak) VLCOneDriveTableViewController *delegate;
+@property (nonatomic, weak) UIViewController <VLCOneDriveControllerDelegate>*delegate;
 @property (readonly) BOOL activeSession;
 @property (readonly) BOOL activeSession;
 @property (readonly) BOOL userAuthenticated;
 @property (readonly) BOOL userAuthenticated;
 @property (nonatomic, readonly) VLCOneDriveObject *rootFolder;
 @property (nonatomic, readonly) VLCOneDriveObject *rootFolder;
@@ -42,8 +42,8 @@
 - (void)login;
 - (void)login;
 - (void)logout;
 - (void)logout;
 
 
+- (void)downloadObject:(VLCOneDriveObject *)object;
+
 - (void)loadCurrentFolder;
 - (void)loadCurrentFolder;
-- (void)downloadFileWithPath:(NSString *)path;
-- (void)streamFileWithPath:(NSString *)path;
 
 
 @end
 @end

+ 66 - 16
Sources/VLCOneDriveController.m

@@ -21,11 +21,19 @@
 /* include private API headers */
 /* include private API headers */
 #import <LiveSDK/LiveApiHelper.h>
 #import <LiveSDK/LiveApiHelper.h>
 
 
-@interface VLCOneDriveController () <LiveAuthDelegate, LiveDownloadOperationDelegate, VLCOneDriveObjectDelegate>
+@interface VLCOneDriveController () <LiveAuthDelegate, VLCOneDriveObjectDelegate, VLCOneDriveObjectDownloadDelegate>
 {
 {
     LiveConnectClient *_liveClient;
     LiveConnectClient *_liveClient;
     NSArray *_liveScopes;
     NSArray *_liveScopes;
     BOOL _activeSession;
     BOOL _activeSession;
+
+    NSMutableArray *_pendingDownloads;
+    BOOL _downloadInProgress;
+
+    CGFloat _averageSpeed;
+    CGFloat _fileSize;
+    NSTimeInterval _startDL;
+    NSTimeInterval _lastStatsUpdate;
 }
 }
 
 
 @end
 @end
@@ -85,7 +93,7 @@
 
 
 - (void)authCompleted:(LiveConnectSessionStatus)status session:(LiveConnectSession *)session userState:(id)userState
 - (void)authCompleted:(LiveConnectSessionStatus)status session:(LiveConnectSession *)session userState:(id)userState
 {
 {
-    NSLog(@"authCompleted, status %i, state %@", status, userState);
+    APLog(@"OneDrive: authCompleted, status %i, state %@", status, userState);
 
 
     if (status == 1 && session != NULL && [userState isEqualToString:@"init"])
     if (status == 1 && session != NULL && [userState isEqualToString:@"init"])
         _activeSession = YES;
         _activeSession = YES;
@@ -151,40 +159,82 @@
 
 
 #pragma mark - file handling
 #pragma mark - file handling
 
 
-- (void)downloadFileWithPath:(NSString *)path
+- (void)downloadObject:(VLCOneDriveObject *)object
 {
 {
+    if (object.isFolder)
+        return;
+
+    object.downloadDelegate = self;
+    if (!_pendingDownloads)
+        _pendingDownloads = [[NSMutableArray alloc] init];
+    [_pendingDownloads addObject:object];
+
+    [self _triggerNextDownload];
 }
 }
 
 
-- (void)liveDownloadOperationProgressed:(LiveOperationProgress *)progress
-                                   data:(NSData *)receivedData
-                              operation:(LiveDownloadOperation *)operation
+- (void)_triggerNextDownload
 {
 {
+    if (_pendingDownloads.count > 0 && !_downloadInProgress) {
+        _downloadInProgress = YES;
+        [_pendingDownloads[0] saveObjectToDocuments];
+        [_pendingDownloads removeObjectAtIndex:0];
+
+        if ([self.delegate respondsToSelector:@selector(numberOfFilesWaitingToBeDownloadedChanged)])
+            [self.delegate numberOfFilesWaitingToBeDownloadedChanged];
+    }
 }
 }
 
 
-- (void)streamFileWithPath:(NSString *)path
+- (void)downloadStarted:(VLCOneDriveObject *)object
 {
 {
+    _startDL = [NSDate timeIntervalSinceReferenceDate];
+    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStarted)])
+        [self.delegate operationWithProgressInformationStarted];
 }
 }
 
 
-#pragma mark - skydrive object delegation
+- (void)downloadEnded:(VLCOneDriveObject *)object
+{
+    if ([self.delegate respondsToSelector:@selector(operationWithProgressInformationStopped)])
+        [self.delegate operationWithProgressInformationStopped];
 
 
-- (void)folderContentLoaded:(VLCOneDriveObject *)sender
+    _downloadInProgress = NO;
+    [self _triggerNextDownload];
+}
+
+- (void)progressUpdated:(CGFloat)progress
 {
 {
-    if (self.delegate)
-        [self.delegate performSelector:@selector(mediaListUpdated)];
+    if ([self.delegate respondsToSelector:@selector(currentProgressInformation:)])
+        [self.delegate currentProgressInformation:progress];
 }
 }
 
 
-- (void)folderContentLoadingFailed:(NSError *)error sender:(VLCOneDriveObject *)sender
+- (void)calculateRemainingTime:(CGFloat)receivedDataSize expectedDownloadSize:(CGFloat)expectedDownloadSize
 {
 {
-    APLog(@"folder content loading failed %@", error);
+    CGFloat lastSpeed = receivedDataSize / ([NSDate timeIntervalSinceReferenceDate] - _startDL);
+    CGFloat smoothingFactor = 0.005;
+    _averageSpeed = isnan(_averageSpeed) ? lastSpeed : smoothingFactor * lastSpeed + (1 - smoothingFactor) * _averageSpeed;
+
+    CGFloat RemainingInSeconds = (expectedDownloadSize - receivedDataSize)/_averageSpeed;
+
+    NSDate *date = [NSDate dateWithTimeIntervalSince1970:RemainingInSeconds];
+    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
+    [formatter setDateFormat:@"HH:mm:ss"];
+    [formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
+
+    NSString  *remaingTime = [formatter stringFromDate:date];
+    if ([self.delegate respondsToSelector:@selector(updateRemainingTime:)])
+        [self.delegate updateRemainingTime:remaingTime];
 }
 }
 
 
-- (void)fileContentLoaded:(VLCOneDriveObject *)sender
+#pragma mark - onedrive object delegation
+
+- (void)folderContentLoaded:(VLCOneDriveObject *)sender
 {
 {
+    if (self.delegate)
+        [self.delegate performSelector:@selector(mediaListUpdated)];
 }
 }
 
 
-- (void)fileContentLoadingFailed:(NSError *)error sender:(VLCOneDriveObject *)sender
+- (void)folderContentLoadingFailed:(NSError *)error sender:(VLCOneDriveObject *)sender
 {
 {
-    APLog(@"file content loading failed %@", error);
+    APLog(@"folder content loading failed %@", error);
 }
 }
 
 
 - (void)fullFolderTreeLoaded:(VLCOneDriveObject *)sender
 - (void)fullFolderTreeLoaded:(VLCOneDriveObject *)sender

+ 8 - 5
Sources/VLCOneDriveObject.h

@@ -22,12 +22,14 @@
 
 
 - (void)folderContentLoadingFailed:(NSError *)error
 - (void)folderContentLoadingFailed:(NSError *)error
                             sender:(VLCOneDriveObject *) sender;
                             sender:(VLCOneDriveObject *) sender;
+@end
 
 
-- (void)fileContentLoaded:(VLCOneDriveObject *)sender;
-
-- (void)fileContentLoadingFailed:(NSError *)error
-                          sender:(VLCOneDriveObject *) sender;
+@protocol VLCOneDriveObjectDownloadDelegate <NSObject>
 
 
+- (void)downloadStarted:(VLCOneDriveObject *)object;
+- (void)downloadEnded:(VLCOneDriveObject *)object;
+- (void)progressUpdated:(CGFloat)progress;
+- (void)calculateRemainingTime:(CGFloat)receivedDataSize expectedDownloadSize:(CGFloat)expectedDownloadSize;
 @end
 @end
 
 
 @interface VLCOneDriveObject : NSObject <LiveOperationDelegate, LiveDownloadOperationDelegate, VLCOneDriveObjectDelegate>
 @interface VLCOneDriveObject : NSObject <LiveOperationDelegate, LiveDownloadOperationDelegate, VLCOneDriveObjectDelegate>
@@ -53,8 +55,9 @@
 
 
 @property (strong, nonatomic) LiveConnectClient *liveClient;
 @property (strong, nonatomic) LiveConnectClient *liveClient;
 @property (strong, nonatomic) id<VLCOneDriveObjectDelegate>delegate;
 @property (strong, nonatomic) id<VLCOneDriveObjectDelegate>delegate;
+@property (strong, nonatomic) id<VLCOneDriveObjectDownloadDelegate>downloadDelegate;
 
 
 - (void)loadFolderContent;
 - (void)loadFolderContent;
-- (void)loadFileContent;
+- (void)saveObjectToDocuments;
 
 
 @end
 @end

+ 38 - 21
Sources/VLCOneDriveObject.m

@@ -11,6 +11,14 @@
  *****************************************************************************/
  *****************************************************************************/
 
 
 #import "VLCOneDriveObject.h"
 #import "VLCOneDriveObject.h"
+#import "VLCHTTPFileDownloader.h"
+
+@interface VLCOneDriveObject () <VLCHTTPFileDownloader>
+{
+    VLCHTTPFileDownloader *_fileDownloader;
+}
+
+@end
 
 
 @implementation VLCOneDriveObject
 @implementation VLCOneDriveObject
 
 
@@ -60,7 +68,6 @@
 
 
 - (void)loadFolderContent
 - (void)loadFolderContent
 {
 {
-    NSLog(@"loadFolderContent");
     if (!self.isFolder) {
     if (!self.isFolder) {
         APLog(@"%@ is no folder, can't load content", self.objectId);
         APLog(@"%@ is no folder, can't load content", self.objectId);
         return;
         return;
@@ -85,25 +92,13 @@
     }
     }
 }
 }
 
 
-- (void)loadFileContent
-{
-}
-
 #pragma mark - live operations
 #pragma mark - live operations
 
 
 - (void)liveOperationSucceeded:(LiveDownloadOperation *)operation
 - (void)liveOperationSucceeded:(LiveDownloadOperation *)operation
 {
 {
     NSString *userState = operation.userState;
     NSString *userState = operation.userState;
 
 
-    NSLog(@"liveOperationSucceeded: %@", userState);
-
-    if ([userState isEqualToString:@"load-file-content"]) {
-//        LiveDownloadOperation *downloadOperation = (LiveDownloadOperation *)operation;
-
-        //FIXME: handle the incoming data!
-
-        [self.delegate fileContentLoaded:self];
-    } else if ([userState isEqualToString:@"load-folder-content"]) {
+    if ([userState isEqualToString:@"load-folder-content"]) {
         NSMutableArray *subFolders = [[NSMutableArray alloc] init];
         NSMutableArray *subFolders = [[NSMutableArray alloc] init];
         NSMutableArray *folderFiles = [[NSMutableArray alloc] init];
         NSMutableArray *folderFiles = [[NSMutableArray alloc] init];
         NSMutableArray *items = [[NSMutableArray alloc] init];
         NSMutableArray *items = [[NSMutableArray alloc] init];
@@ -146,14 +141,10 @@
 {
 {
     NSString *userState = operation.userState;
     NSString *userState = operation.userState;
 
 
-    NSLog(@"liveOperationFailed %@ (%@)", userState, error);
+    APLog(@"liveOperationFailed %@ (%@)", userState, error);
 
 
     if ([userState isEqualToString:@"load-folder-content"])
     if ([userState isEqualToString:@"load-folder-content"])
         [self.delegate folderContentLoadingFailed:error sender:self];
         [self.delegate folderContentLoadingFailed:error sender:self];
-    else if ([userState isEqualToString:@"load-file-content"])
-        [self.delegate fileContentLoadingFailed:error sender:self];
-    else
-        APLog(@"failing live operation with state %@ failed with error %@", userState, error);
 }
 }
 
 
 #pragma mark - delegation
 #pragma mark - delegation
@@ -173,12 +164,38 @@
     [self loadFolderContent];
     [self loadFolderContent];
 }
 }
 
 
-- (void)fileContentLoaded:(VLCOneDriveObject *)sender
+#pragma mark - file downloading
+
+- (void)saveObjectToDocuments
+{
+    _fileDownloader = [[VLCHTTPFileDownloader alloc] init];
+    _fileDownloader.delegate = self;
+    [_fileDownloader downloadFileFromURLwithFileName:[NSURL URLWithString:self.downloadPath] fileNameOfMedia:self.name];
+}
+
+- (void)downloadStarted
+{
+    if ([self.downloadDelegate respondsToSelector:@selector(downloadStarted:)])
+        [self.downloadDelegate downloadStarted:self];
+}
+
+- (void)downloadEnded
+{
+    if ([self.downloadDelegate respondsToSelector:@selector(downloadEnded:)])
+        [self.downloadDelegate downloadEnded:self];
+}
+
+- (void)downloadFailedWithErrorDescription:(NSString *)description
 {
 {
+    APLog(@"download failed (%@)", description);
 }
 }
 
 
-- (void)fileContentLoadingFailed:(NSError *)error sender:(VLCOneDriveObject *)sender
+- (void)progressUpdatedTo:(CGFloat)percentage receivedDataSize:(CGFloat)receivedDataSize expectedDownloadSize:(CGFloat)expectedDownloadSize
 {
 {
+    if ([self.downloadDelegate respondsToSelector:@selector(progressUpdated:)])
+        [self.downloadDelegate progressUpdated:percentage];
+    if ([self.downloadDelegate respondsToSelector:@selector(calculateRemainingTime:expectedDownloadSize:)])
+        [self.downloadDelegate calculateRemainingTime:receivedDataSize expectedDownloadSize:expectedDownloadSize];
 }
 }
 
 
 @end
 @end

+ 80 - 0
Sources/VLCOneDriveTableViewController.m

@@ -16,16 +16,22 @@
 #import "VLCCloudStorageTableViewCell.h"
 #import "VLCCloudStorageTableViewCell.h"
 #import "VLCAppDelegate.h"
 #import "VLCAppDelegate.h"
 #import "VLCOneDriveController.h"
 #import "VLCOneDriveController.h"
+#import "VLCProgressView.h"
 
 
 @interface VLCOneDriveTableViewController () <UITableViewDataSource, UITableViewDelegate, VLCOneDriveControllerDelegate, VLCCloudStorageTableViewCell>
 @interface VLCOneDriveTableViewController () <UITableViewDataSource, UITableViewDelegate, VLCOneDriveControllerDelegate, VLCCloudStorageTableViewCell>
 {
 {
     UIBarButtonItem *_backButton;
     UIBarButtonItem *_backButton;
     UIBarButtonItem *_logoutButton;
     UIBarButtonItem *_logoutButton;
+    UIBarButtonItem *_numberOfFilesBarButtonItem;
+    UIBarButtonItem *_progressBarButtonItem;
+    VLCProgressView *_progressView;
 
 
     UIActivityIndicatorView *_activityIndicator;
     UIActivityIndicatorView *_activityIndicator;
 
 
     VLCOneDriveController *_oneDriveController;
     VLCOneDriveController *_oneDriveController;
     NSString *_currentPath;
     NSString *_currentPath;
+
+    VLCOneDriveObject *_selectedFile;
 }
 }
 @end
 @end
 
 
@@ -50,6 +56,12 @@
     self.tableView.separatorColor = [UIColor VLCDarkBackgroundColor];
     self.tableView.separatorColor = [UIColor VLCDarkBackgroundColor];
     self.view.backgroundColor = [UIColor VLCDarkBackgroundColor];
     self.view.backgroundColor = [UIColor VLCDarkBackgroundColor];
 
 
+    _numberOfFilesBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:[NSString stringWithFormat:NSLocalizedString(@"NUM_OF_FILES", nil), 0] style:UIBarButtonItemStylePlain target:nil action:nil];
+    [_numberOfFilesBarButtonItem setTitleTextAttributes:@{ UITextAttributeFont : [UIFont systemFontOfSize:11.] } forState:UIControlStateNormal];
+
+    _progressView = [VLCProgressView new];
+    _progressBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_progressView];
+
     self.cloudStorageLogo = nil;
     self.cloudStorageLogo = nil;
     if (!SYSTEM_RUNS_IOS7_OR_LATER) {
     if (!SYSTEM_RUNS_IOS7_OR_LATER) {
         self.flatLoginButton.hidden = YES;
         self.flatLoginButton.hidden = YES;
@@ -59,6 +71,10 @@
         [self.flatLoginButton setTitle:NSLocalizedString(@"DROPBOX_LOGIN", nil) forState:UIControlStateNormal];
         [self.flatLoginButton setTitle:NSLocalizedString(@"DROPBOX_LOGIN", nil) forState:UIControlStateNormal];
     }
     }
 
 
+    [self.navigationController.toolbar setBackgroundImage:[UIImage imageNamed:@"sudHeaderBg"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
+
+    [self _showProgressInToolbar:NO];
+
     _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
     _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
     _activityIndicator.hidesWhenStopped = YES;
     _activityIndicator.hidesWhenStopped = YES;
     _activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
     _activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
@@ -70,6 +86,10 @@
 
 
 - (void)viewWillAppear:(BOOL)animated
 - (void)viewWillAppear:(BOOL)animated
 {
 {
+    self.navigationController.toolbarHidden = NO;
+    self.navigationController.toolbar.barStyle = UIBarStyleBlack;
+    [self.navigationController.toolbar setBackgroundImage:[UIImage imageNamed:@"bottomBlackBar"] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
+
     [super viewWillAppear:animated];
     [super viewWillAppear:animated];
 
 
     if (_oneDriveController.activeSession)
     if (_oneDriveController.activeSession)
@@ -82,6 +102,12 @@
     self.cloudStorageLogo.center = self.view.center;
     self.cloudStorageLogo.center = self.view.center;
 }
 }
 
 
+- (void)viewWillDisappear:(BOOL)animated
+{
+    self.navigationController.toolbarHidden = YES;
+    [super viewWillDisappear:animated];
+}
+
 #pragma mark - generic interface interaction
 #pragma mark - generic interface interaction
 
 
 - (IBAction)goBack:(id)sender
 - (IBAction)goBack:(id)sender
@@ -148,6 +174,14 @@
     [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
     [self.tableView deselectRowAtIndexPath:indexPath animated:NO];
 }
 }
 
 
+- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
+{
+    if (buttonIndex == 1)
+        [_oneDriveController downloadObject:_selectedFile];
+
+    _selectedFile = nil;
+}
+
 #pragma mark - login dialog
 #pragma mark - login dialog
 
 
 - (void)logout
 - (void)logout
@@ -175,6 +209,14 @@
     [_activityIndicator stopAnimating];
     [_activityIndicator stopAnimating];
 
 
     [self.tableView reloadData];
     [self.tableView reloadData];
+
+    NSUInteger count = _oneDriveController.currentFolder.items.count;
+    if (count == 0)
+        _numberOfFilesBarButtonItem.title = NSLocalizedString(@"NO_FILES", nil);
+    else if (count != 1)
+        _numberOfFilesBarButtonItem.title = [NSString stringWithFormat:NSLocalizedString(@"NUM_OF_FILES", nil), count];
+    else
+        _numberOfFilesBarButtonItem.title = NSLocalizedString(@"ONE_FILE", nil);
 }
 }
 
 
 - (void)sessionWasUpdated
 - (void)sessionWasUpdated
@@ -182,6 +224,39 @@
     [self updateViewAfterSessionChange];
     [self updateViewAfterSessionChange];
 }
 }
 
 
+#pragma mark - download visualization
+
+- (void)_showProgressInToolbar:(BOOL)value
+{
+    if (!value)
+        [self setToolbarItems:@[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], _numberOfFilesBarButtonItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]] animated:YES];
+    else {
+        _progressView.progressBar.progress = 0.;
+        [self setToolbarItems:@[[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], _progressBarButtonItem, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]] animated:YES];
+    }
+}
+
+
+- (void)operationWithProgressInformationStarted
+{
+    [self _showProgressInToolbar:YES];
+}
+
+- (void)currentProgressInformation:(float)progress
+{
+    [_progressView.progressBar setProgress:progress animated:YES];
+}
+
+- (void)updateRemainingTime:(NSString *)time
+{
+    [_progressView updateTime:time];
+}
+
+- (void)operationWithProgressInformationStopped
+{
+    [self _showProgressInToolbar:NO];
+}
+
 #pragma mark - app delegate
 #pragma mark - app delegate
 
 
 - (void)updateViewAfterSessionChange
 - (void)updateViewAfterSessionChange
@@ -206,6 +281,11 @@
 
 
 - (void)triggerDownloadForCell:(VLCCloudStorageTableViewCell *)cell
 - (void)triggerDownloadForCell:(VLCCloudStorageTableViewCell *)cell
 {
 {
+    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
+    _selectedFile = _oneDriveController.currentFolder.items[indexPath.row];
+
+    UIAlertView * alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"DROPBOX_DOWNLOAD", nil) 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];
 }
 }
 
 
 @end
 @end