forked from itinance/react-native-fs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Downloader.m
114 lines (88 loc) · 4.05 KB
/
Downloader.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#import "Downloader.h"
@implementation DownloadParams
@end
@interface Downloader()
@property (copy) DownloadParams* params;
@property (retain) NSURLSession* session;
@property (retain) NSURLSessionTask* task;
@property (retain) NSNumber* statusCode;
@property (retain) NSNumber* lastProgressValue;
@property (retain) NSNumber* contentLength;
@property (retain) NSNumber* bytesWritten;
@property (retain) NSFileHandle* fileHandle;
@end
@implementation Downloader
- (void)downloadFile:(DownloadParams*)params
{
_params = params;
_bytesWritten = 0;
NSURL* url = [NSURL URLWithString:_params.fromUrl];
[[NSFileManager defaultManager] createFileAtPath:_params.toFile contents:nil attributes:nil];
_fileHandle = [NSFileHandle fileHandleForWritingAtPath:_params.toFile];
if (!_fileHandle) {
NSError* error = [NSError errorWithDomain:@"Downloader" code:NSURLErrorFileDoesNotExist
userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"Failed to create target file at path: %@", _params.toFile]}];
return _params.errorCallback(error);
} else {
[_fileHandle closeFile];
}
NSURLSessionConfiguration *config;
if (_params.background) {
NSString *uuid = [[NSUUID UUID] UUIDString];
config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:uuid];
} else {
config = [NSURLSessionConfiguration defaultSessionConfiguration];
}
config.HTTPAdditionalHeaders = _params.headers;
_session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
_task = [_session downloadTaskWithURL:url];
[_task resume];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)downloadTask.response;
if (!_statusCode) {
_statusCode = [NSNumber numberWithLong:httpResponse.statusCode];
_contentLength = [NSNumber numberWithLong:httpResponse.expectedContentLength];
return _params.beginCallback(_statusCode, _contentLength, httpResponse.allHeaderFields);
}
if ([_statusCode isEqualToNumber:[NSNumber numberWithInt:200]]) {
_bytesWritten = @(totalBytesWritten);
if (_params.progressDivider <= 1) {
return _params.progressCallback(_contentLength, _bytesWritten);
} else {
double doubleBytesWritten = (double)[_bytesWritten longValue];
double doubleContentLength = (double)[_contentLength longValue];
double doublePercents = doubleBytesWritten / doubleContentLength * 100;
NSNumber* progress = [NSNumber numberWithUnsignedInt: floor(doublePercents)];
if ([progress unsignedIntValue] % [_params.progressDivider integerValue] == 0) {
if (([progress unsignedIntValue] != [_lastProgressValue unsignedIntValue]) || ([_bytesWritten unsignedIntegerValue] == [_contentLength longValue])) {
NSLog(@"---Progress callback EMIT--- %zu", [progress unsignedIntValue]);
_lastProgressValue = [NSNumber numberWithUnsignedInt:[progress unsignedIntValue]];
return _params.progressCallback(_contentLength, _bytesWritten);
}
}
}
}
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSURL *destURL = [NSURL fileURLWithPath:_params.toFile];
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
[fm removeItemAtURL:destURL error:nil]; // Remove file at destination path, if it exists
[fm moveItemAtURL:location toURL:destURL error:&error];
if (error) {
NSLog(@"RNFS download: unable to move tempfile to destination. %@, %@", error, error.userInfo);
}
return _params.completeCallback(_statusCode, _bytesWritten);
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionTask *)downloadTask didCompleteWithError:(NSError *)error
{
return _params.errorCallback(error);
}
- (void)stopDownload
{
[_task cancel];
}
@end