@kesha-antonov/react-native-background-downloader 3.0.3 → 3.1.1
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/android/build.gradle +2 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/eko/RNBackgroundDownloaderModule.java +35 -71
- package/ios/RNBGDTaskConfig.h +21 -11
- package/ios/RNBackgroundDownloader.m +21 -13
- package/package.json +1 -1
- package/react-native-background-downloader.podspec +1 -0
package/android/build.gradle
CHANGED
|
@@ -23,36 +23,29 @@ import java.io.File;
|
|
|
23
23
|
import java.io.FileInputStream;
|
|
24
24
|
import java.io.FileOutputStream;
|
|
25
25
|
import java.io.IOException;
|
|
26
|
-
import java.io.ObjectInputStream;
|
|
27
|
-
import java.io.ObjectOutputStream;
|
|
28
26
|
import java.nio.channels.FileChannel;
|
|
29
27
|
import java.util.Date;
|
|
30
28
|
import java.util.HashMap;
|
|
31
29
|
import java.util.List;
|
|
32
30
|
import java.util.Map;
|
|
33
|
-
import java.util.Scanner;
|
|
34
31
|
|
|
35
32
|
import javax.annotation.Nullable;
|
|
36
33
|
|
|
37
|
-
import java.util.Set;
|
|
38
|
-
import java.net.URL;
|
|
39
|
-
import java.net.URLConnection;
|
|
40
|
-
|
|
41
34
|
import android.content.BroadcastReceiver;
|
|
42
35
|
import android.content.Context;
|
|
43
36
|
import android.content.Intent;
|
|
44
37
|
import android.content.IntentFilter;
|
|
45
|
-
import android.util.LongSparseArray;
|
|
46
|
-
|
|
47
|
-
import com.facebook.react.bridge.Callback;
|
|
48
38
|
|
|
49
|
-
import java.util.ArrayList;
|
|
50
|
-
import java.util.Arrays;
|
|
51
39
|
import android.net.Uri;
|
|
52
40
|
import android.webkit.MimeTypeMap;
|
|
53
41
|
import android.database.Cursor;
|
|
54
42
|
import android.os.Build;
|
|
55
|
-
|
|
43
|
+
// TOREMOVE
|
|
44
|
+
// import android.os.Environment;
|
|
45
|
+
|
|
46
|
+
import com.tencent.mmkv.MMKV;
|
|
47
|
+
import com.google.gson.Gson;
|
|
48
|
+
import com.google.gson.reflect.TypeToken;
|
|
56
49
|
|
|
57
50
|
public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|
58
51
|
|
|
@@ -90,11 +83,12 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|
|
90
83
|
|
|
91
84
|
private static Object sharedLock = new Object();
|
|
92
85
|
|
|
93
|
-
private static void
|
|
86
|
+
private static void moveFile(File src, File dst) throws IOException {
|
|
94
87
|
FileChannel inChannel = new FileInputStream(src).getChannel();
|
|
95
88
|
FileChannel outChannel = new FileOutputStream(dst).getChannel();
|
|
96
89
|
try {
|
|
97
90
|
inChannel.transferTo(0, inChannel.size(), outChannel);
|
|
91
|
+
src.delete();
|
|
98
92
|
} finally {
|
|
99
93
|
if (inChannel != null)
|
|
100
94
|
inChannel.close();
|
|
@@ -103,6 +97,8 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|
|
103
97
|
}
|
|
104
98
|
}
|
|
105
99
|
|
|
100
|
+
private static MMKV mmkv;
|
|
101
|
+
|
|
106
102
|
BroadcastReceiver downloadReceiver = new BroadcastReceiver() {
|
|
107
103
|
@Override
|
|
108
104
|
public void onReceive(Context context, Intent intent) {
|
|
@@ -137,7 +133,7 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|
|
137
133
|
}
|
|
138
134
|
|
|
139
135
|
// MOVE FILE
|
|
140
|
-
|
|
136
|
+
moveFile(file, dest);
|
|
141
137
|
file.delete();
|
|
142
138
|
|
|
143
139
|
WritableMap params = Arguments.createMap();
|
|
@@ -173,6 +169,10 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|
|
173
169
|
public RNBackgroundDownloaderModule(ReactApplicationContext reactContext) {
|
|
174
170
|
super(reactContext);
|
|
175
171
|
|
|
172
|
+
MMKV.initialize(reactContext);
|
|
173
|
+
|
|
174
|
+
mmkv = MMKV.mmkvWithID(getName());
|
|
175
|
+
|
|
176
176
|
loadDownloadIdToConfigMap();
|
|
177
177
|
loadConfigMap();
|
|
178
178
|
|
|
@@ -269,25 +269,26 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|
|
269
269
|
|
|
270
270
|
private void saveDownloadIdToConfigMap() {
|
|
271
271
|
synchronized (sharedLock) {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
outputStream.flush();
|
|
277
|
-
outputStream.close();
|
|
278
|
-
} catch (IOException e) {
|
|
279
|
-
e.printStackTrace();
|
|
280
|
-
}
|
|
272
|
+
Gson gson = new Gson();
|
|
273
|
+
String str = gson.toJson(downloadIdToConfig);
|
|
274
|
+
|
|
275
|
+
mmkv.encode(getName() + "_downloadIdToConfig", str);
|
|
281
276
|
}
|
|
282
277
|
}
|
|
283
278
|
|
|
284
279
|
private void loadDownloadIdToConfigMap() {
|
|
285
|
-
|
|
286
|
-
if (file.exists()) {
|
|
280
|
+
synchronized (sharedLock) {
|
|
287
281
|
try {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
282
|
+
String str = mmkv.decodeString(getName() + "_downloadIdToConfig");
|
|
283
|
+
if (str != null) {
|
|
284
|
+
Gson gson = new Gson();
|
|
285
|
+
|
|
286
|
+
TypeToken<Map<Long, RNBGDTaskConfig>> mapType = new TypeToken<Map<Long, RNBGDTaskConfig>>() {
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
downloadIdToConfig = (Map<Long, RNBGDTaskConfig>) gson.fromJson(str, mapType);
|
|
290
|
+
}
|
|
291
|
+
} catch (Exception e) {
|
|
291
292
|
e.printStackTrace();
|
|
292
293
|
}
|
|
293
294
|
}
|
|
@@ -295,52 +296,15 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule {
|
|
|
295
296
|
|
|
296
297
|
private void saveConfigMap() {
|
|
297
298
|
synchronized (sharedLock) {
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
|
|
301
|
-
|
|
302
|
-
Map<String, String> config = new HashMap<>();
|
|
303
|
-
config.put("progressInterval", Integer.toString(progressInterval));
|
|
304
|
-
outputStream.writeObject(config);
|
|
305
|
-
outputStream.flush();
|
|
306
|
-
outputStream.close();
|
|
307
|
-
} catch (IOException e) {
|
|
308
|
-
e.printStackTrace();
|
|
309
|
-
}
|
|
299
|
+
mmkv.encode(getName() + "_progressInterval", progressInterval);
|
|
310
300
|
}
|
|
311
301
|
}
|
|
312
302
|
|
|
313
303
|
private void loadConfigMap() {
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
Map<String, Object> config = (HashMap<String, Object>) inputStream.readObject();
|
|
319
|
-
// iterate over config
|
|
320
|
-
for (Map.Entry<String, Object> entry : config.entrySet()) {
|
|
321
|
-
String key = entry.getKey();
|
|
322
|
-
|
|
323
|
-
Object valueObj = entry.getValue();
|
|
324
|
-
String value = null;
|
|
325
|
-
if (valueObj instanceof Long) {
|
|
326
|
-
value = Long.toString((Long) valueObj);
|
|
327
|
-
} else if (valueObj instanceof String) {
|
|
328
|
-
value = (String) valueObj;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
if (key.equals("progressInterval") && value != null) {
|
|
332
|
-
try {
|
|
333
|
-
int _progressInterval = Integer.parseInt(value);
|
|
334
|
-
if (_progressInterval > 0) {
|
|
335
|
-
progressInterval = _progressInterval;
|
|
336
|
-
}
|
|
337
|
-
} catch (NumberFormatException e) {
|
|
338
|
-
e.printStackTrace();
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
} catch (IOException | ClassNotFoundException e) {
|
|
343
|
-
e.printStackTrace();
|
|
304
|
+
synchronized (sharedLock) {
|
|
305
|
+
int _progressInterval = mmkv.decodeInt(getName() + "_progressInterval");
|
|
306
|
+
if (_progressInterval > 0) {
|
|
307
|
+
progressInterval = _progressInterval;
|
|
344
308
|
}
|
|
345
309
|
}
|
|
346
310
|
}
|
package/ios/RNBGDTaskConfig.h
CHANGED
|
@@ -8,22 +8,24 @@
|
|
|
8
8
|
|
|
9
9
|
#import <Foundation/Foundation.h>
|
|
10
10
|
|
|
11
|
-
@interface RNBGDTaskConfig : NSObject <NSCoding>
|
|
11
|
+
@interface RNBGDTaskConfig : NSObject <NSCoding, NSSecureCoding>
|
|
12
12
|
|
|
13
|
-
@property NSString *
|
|
14
|
-
@property NSString *
|
|
15
|
-
@property NSString *
|
|
13
|
+
@property NSString *_Nonnull id;
|
|
14
|
+
@property NSString *_Nonnull destination;
|
|
15
|
+
@property NSString *_Nonnull metadata;
|
|
16
16
|
@property BOOL reportedBegin;
|
|
17
17
|
|
|
18
|
-
- (id _Nullable
|
|
18
|
+
- (id _Nullable)initWithDictionary:(NSDictionary *_Nonnull)dict;
|
|
19
19
|
|
|
20
20
|
@end
|
|
21
21
|
|
|
22
22
|
@implementation RNBGDTaskConfig
|
|
23
23
|
|
|
24
|
-
- (id _Nullable
|
|
24
|
+
- (id _Nullable)initWithDictionary:(NSDictionary *_Nonnull)dict
|
|
25
|
+
{
|
|
25
26
|
self = [super init];
|
|
26
|
-
if (self)
|
|
27
|
+
if (self)
|
|
28
|
+
{
|
|
27
29
|
self.id = dict[@"id"];
|
|
28
30
|
self.destination = dict[@"destination"];
|
|
29
31
|
self.metadata = dict[@"metadata"];
|
|
@@ -33,21 +35,24 @@
|
|
|
33
35
|
return self;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder
|
|
38
|
+
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder
|
|
39
|
+
{
|
|
37
40
|
[aCoder encodeObject:self.id forKey:@"id"];
|
|
38
41
|
[aCoder encodeObject:self.destination forKey:@"destination"];
|
|
39
42
|
[aCoder encodeObject:self.metadata forKey:@"metadata"];
|
|
40
43
|
[aCoder encodeBool:self.reportedBegin forKey:@"reportedBegin"];
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder
|
|
46
|
+
- (nullable instancetype)initWithCoder:(nonnull NSCoder *)aDecoder
|
|
47
|
+
{
|
|
44
48
|
self = [super init];
|
|
45
|
-
if (self)
|
|
49
|
+
if (self)
|
|
50
|
+
{
|
|
46
51
|
self.id = [aDecoder decodeObjectForKey:@"id"];
|
|
47
52
|
self.destination = [aDecoder decodeObjectForKey:@"destination"];
|
|
48
53
|
|
|
49
54
|
// metadata CAN BE nil AFTER UPGRADE FROM VERSION WHERE WAS NO PROP "metadata"
|
|
50
|
-
NSString *
|
|
55
|
+
NSString *metadata = [aDecoder decodeObjectForKey:@"metadata"];
|
|
51
56
|
if (metadata == nil)
|
|
52
57
|
metadata = @"{}";
|
|
53
58
|
self.metadata = metadata;
|
|
@@ -58,4 +63,9 @@
|
|
|
58
63
|
return self;
|
|
59
64
|
}
|
|
60
65
|
|
|
66
|
+
+ (BOOL)supportsSecureCoding
|
|
67
|
+
{
|
|
68
|
+
return YES;
|
|
69
|
+
}
|
|
70
|
+
|
|
61
71
|
@end
|
|
@@ -8,9 +8,10 @@
|
|
|
8
8
|
//
|
|
9
9
|
#import "RNBackgroundDownloader.h"
|
|
10
10
|
#import "RNBGDTaskConfig.h"
|
|
11
|
+
#import <MMKV/MMKV.h>
|
|
11
12
|
|
|
12
13
|
#define ID_TO_CONFIG_MAP_KEY @"com.eko.bgdownloadidmap"
|
|
13
|
-
#define
|
|
14
|
+
#define PROGRESS_INTERVAL_KEY @"progressInterval"
|
|
14
15
|
|
|
15
16
|
static CompletionHandler storedCompletionHandler;
|
|
16
17
|
|
|
@@ -26,6 +27,8 @@ static CompletionHandler storedCompletionHandler;
|
|
|
26
27
|
NSNumber *sharedLock;
|
|
27
28
|
float progressInterval; // IN SECONDS
|
|
28
29
|
BOOL isNotificationCenterInited;
|
|
30
|
+
|
|
31
|
+
MMKV *mmkv;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
RCT_EXPORT_MODULE();
|
|
@@ -64,18 +67,24 @@ RCT_EXPORT_MODULE();
|
|
|
64
67
|
NSLog(@"[RNBackgroundDownloader] - [init]");
|
|
65
68
|
self = [super init];
|
|
66
69
|
if (self) {
|
|
67
|
-
|
|
70
|
+
[MMKV initializeMMKV:nil];
|
|
71
|
+
|
|
72
|
+
mmkv = [MMKV mmkvWithID:@"RNBackgroundDownloader"];
|
|
73
|
+
|
|
74
|
+
NSData *taskToConfigMapData = [mmkv getDataForKey:ID_TO_CONFIG_MAP_KEY];
|
|
75
|
+
if (taskToConfigMapData != nil) {
|
|
76
|
+
NSMutableDictionary *_taskToConfigMap = [self deserialize:taskToConfigMapData];
|
|
77
|
+
if (_taskToConfigMap != nil) {
|
|
78
|
+
taskToConfigMap = _taskToConfigMap;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
68
81
|
if (taskToConfigMap == nil) {
|
|
69
82
|
taskToConfigMap = [[NSMutableDictionary alloc] init];
|
|
70
83
|
}
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
if ([key isEqual: @"progressInterval"]) {
|
|
76
|
-
progressInterval = [configMap[key] intValue];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
85
|
+
float _progressInterval = [mmkv getFloatForKey:PROGRESS_INTERVAL_KEY];
|
|
86
|
+
if (_progressInterval) {
|
|
87
|
+
progressInterval = _progressInterval;
|
|
79
88
|
}
|
|
80
89
|
if (isnan(progressInterval)) {
|
|
81
90
|
progressInterval = 1.0;
|
|
@@ -165,7 +174,7 @@ RCT_EXPORT_MODULE();
|
|
|
165
174
|
RNBGDTaskConfig *taskConfig = taskToConfigMap[taskId];
|
|
166
175
|
|
|
167
176
|
[taskToConfigMap removeObjectForKey:taskId];
|
|
168
|
-
[
|
|
177
|
+
[mmkv setData:[self serialize: taskToConfigMap] forKey:ID_TO_CONFIG_MAP_KEY];
|
|
169
178
|
|
|
170
179
|
if (taskConfig) {
|
|
171
180
|
[self->idToTaskMap removeObjectForKey:taskConfig.id];
|
|
@@ -224,8 +233,7 @@ RCT_EXPORT_METHOD(download: (NSDictionary *) options) {
|
|
|
224
233
|
if (_progressInterval) {
|
|
225
234
|
progressInterval = [_progressInterval intValue] / 1000; // progressInterval IN options SUPPLIED IN MILLISECONDS
|
|
226
235
|
|
|
227
|
-
|
|
228
|
-
[[NSUserDefaults standardUserDefaults] setObject:[self serialize: configMap] forKey:CONFIG_MAP_KEY];
|
|
236
|
+
[mmkv setFloat:progressInterval forKey:PROGRESS_INTERVAL_KEY];
|
|
229
237
|
}
|
|
230
238
|
|
|
231
239
|
|
|
@@ -253,7 +261,7 @@ RCT_EXPORT_METHOD(download: (NSDictionary *) options) {
|
|
|
253
261
|
RNBGDTaskConfig *taskConfig = [[RNBGDTaskConfig alloc] initWithDictionary: @{@"id": identifier, @"destination": destination, @"metadata": metadata}];
|
|
254
262
|
|
|
255
263
|
taskToConfigMap[@(task.taskIdentifier)] = taskConfig;
|
|
256
|
-
[
|
|
264
|
+
[mmkv setData:[self serialize: taskToConfigMap] forKey:ID_TO_CONFIG_MAP_KEY];
|
|
257
265
|
|
|
258
266
|
self->idToTaskMap[identifier] = task;
|
|
259
267
|
idToPercentMap[identifier] = @0.0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kesha-antonov/react-native-background-downloader",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.1",
|
|
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",
|