Skip to content

Commit

Permalink
Microsoft OneDrive SDK & plugin : download file directly to file with…
Browse files Browse the repository at this point in the history
…out using NSData
  • Loading branch information
sylverb committed Dec 29, 2014
1 parent 1552358 commit f871544
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 34 deletions.
9 changes: 5 additions & 4 deletions NAStify/ConnectionManager/Plugins/OneDrive/CMOneDrive.m
Original file line number Diff line number Diff line change
Expand Up @@ -297,12 +297,12 @@ - (void)downloadFile:(FileItem *)file toLocalName:(NSString *)localName
[[SBNetworkActivityIndicator sharedInstance] beginActivity:self];

self.downloadOperation = [self.liveClient downloadFromPath:[[file.objectIds lastObject] stringByAppendingString:@"/content"]
destinationPath:localName
delegate:self
userState:@"downloadFile"];
}

- (void) liveDownloadOperationProgressed:(LiveOperationProgress *)progress
data:(NSData *)receivedData
operation:(LiveDownloadOperation *)operation
{
dispatch_async(dispatch_get_main_queue(), ^{
Expand Down Expand Up @@ -628,10 +628,8 @@ - (void) liveOperationSucceeded:(LiveOperation *)operation

else if ([operation.userState isEqual:@"downloadFile"])
{
// Write data to file
// FIXME: this is not a good way to do as it's not working for huge files ...
[self.downloadOperation.data writeToFile:self.destPath atomically:YES];
self.downloadOperation = nil;
self.destPath = nil;
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate CMDownloadFinished:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],@"success",
Expand Down Expand Up @@ -806,6 +804,9 @@ - (void) liveOperationFailed:(NSError *)error operation:(LiveOperation *)operati
nil]];
});
}
// Delete partially downloaded file
[[NSFileManager defaultManager] removeItemAtPath:self.destPath error:NULL];
self.destPath = nil;
}
else if ([operation.userState isEqual:@"uploadFile"])
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
userState:(id) userState;

- (LiveDownloadOperation *) downloadFromPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate
userState:(id)userState;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,10 +216,12 @@ - (LiveOperation *) sendRequestWithMethod:(NSString *)method
}

