@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.
@@ -24,4 +24,6 @@ android {
24
24
  dependencies {
25
25
  //noinspection GradleDynamicVersion
26
26
  implementation 'com.facebook.react:react-native:+'
27
+ implementation 'com.tencent:mmkv:+'
28
+ implementation 'com.google.code.gson:gson:+'
27
29
  }
@@ -1,4 +1,6 @@
1
1
  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
2
  package="com.eko">
3
3
 
4
+ <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
5
+
4
6
  </manifest>
@@ -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
- import android.os.Environment;
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 copyFile(File src, File dst) throws IOException {
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
- copyFile(file, dest);
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
- File file = new File(this.getReactApplicationContext().getFilesDir(), getName() + "_downloadIdToConfig");
273
- try {
274
- ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream(file));
275
- outputStream.writeObject(downloadIdToConfig);
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
- File file = new File(this.getReactApplicationContext().getFilesDir(), getName() + "_downloadIdToConfig");
286
- if (file.exists()) {
280
+ synchronized (sharedLock) {
287
281
  try {
288
- ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file));
289
- downloadIdToConfig = (Map<Long, RNBGDTaskConfig>) inputStream.readObject();
290
- } catch (IOException | ClassNotFoundException e) {
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
- File file = new File(this.getReactApplicationContext().getFilesDir(), getName() + "_config");
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
- File file = new File(this.getReactApplicationContext().getFilesDir(), getName() + "_config");
315
- if (file.exists()) {
316
- try {
317
- ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(file));
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
  }
@@ -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 * _Nonnull id;
14
- @property NSString * _Nonnull destination;
15
- @property NSString * _Nonnull metadata;
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 )initWithDictionary: (NSDictionary *_Nonnull)dict;
18
+ - (id _Nullable)initWithDictionary:(NSDictionary *_Nonnull)dict;
19
19
 
20
20
  @end
21
21
 
22
22
  @implementation RNBGDTaskConfig
23
23
 
24
- - (id _Nullable )initWithDictionary: (NSDictionary *_Nonnull)dict {
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 * metadata = [aDecoder decodeObjectForKey:@"metadata"];
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 CONFIG_MAP_KEY @"com.eko.config_map"
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
- taskToConfigMap = [self deserialize:[[NSUserDefaults standardUserDefaults] objectForKey:ID_TO_CONFIG_MAP_KEY]];
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
- NSDictionary *configMap = [self deserialize:[[NSUserDefaults standardUserDefaults] objectForKey:CONFIG_MAP_KEY]];
73
- if (configMap != nil) {
74
- for (NSString *key in configMap) {
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
- [[NSUserDefaults standardUserDefaults] setObject:[self serialize: taskToConfigMap] forKey:ID_TO_CONFIG_MAP_KEY];
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
- NSDictionary *configMap = @{@"progressInterval": [NSNumber numberWithFloat:progressInterval]};
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
- [[NSUserDefaults standardUserDefaults] setObject:[self serialize: taskToConfigMap] forKey:ID_TO_CONFIG_MAP_KEY];
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.0.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",
@@ -14,4 +14,5 @@ Pod::Spec.new do |s|
14
14
  s.requires_arc = true
15
15
 
16
16
  s.dependency 'React-Core'
17
+ s.dependency 'MMKV'
17
18
  end