@kesha-antonov/react-native-background-downloader 2.10.0 → 3.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -60
- package/android/build.gradle +0 -9
- package/android/src/main/AndroidManifest.xml +0 -1
- package/android/src/main/java/com/eko/Downloader.java +157 -0
- package/android/src/main/java/com/eko/OnBegin.java +49 -0
- package/android/src/main/java/com/eko/OnProgress.java +132 -0
- package/android/src/main/java/com/eko/RNBGDTaskConfig.java +3 -1
- package/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java +297 -301
- package/index.d.ts +8 -22
- package/index.ts +37 -28
- package/ios/RNBackgroundDownloader.h +1 -1
- package/ios/RNBackgroundDownloader.m +8 -8
- package/lib/DownloadTask.ts +8 -8
- package/package.json +1 -1
package/index.d.ts
CHANGED
|
@@ -16,8 +16,8 @@ export interface TaskInfoObject {
|
|
|
16
16
|
metadata: object | string;
|
|
17
17
|
|
|
18
18
|
percent?: number;
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
bytesDownloaded?: number;
|
|
20
|
+
bytesTotal?: number;
|
|
21
21
|
|
|
22
22
|
beginHandler?: Function;
|
|
23
23
|
progressHandler?: Function;
|
|
@@ -37,8 +37,8 @@ export type BeginHandler = ({
|
|
|
37
37
|
}: BeginHandlerObject) => any;
|
|
38
38
|
export type ProgressHandler = (
|
|
39
39
|
percent: number,
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
bytesDownloaded: number,
|
|
41
|
+
bytesTotal: number
|
|
42
42
|
) => any;
|
|
43
43
|
export type DoneHandler = () => any;
|
|
44
44
|
export type ErrorHandler = (error: any, errorCode: any) => any;
|
|
@@ -55,8 +55,8 @@ export interface DownloadTask {
|
|
|
55
55
|
id: string;
|
|
56
56
|
state: DownloadTaskState;
|
|
57
57
|
percent: number;
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
bytesDownloaded: number;
|
|
59
|
+
bytesTotal: number;
|
|
60
60
|
|
|
61
61
|
begin: (handler: BeginHandler) => DownloadTask;
|
|
62
62
|
progress: (handler: ProgressHandler) => DownloadTask;
|
|
@@ -77,7 +77,6 @@ export type CheckForExistingDownloads = () => Promise<DownloadTask[]>;
|
|
|
77
77
|
export type EnsureDownloadsAreRunning = () => Promise<void>;
|
|
78
78
|
|
|
79
79
|
export interface InitDownloaderOptions {
|
|
80
|
-
type?: 'parallel' | 'sequential' | null;
|
|
81
80
|
}
|
|
82
81
|
export type InitDownloader = (options: InitDownloaderOptions) => undefined;
|
|
83
82
|
|
|
@@ -87,6 +86,8 @@ export interface DownloadOption {
|
|
|
87
86
|
destination: string;
|
|
88
87
|
headers?: DownloadHeaders | undefined;
|
|
89
88
|
metadata?: object;
|
|
89
|
+
isAllowedOverRoaming?: boolean;
|
|
90
|
+
isAllowedOverMetered?: boolean;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
export type Download = (options: DownloadOption) => DownloadTask;
|
|
@@ -96,17 +97,6 @@ export interface Directories {
|
|
|
96
97
|
documents: string;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
export interface Network {
|
|
100
|
-
WIFI_ONLY: string;
|
|
101
|
-
ALL: string;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
export interface Priority {
|
|
105
|
-
HIGH: string;
|
|
106
|
-
MEDIUM: string;
|
|
107
|
-
LOW: string;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
100
|
export const setHeaders: SetHeaders;
|
|
111
101
|
export const checkForExistingDownloads: CheckForExistingDownloads;
|
|
112
102
|
export const ensureDownloadsAreRunning: EnsureDownloadsAreRunning;
|
|
@@ -114,8 +104,6 @@ export const initDownloader: InitDownloader;
|
|
|
114
104
|
export const download: Download;
|
|
115
105
|
export const completeHandler: CompleteHandler;
|
|
116
106
|
export const directories: Directories;
|
|
117
|
-
export const Network: Network;
|
|
118
|
-
export const Priority: Priority;
|
|
119
107
|
|
|
120
108
|
export interface RNBackgroundDownloader {
|
|
121
109
|
setHeaders: SetHeaders;
|
|
@@ -125,8 +113,6 @@ export interface RNBackgroundDownloader {
|
|
|
125
113
|
download: Download;
|
|
126
114
|
completeHandler: CompleteHandler;
|
|
127
115
|
directories: Directories;
|
|
128
|
-
Network: Network;
|
|
129
|
-
Priority: Priority;
|
|
130
116
|
}
|
|
131
117
|
|
|
132
118
|
declare const RNBackgroundDownloader: RNBackgroundDownloader;
|
package/index.ts
CHANGED
|
@@ -7,14 +7,23 @@ const RNBackgroundDownloaderEmitter = new NativeEventEmitter(RNBackgroundDownloa
|
|
|
7
7
|
const tasksMap = new Map()
|
|
8
8
|
let headers = {}
|
|
9
9
|
|
|
10
|
+
RNBackgroundDownloaderEmitter.addListener('downloadBegin', ({ id, expectedBytes, headers }) => {
|
|
11
|
+
console.log('[RNBackgroundDownloader] downloadBegin', id, expectedBytes, headers)
|
|
12
|
+
const task = tasksMap.get(id)
|
|
13
|
+
task?.onBegin({ expectedBytes, headers })
|
|
14
|
+
})
|
|
15
|
+
|
|
10
16
|
RNBackgroundDownloaderEmitter.addListener('downloadProgress', events => {
|
|
17
|
+
// console.log('[RNBackgroundDownloader] downloadProgress-1', events, tasksMap)
|
|
11
18
|
for (const event of events) {
|
|
12
19
|
const task = tasksMap.get(event.id)
|
|
13
|
-
|
|
20
|
+
// console.log('[RNBackgroundDownloader] downloadProgress-2', event.id, task)
|
|
21
|
+
task?.onProgress(event.percent, event.bytesDownloaded, event.bytesTotal)
|
|
14
22
|
}
|
|
15
23
|
})
|
|
16
24
|
|
|
17
25
|
RNBackgroundDownloaderEmitter.addListener('downloadComplete', ({ id, location }) => {
|
|
26
|
+
console.log('[RNBackgroundDownloader] downloadComplete', id, location)
|
|
18
27
|
const task = tasksMap.get(id)
|
|
19
28
|
task?.onDone({ location })
|
|
20
29
|
|
|
@@ -22,35 +31,34 @@ RNBackgroundDownloaderEmitter.addListener('downloadComplete', ({ id, location })
|
|
|
22
31
|
})
|
|
23
32
|
|
|
24
33
|
RNBackgroundDownloaderEmitter.addListener('downloadFailed', event => {
|
|
34
|
+
console.log('[RNBackgroundDownloader] downloadFailed', event)
|
|
25
35
|
const task = tasksMap.get(event.id)
|
|
26
|
-
task?.onError(event.error, event.
|
|
36
|
+
task?.onError(event.error, event.errorCode)
|
|
27
37
|
|
|
28
38
|
tasksMap.delete(event.id)
|
|
29
39
|
})
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
const task = tasksMap.get(id)
|
|
33
|
-
task?.onBegin({ expectedBytes, headers })
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
export function setHeaders (h = {}) {
|
|
41
|
+
export function setHeaders(h = {}) {
|
|
37
42
|
if (typeof h !== 'object')
|
|
38
43
|
throw new Error('[RNBackgroundDownloader] headers must be an object')
|
|
39
44
|
|
|
40
45
|
headers = h
|
|
41
46
|
}
|
|
42
47
|
|
|
43
|
-
export function initDownloader
|
|
48
|
+
export function initDownloader(options = {}) {
|
|
44
49
|
if (Platform.OS === 'android')
|
|
45
50
|
RNBackgroundDownloader.initDownloader(options)
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
export function checkForExistingDownloads
|
|
53
|
+
export function checkForExistingDownloads() {
|
|
54
|
+
console.log('[RNBackgroundDownloader] checkForExistingDownloads-1')
|
|
49
55
|
return RNBackgroundDownloader.checkForExistingDownloads()
|
|
50
56
|
.then(foundTasks => {
|
|
57
|
+
console.log('[RNBackgroundDownloader] checkForExistingDownloads-2', foundTasks)
|
|
51
58
|
return foundTasks.map(taskInfo => {
|
|
52
59
|
// SECOND ARGUMENT RE-ASSIGNS EVENT HANDLERS
|
|
53
60
|
const task = new DownloadTask(taskInfo, tasksMap.get(taskInfo.id))
|
|
61
|
+
console.log('[RNBackgroundDownloader] checkForExistingDownloads-3', taskInfo)
|
|
54
62
|
|
|
55
63
|
if (taskInfo.state === RNBackgroundDownloader.TaskRunning) {
|
|
56
64
|
task.state = 'DOWNLOADING'
|
|
@@ -60,7 +68,7 @@ export function checkForExistingDownloads () {
|
|
|
60
68
|
task.stop()
|
|
61
69
|
return null
|
|
62
70
|
} else if (taskInfo.state === RNBackgroundDownloader.TaskCompleted) {
|
|
63
|
-
if (taskInfo.
|
|
71
|
+
if (taskInfo.bytesDownloaded === taskInfo.bytesTotal)
|
|
64
72
|
task.state = 'DONE'
|
|
65
73
|
else
|
|
66
74
|
// IOS completed the download but it was not done.
|
|
@@ -68,11 +76,12 @@ export function checkForExistingDownloads () {
|
|
|
68
76
|
}
|
|
69
77
|
tasksMap.set(taskInfo.id, task)
|
|
70
78
|
return task
|
|
71
|
-
}).filter(task => task
|
|
79
|
+
}).filter(task => !!task)
|
|
72
80
|
})
|
|
73
81
|
}
|
|
74
82
|
|
|
75
|
-
export function ensureDownloadsAreRunning
|
|
83
|
+
export function ensureDownloadsAreRunning() {
|
|
84
|
+
console.log('[RNBackgroundDownloader] ensureDownloadsAreRunning')
|
|
76
85
|
return checkForExistingDownloads()
|
|
77
86
|
.then(tasks => {
|
|
78
87
|
for (const task of tasks)
|
|
@@ -83,7 +92,12 @@ export function ensureDownloadsAreRunning () {
|
|
|
83
92
|
})
|
|
84
93
|
}
|
|
85
94
|
|
|
86
|
-
export function completeHandler
|
|
95
|
+
export function completeHandler(jobId: string) {
|
|
96
|
+
if (jobId == null) {
|
|
97
|
+
console.warn('[RNBackgroundDownloader] completeHandler: jobId is empty')
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
87
101
|
return RNBackgroundDownloader.completeHandler(jobId)
|
|
88
102
|
}
|
|
89
103
|
|
|
@@ -93,9 +107,12 @@ type DownloadOptions = {
|
|
|
93
107
|
destination: string,
|
|
94
108
|
headers?: object,
|
|
95
109
|
metadata?: object,
|
|
110
|
+
isAllowedOverRoaming?: boolean,
|
|
111
|
+
isAllowedOverMetered?: boolean,
|
|
96
112
|
}
|
|
97
113
|
|
|
98
|
-
export function download
|
|
114
|
+
export function download(options: DownloadOptions) {
|
|
115
|
+
console.log('[RNBackgroundDownloader] download', options)
|
|
99
116
|
if (!options.id || !options.url || !options.destination)
|
|
100
117
|
throw new Error('[RNBackgroundDownloader] id, url and destination are required')
|
|
101
118
|
|
|
@@ -104,6 +121,11 @@ export function download (options : DownloadOptions) {
|
|
|
104
121
|
if (!(options.metadata && typeof options.metadata === 'object'))
|
|
105
122
|
options.metadata = {}
|
|
106
123
|
|
|
124
|
+
options.destination = options.destination.replace('file://', '')
|
|
125
|
+
|
|
126
|
+
if (options.isAllowedOverRoaming == null) options.isAllowedOverRoaming = true
|
|
127
|
+
if (options.isAllowedOverMetered == null) options.isAllowedOverMetered = true
|
|
128
|
+
|
|
107
129
|
const task = new DownloadTask({
|
|
108
130
|
id: options.id,
|
|
109
131
|
metadata: options.metadata,
|
|
@@ -122,17 +144,6 @@ export const directories = {
|
|
|
122
144
|
documents: RNBackgroundDownloader.documents,
|
|
123
145
|
}
|
|
124
146
|
|
|
125
|
-
export const Network = {
|
|
126
|
-
WIFI_ONLY: RNBackgroundDownloader.OnlyWifi,
|
|
127
|
-
ALL: RNBackgroundDownloader.AllNetworks,
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export const Priority = {
|
|
131
|
-
HIGH: RNBackgroundDownloader.PriorityHigh,
|
|
132
|
-
MEDIUM: RNBackgroundDownloader.PriorityNormal,
|
|
133
|
-
LOW: RNBackgroundDownloader.PriorityLow,
|
|
134
|
-
}
|
|
135
|
-
|
|
136
147
|
export default {
|
|
137
148
|
initDownloader,
|
|
138
149
|
download,
|
|
@@ -141,6 +152,4 @@ export default {
|
|
|
141
152
|
completeHandler,
|
|
142
153
|
setHeaders,
|
|
143
154
|
directories,
|
|
144
|
-
Network,
|
|
145
|
-
Priority,
|
|
146
155
|
}
|
|
@@ -19,6 +19,6 @@ typedef void (^CompletionHandler)();
|
|
|
19
19
|
|
|
20
20
|
@interface RNBackgroundDownloader : RCTEventEmitter <RCTBridgeModule, NSURLSessionDelegate, NSURLSessionDownloadDelegate>
|
|
21
21
|
|
|
22
|
-
+ (void)setCompletionHandlerWithIdentifier:
|
|
22
|
+
+ (void)setCompletionHandlerWithIdentifier:(NSString *)identifier completionHandler:(CompletionHandler)completionHandler;
|
|
23
23
|
|
|
24
24
|
@end
|
|
@@ -62,7 +62,7 @@ RCT_EXPORT_MODULE();
|
|
|
62
62
|
taskToConfigMap = [[NSMutableDictionary alloc] init];
|
|
63
63
|
}
|
|
64
64
|
idToTaskMap = [[NSMutableDictionary alloc] init];
|
|
65
|
-
idToResumeDataMap= [[NSMutableDictionary alloc] init];
|
|
65
|
+
idToResumeDataMap = [[NSMutableDictionary alloc] init];
|
|
66
66
|
idToPercentMap = [[NSMutableDictionary alloc] init];
|
|
67
67
|
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
|
|
68
68
|
NSString *sessonIdentifier = [bundleIdentifier stringByAppendingString:@".backgrounddownloadtask"];
|
|
@@ -286,8 +286,8 @@ RCT_EXPORT_METHOD(checkForExistingDownloads: (RCTPromiseResolveBlock)resolve rej
|
|
|
286
286
|
@"id": taskConfig.id,
|
|
287
287
|
@"metadata": taskConfig.metadata,
|
|
288
288
|
@"state": [NSNumber numberWithInt: task.state],
|
|
289
|
-
@"
|
|
290
|
-
@"
|
|
289
|
+
@"bytesDownloaded": [NSNumber numberWithLongLong:task.countOfBytesReceived],
|
|
290
|
+
@"bytesTotal": [NSNumber numberWithLongLong:task.countOfBytesExpectedToReceive],
|
|
291
291
|
@"percent": percent
|
|
292
292
|
}];
|
|
293
293
|
taskConfig.reportedBegin = YES;
|
|
@@ -341,11 +341,11 @@ RCT_EXPORT_METHOD(completeHandler:(nonnull NSString *)jobId
|
|
|
341
341
|
}
|
|
342
342
|
}
|
|
343
343
|
|
|
344
|
-
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset
|
|
344
|
+
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedbytesTotal:(int64_t)expectedbytesTotal {
|
|
345
345
|
NSLog(@"[RNBackgroundDownloader] - [didResumeAtOffset]");
|
|
346
346
|
}
|
|
347
347
|
|
|
348
|
-
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)
|
|
348
|
+
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesDownloaded bytesTotalWritten:(int64_t)bytesTotalWritten bytesTotalExpectedToWrite:(int64_t)bytesTotalExpectedToWrite {
|
|
349
349
|
NSLog(@"[RNBackgroundDownloader] - [didWriteData]");
|
|
350
350
|
@synchronized (sharedLock) {
|
|
351
351
|
RNBGDTaskConfig *taskCofig = taskToConfigMap[@(downloadTask.taskIdentifier)];
|
|
@@ -356,7 +356,7 @@ RCT_EXPORT_METHOD(completeHandler:(nonnull NSString *)jobId
|
|
|
356
356
|
if (self.bridge) {
|
|
357
357
|
[self sendEventWithName:@"downloadBegin" body:@{
|
|
358
358
|
@"id": taskCofig.id,
|
|
359
|
-
@"expectedBytes": [NSNumber numberWithLongLong:
|
|
359
|
+
@"expectedBytes": [NSNumber numberWithLongLong: bytesTotalExpectedToWrite],
|
|
360
360
|
@"headers": responseHeaders
|
|
361
361
|
}];
|
|
362
362
|
}
|
|
@@ -364,9 +364,9 @@ RCT_EXPORT_METHOD(completeHandler:(nonnull NSString *)jobId
|
|
|
364
364
|
}
|
|
365
365
|
|
|
366
366
|
NSNumber *prevPercent = idToPercentMap[taskCofig.id];
|
|
367
|
-
NSNumber *percent = [NSNumber numberWithFloat:(float)
|
|
367
|
+
NSNumber *percent = [NSNumber numberWithFloat:(float)bytesTotalWritten/(float)bytesTotalExpectedToWrite];
|
|
368
368
|
if ([percent floatValue] - [prevPercent floatValue] > 0.01f) {
|
|
369
|
-
progressReports[taskCofig.id] = @{@"id": taskCofig.id, @"
|
|
369
|
+
progressReports[taskCofig.id] = @{@"id": taskCofig.id, @"bytesDownloaded": [NSNumber numberWithLongLong: bytesTotalWritten], @"bytesTotal": [NSNumber numberWithLongLong: bytesTotalExpectedToWrite], @"percent": percent};
|
|
370
370
|
idToPercentMap[taskCofig.id] = percent;
|
|
371
371
|
}
|
|
372
372
|
|
package/lib/DownloadTask.ts
CHANGED
|
@@ -16,14 +16,14 @@ export default class DownloadTask {
|
|
|
16
16
|
metadata = {}
|
|
17
17
|
|
|
18
18
|
percent = 0
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
bytesDownloaded = 0
|
|
20
|
+
bytesTotal = 0
|
|
21
21
|
|
|
22
22
|
constructor (taskInfo: TaskInfo, originalTask?: TaskInfo) {
|
|
23
23
|
this.id = taskInfo.id
|
|
24
24
|
this.percent = taskInfo.percent ?? 0
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
25
|
+
this.bytesDownloaded = taskInfo.bytesDownloaded ?? 0
|
|
26
|
+
this.bytesTotal = taskInfo.bytesTotal ?? 0
|
|
27
27
|
|
|
28
28
|
const metadata = this.tryParseJson(taskInfo.metadata)
|
|
29
29
|
if (metadata)
|
|
@@ -66,11 +66,11 @@ export default class DownloadTask {
|
|
|
66
66
|
this.beginHandler?.({ expectedBytes, headers })
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
onProgress (percent,
|
|
69
|
+
onProgress (percent, bytesDownloaded, bytesTotal) {
|
|
70
70
|
this.percent = percent
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
this.progressHandler?.(percent,
|
|
71
|
+
this.bytesDownloaded = bytesDownloaded
|
|
72
|
+
this.bytesTotal = bytesTotal
|
|
73
|
+
this.progressHandler?.(percent, bytesDownloaded, bytesTotal)
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
onDone ({ location }) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kesha-antonov/react-native-background-downloader",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.0",
|
|
4
4
|
"description": "A library for React-Native to help you download large files on iOS and Android both in the foreground and most importantly in the background.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|