- (LiveDownloadOperation *) downloadFromPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate
userState:(id)userState
{
LiveDownloadOperationCore *operation = [[[LiveDownloadOperationCore alloc] initWithPath:path
LiveDownloadOperationCore *operation = [[[LiveDownloadOperationCore alloc] initWithPath:path
destinationPath:destinationPath
delegate:delegate
userState:userState
liveClient:self]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,20 @@
#import "LiveDownloadOperationDelegate.h"

@interface LiveDownloadOperationCore : LiveOperationCore
{
@private
NSUInteger contentLength;
}

- (id) initWithPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate
userState:(id)userState
liveClient:(LiveConnectClientCore *)liveClient;

// The destination path to where the file will be saved after downloading
@property (nonatomic, strong, readonly) NSString *destinationDownloadPath;

// The destination path to where the file will be saved after downloading
@property (nonatomic, assign, readonly) unsigned long long downloadedBytes;

// The expected content length. If there's no Content-Length specified, this could be -1
@property (nonatomic, assign, readonly) long long expectedContentLength;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,25 @@
#import "LiveDownloadOperationInternal.h"
#import "LiveOperationInternal.h"
#import "LiveOperationProgress.h"
#import "LiveConstants.h"

@class LiveDownloadOperation;

@interface LiveDownloadOperationCore ()
{
unsigned long long _downloadedBytes;
long long _expectedContentLength;
}

@property (nonatomic, strong, readwrite) NSString *destinationDownloadPath;
@property (nonatomic, strong) NSFileHandle *outputFileHandle;

@end

@implementation LiveDownloadOperationCore

- (id) initWithPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate
userState:(id)userState
liveClient:(LiveConnectClientCore *)liveClient
Expand All @@ -40,14 +53,56 @@ - (id) initWithPath:(NSString *)path
liveClient:liveClient];
if (self)
{
contentLength = 0;
self.destinationDownloadPath = destinationPath;
}

return self;
}

- (unsigned long long)downloadedBytes
{
return _downloadedBytes;
}

- (long long)expectedContentLength
{
return _expectedContentLength;
}

#pragma mark override methods

- (void)execute
{
NSError *fileTruncationError = nil;

[[[NSData alloc] init] writeToFile:self.destinationDownloadPath options:0 error:&fileTruncationError];

if (fileTruncationError)
{
[self operationFailed:fileTruncationError];
}
else
{
self.outputFileHandle = [NSFileHandle fileHandleForWritingAtPath:self.destinationDownloadPath];

_downloadedBytes = 0;
_expectedContentLength = 0;

[super execute];
}
}

- (void)cancel
{
[super cancel];

if (self.outputFileHandle)
{
[self.outputFileHandle closeFile];
self.outputFileHandle = nil;
}
}

- (NSURL *)requestUrl
{
// We don't use suppress_redirects for download, since redirect maybe expected.
Expand All @@ -67,6 +122,9 @@ - (void) operationCompleted
return;
}

[self.outputFileHandle closeFile];
self.outputFileHandle = nil;

if (self.httpError)
{
// If there is httpError, try read the error information from the server.
Expand All @@ -83,7 +141,7 @@ - (void) operationCompleted
}
else
{
if ([self.delegate respondsToSelector:@selector(liveOperationSucceeded:)])
if ([self.delegate respondsToSelector:@selector(liveOperationSucceeded:)])
{
[self.delegate liveOperationSucceeded:self.publicOperation];
}
Expand All @@ -99,24 +157,65 @@ - (void) operationCompleted

- (void) operationReceivedData:(NSData *)data
{
[self.responseData appendData:data];
@try
{
[self.outputFileHandle writeData:data];
}
@catch (NSException *exception)
{
[self cancel];

NSMutableDictionary *userInfo = [exception.userInfo mutableCopy];
userInfo[NSLocalizedFailureReasonErrorKey] = exception.reason;

NSError *error = [NSError errorWithDomain:LIVE_ERROR_DOMAIN
code:0
userInfo:userInfo];
[self operationFailed:error];

return;
}
@finally
{

}

_downloadedBytes += (unsigned long long)data.length;

if ([self.delegate respondsToSelector:@selector(liveDownloadOperationProgressed:data:operation:)])
if ([self.delegate respondsToSelector:@selector(liveDownloadOperationProgressed:operation:)])
{
if (contentLength == 0)
if (_expectedContentLength == 0)
{
contentLength = [[self.httpResponse.allHeaderFields valueForKey:@"Content-Length"] intValue];
NSString *field = [self.httpResponse.allHeaderFields valueForKey:@"Content-Length"];
if (field)
{
_expectedContentLength = [field longLongValue];
}
else
{
_expectedContentLength = -1ULL;
}
}

LiveOperationProgress *progress = [[[LiveOperationProgress alloc]
initWithBytesTransferred:self.responseData.length
totalBytes:contentLength]
initWithBytesTransferred:(NSUInteger)_downloadedBytes
totalBytes:(NSUInteger)_expectedContentLength]
autorelease];

[self.delegate liveDownloadOperationProgressed:progress
data:data
[self.delegate liveDownloadOperationProgressed:progress
operation:self.publicOperation];
}
}

- (void) operationFailed:(NSError *)error
{
if (!self.completed && self.outputFileHandle)
{
[self.outputFileHandle closeFile];
self.outputFileHandle = nil;
}

[super operationFailed:error];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,11 @@
// when a LiveDownloadOperationDelegate protocol method is invoked.

- (LiveDownloadOperation *) downloadFromPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate;

- (LiveDownloadOperation *) downloadFromPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate
userState:(id)userState;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,12 +482,14 @@ - (LiveOperation *) copyFromPath:(NSString *)path
}

- (LiveDownloadOperation *) downloadFromPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate
{
return [self downloadFromPath:path delegate:delegate userState:nil];
return [self downloadFromPath:path destinationPath:destinationPath delegate:delegate userState:nil];
}

- (LiveDownloadOperation *) downloadFromPath:(NSString *)path
destinationPath:(NSString *)destinationPath
delegate:(id <LiveDownloadOperationDelegate>)delegate
userState:(id)userState
{
Expand All @@ -497,7 +499,8 @@ - (LiveDownloadOperation *) downloadFromPath:(NSString *)path
relative:NO];


return [_liveClientCore downloadFromPath:path
return [_liveClientCore downloadFromPath:path
destinationPath:destinationPath
delegate:delegate
userState:userState];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,16 @@
// LiveDownloadOperation class represents an operation of downloading a file from the user's SkyDrive account.
@interface LiveDownloadOperation : LiveOperation

// The NSData instance that contains the downloaded data.
@property (nonatomic, readonly) NSData *data;
// The path to the temporary file where we are downloading to, which can be used to track progress
@property (nonatomic, strong, readonly) NSString *temporaryPath;

// The destination path to where the file will be saved after downloading
@property (nonatomic, strong, readonly) NSString *destinationDownloadPath;

// The destination path to where the file will be saved after downloading
@property (nonatomic, assign, readonly) unsigned long long downloadedBytes;

// The expected content length. If there's no Content-Length specified, this could be -1
@property (nonatomic, assign, readonly) long long expectedContentLength;

@end
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,28 @@

@implementation LiveDownloadOperation

@synthesize data;

- (id) initWithOpCore:(LiveDownloadOperationCore *)opCore
- (id)initWithOpCore:(LiveDownloadOperationCore *)opCore
{
return [super initWithOpCore:opCore];
}

- (NSData *)data
- (NSString *)destinationDownloadPath
{
return ((LiveDownloadOperationCore*)self.liveOpCore).destinationDownloadPath;
}

- (unsigned long long)downloadedBytes
{
return ((LiveDownloadOperationCore*)self.liveOpCore).downloadedBytes;
}

- (long long)expectedContentLength
{
return self.liveOpCore.responseData;
return ((LiveDownloadOperationCore*)self.liveOpCore).expectedContentLength;
}

- (void)dealloc
{
[data release];

[super dealloc];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@

// This is invoked when there is a download progress event raised.
- (void) liveDownloadOperationProgressed:(LiveOperationProgress *)progress
data:(NSData *)receivedData
operation:(LiveDownloadOperation *)operation;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,12 @@ - (IBAction)onClickDownloadButton:(id)sender
{
@try
{
[self.liveClient downloadFromPath:self.pathTextField.text
delegate:self
NSString *tempPath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", [[NSProcessInfo processInfo] globallyUniqueString]]];

[self.liveClient downloadFromPath:self.pathTextField.text
destinationPath:tempPath
overwrite:YES
delegate:self
userState:@"download"];
}
@catch (id ex)
Expand Down Expand Up @@ -399,7 +403,7 @@ - (void) liveOperationSucceeded:(LiveOperation *)operation
if ([operation.userState isEqual:@"download"])
{
LiveDownloadOperation *downloadOp = (LiveDownloadOperation *)operation;
self.imgView.image = [UIImage imageWithData:downloadOp.data];
self.imgView.image = [UIImage imageWithContentsOfFile:downloadOp.destinationDownloadPath];

}
}
Expand Down

0 comments on commit f871544

Please sign in to comment.