Merge pull request #5 from HyopeR/master

Added Metadata support for DownloadFile.
This commit is contained in:
Kesha Antonov
2022-11-03 12:50:36 +01:00
committed by GitHub
7 changed files with 48 additions and 25 deletions

View File

@@ -92,8 +92,9 @@ const jobId = 'file123'
let task = download({
id: jobId,
url: 'https://link-to-very.large/file.zip'
destination: `${RNBackgroundDownloader.directories.documents}/file.zip`
url: 'https://link-to-very.large/file.zip',
destination: `${RNBackgroundDownloader.directories.documents}/file.zip`,
metadata: {}
}).begin(({ expectedBytes, headers }) => {
console.log(`Going to download ${expectedBytes} bytes!`)
}).progress(percent => {
@@ -195,7 +196,8 @@ An object containing options properties
| `id` | String | ✅ | All | A Unique ID to provide for this download. This ID will help to identify the download task when the app re-launches |
| `url` | String | ✅ | All | URL to file you want to download |
| `destination` | String | ✅ | All | Where to copy the file to once the download is done |
| `headers` | Object | | All | Costume headers to add to the download request. These are merged with the headers given in the `setHeaders` function
| `metadata` | Object | | All | Data to be preserved on reboot. |
| `headers` | Object | | All | Costume headers to add to the download request. These are merged with the headers given in the `setHeaders` function
| `priority` | [Priority (enum)](#priority-enum---android-only) | | Android | The priority of the download. On Android, downloading is limited to 4 simultaneous instances where further downloads are queued. Priority helps in deciding which download to pick next from the queue. **Default:** Priority.MEDIUM |
| `network` | [Network (enum)](#network-enum---android-only) | | Android | Give your the ability to limit the download to WIFI only. **Default:** Network.ALL |
@@ -224,7 +226,8 @@ A class representing a download task created by `RNBackgroundDownloader.download
### `Members`
| Name | Type | Info |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------- |
| `id` | String | The id you gave the task when calling `RNBackgroundDownloader.download` |
| `id` | String | The id you gave the task when calling `RNBackgroundDownloader.download` |
| `metadata` | Object | The metadata you gave the task when calling `RNBackgroundDownloader.download` |
| `percent` | Number | The current percent of completion of the task between 0 and 1 |
| `bytesWritten` | Number | The number of bytes currently written by the task |
| `totalBytes` | Number | The number bytes expected to be written by this task or more plainly, the file size being downloaded |

View File

@@ -4,10 +4,12 @@ import java.io.Serializable;
public class RNBGDTaskConfig implements Serializable {
public String id;
public String metadata;
public boolean reportedBegin;
public RNBGDTaskConfig(String id) {
public RNBGDTaskConfig(String id, String metadata) {
this.id = id;
this.metadata = metadata;
this.reportedBegin = false;
}
}
}

View File

@@ -204,13 +204,14 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule imp
String url = options.getString("url");
String destination = options.getString("destination");
ReadableMap headers = options.getMap("headers");
String metadata = options.getString("metadata");
if (id == null || url == null || destination == null) {
Log.e(getName(), "id, url and destination must be set");
return;
}
RNBGDTaskConfig config = new RNBGDTaskConfig(id);
RNBGDTaskConfig config = new RNBGDTaskConfig(id, metadata);
final Request request = new Request(url, destination);
if (headers != null) {
ReadableMapKeySetIterator it = headers.keySetIterator();
@@ -298,6 +299,7 @@ public class RNBackgroundDownloaderModule extends ReactContextBaseJavaModule imp
RNBGDTaskConfig config = requestIdToConfig.get(download.getId());
WritableMap params = Arguments.createMap();
params.putString("id", config.id);
params.putString("metadata", config.metadata);
params.putInt("state", stateMap.get(download.getStatus()));
params.putInt("bytesWritten", (int)download.getDownloaded());
params.putInt("totalBytes", (int)download.getTotal());

View File

@@ -76,16 +76,16 @@ export function download (options) {
if (!options.id || !options.url || !options.destination)
throw new Error('[RNBackgroundDownloader] id, url and destination are required')
if (options.headers && typeof options.headers === 'object')
options.headers = {
...headers,
...options.headers,
}
else
options.headers = headers
options.headers = options.headers && typeof options.headers === 'object'
? { ...headers, ...options.headers }
: headers
options.metadata = options.metadata && typeof options.metadata === 'object'
? JSON.stringify(options.metadata)
: JSON.stringify({})
RNBackgroundDownloader.download(options)
const task = new DownloadTask(options.id)
const task = new DownloadTask({ id: options.id, metadata: options.metadata})
tasksMap.set(options.id, task)
return task
}

View File

@@ -12,6 +12,7 @@
@property NSString * _Nonnull id;
@property NSString * _Nonnull destination;
@property NSString * _Nonnull metadata;
@property BOOL reportedBegin;
- (id _Nullable )initWithDictionary: (NSDictionary *_Nonnull)dict;
@@ -25,15 +26,17 @@
if (self) {
self.id = dict[@"id"];
self.destination = dict[@"destination"];
self.metadata = dict[@"metadata"];
self.reportedBegin = NO;
}
return self;
}
- (void)encodeWithCoder:(nonnull NSCoder *)aCoder {
[aCoder encodeObject:self.id forKey:@"id"];
[aCoder encodeObject:self.destination forKey:@"destination"];
[aCoder encodeObject:self.metadata forKey:@"metadata"];
[aCoder encodeBool:self.reportedBegin forKey:@"reportedBegin"];
}
@@ -42,9 +45,10 @@
if (self) {
self.id = [aDecoder decodeObjectForKey:@"id"];
self.destination = [aDecoder decodeObjectForKey:@"destination"];
self.metadata = [aDecoder decodeObjectForKey:@"metadata"];
self.reportedBegin = [aDecoder decodeBoolForKey:@"reportedBegin"];
}
return self;
}

View File

@@ -200,6 +200,7 @@ RCT_EXPORT_METHOD(download: (NSDictionary *) options) {
NSString *identifier = options[@"id"];
NSString *url = options[@"url"];
NSString *destination = options[@"destination"];
NSString *metadata = options[@"metadata"];
NSDictionary *headers = options[@"headers"];
if (identifier == nil || url == nil || destination == nil) {
NSLog(@"[RNBackgroundDownloader] - [Error] id, url and destination must be set");
@@ -221,7 +222,7 @@ RCT_EXPORT_METHOD(download: (NSDictionary *) options) {
return;
}
RNBGDTaskConfig *taskConfig = [[RNBGDTaskConfig alloc] initWithDictionary: @{@"id": identifier, @"destination": destination}];
RNBGDTaskConfig *taskConfig = [[RNBGDTaskConfig alloc] initWithDictionary: @{@"id": identifier, @"destination": destination, @"metadata": metadata}];
taskToConfigMap[@(task.taskIdentifier)] = taskConfig;
[[NSUserDefaults standardUserDefaults] setObject:[self serialize: taskToConfigMap] forKey:ID_TO_CONFIG_MAP_KEY];
@@ -286,6 +287,7 @@ RCT_EXPORT_METHOD(checkForExistingDownloads: (RCTPromiseResolveBlock)resolve rej
NSNumber *percent = foundTask.countOfBytesExpectedToReceive > 0 ? [NSNumber numberWithFloat:(float)task.countOfBytesReceived/(float)foundTask.countOfBytesExpectedToReceive] : @0.0;
[idsFound addObject:@{
@"id": taskConfig.id,
@"metadata": taskConfig.metadata,
@"state": [NSNumber numberWithInt: task.state],
@"bytesWritten": [NSNumber numberWithLongLong:task.countOfBytesReceived],
@"totalBytes": [NSNumber numberWithLongLong:foundTask.countOfBytesExpectedToReceive],

View File

@@ -10,15 +10,16 @@ export default class DownloadTask {
percent = 0
bytesWritten = 0
totalBytes = 0
metadata = {}
constructor (taskInfo, originalTask) {
if (typeof taskInfo === 'string') {
this.id = taskInfo
} else {
this.id = taskInfo.id
this.percent = taskInfo.percent
this.bytesWritten = taskInfo.bytesWritten
this.totalBytes = taskInfo.totalBytes
this.id = taskInfo.id
this.percent = taskInfo.percent ?? 0
this.bytesWritten = taskInfo.bytesWritten ?? 0
this.totalBytes = taskInfo.totalBytes ?? 0
if (this.#parseable(taskInfo.metadata)) {
this.metadata = JSON.parse(taskInfo.metadata)
}
if (originalTask) {
@@ -93,4 +94,13 @@ export default class DownloadTask {
this.state = 'STOPPED'
RNBackgroundDownloader.stopTask(this.id)
}
#parseable = (element) => {
try {
JSON.parse(element)
return true
} catch (err) {
return false
}
}
}