Skip to content

Commit 774e330

Browse files
Merge pull request #282 from spoonconsulting/upload-duration-logic-in-plugin
Upload duration logic
2 parents 400edd2 + bbc74f8 commit 774e330

8 files changed

+69
-27
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## [4.1.2](https://github.com/spoonconsulting/cordova-plugin-background-upload/compare/4.1.1...4.1.2) (2024-11-05)
2+
* **android:** Return upload start and end time in upload response
3+
* **iOS:** Return upload start and end time in upload response
4+
15
## [4.1.1](https://github.com/spoonconsulting/cordova-plugin-background-upload/compare/4.1.0...4.1.1) (2024-09-23)
26
* **android:** Update cordova plugin file version to 8.1.0
37
* **iOS:** Update cordova plugin file version to 8.1.0

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@spoonconsulting/cordova-plugin-background-upload",
3-
"version": "4.1.1",
3+
"version": "4.1.2",
44
"description": "Cordova plugin for uploading file in the background",
55
"cordova": {
66
"id": "@spoonconsulting/cordova-plugin-background-upload",

plugin.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="@spoonconsulting/cordova-plugin-background-upload" version="4.1.1">
2+
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="@spoonconsulting/cordova-plugin-background-upload" version="4.1.2">
33
<name>Cordova Background Upload Plugin</name>
44
<description>Background Upload plugin for Cordova</description>
55
<license>ISC</license>

src/android/FileTransferBackground.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.ArrayList;
3333
import java.util.Arrays;
3434
import java.util.Collections;
35+
import java.util.Date;
3536
import java.util.HashMap;
3637
import java.util.Iterator;
3738
import java.util.List;
@@ -81,7 +82,13 @@ private void sendProgress(final String id, int progressPercent) {
8182
}
8283
}
8384

84-
private void sendSuccess(final String id, final String response, int statusCode) {
85+
private void sendSuccess(HashMap<String, Object> uploadData) {
86+
String id = (String) uploadData.get("outputId");
87+
String response = (String) uploadData.get("response");
88+
int statusCode = (int) uploadData.get("statusCode");
89+
long uploadDuration = (long) uploadData.get("uploadDuration");
90+
long finishUploadTime = (long) uploadData.get("finishUploadTime");
91+
8592
if (response != null && !response.isEmpty()) {
8693
logMessage("eventLabel='Uploader onSuccess' uploadId='" + id + "' response='" + response.substring(0, Math.min(2000, response.length() - 1)) + "'");
8794
} else {
@@ -95,6 +102,8 @@ private void sendSuccess(final String id, final String response, int statusCode)
95102
.put("state", "UPLOADED")
96103
.put("serverResponse", response)
97104
.put("statusCode", statusCode)
105+
.put("uploadDuration", uploadDuration)
106+
.put("finishUploadTime", finishUploadTime)
98107
);
99108
} catch (JSONException e) {
100109
// Can't really happen but just in case
@@ -401,26 +410,28 @@ private void acknowledgeEvent(String eventId, CallbackContext context) {
401410
* Handle ACK data and send it to the JS.
402411
*/
403412
private void handleAck(final Data ackData) {
404-
// If upload was successful
405413
if (!ackData.getBoolean(UploadTask.KEY_OUTPUT_IS_ERROR, false)) {
406-
// Read response from file if present
407414
String response = null;
408415
if (ackData.getString(UploadTask.KEY_OUTPUT_RESPONSE_FILE) != null) {
409416
response = readFileToStringNoThrow(ackData.getString(UploadTask.KEY_OUTPUT_RESPONSE_FILE));
410417
}
411418

412-
sendSuccess(
413-
ackData.getString(UploadTask.KEY_OUTPUT_ID),
414-
response,
415-
ackData.getInt(UploadTask.KEY_OUTPUT_STATUS_CODE, -1 /* If this is sent, something is really wrong */)
416-
);
417-
419+
long startUploadTime = ackData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_START_TIME, 0);
420+
long finishUploadTime = ackData.getLong(UploadTask.KEY_OUTPUT_UPLOAD_FINISH_TIME, 0);
421+
long uploadDuration = finishUploadTime - startUploadTime;
422+
423+
HashMap<String, Object> uploadData = new HashMap<>();
424+
uploadData.put("outputId", ackData.getString(UploadTask.KEY_OUTPUT_ID));
425+
uploadData.put("response", response);
426+
uploadData.put("statusCode", ackData.getInt(UploadTask.KEY_OUTPUT_STATUS_CODE, -1));
427+
uploadData.put("uploadDuration", uploadDuration);
428+
uploadData.put("finishUploadTime", finishUploadTime);
429+
sendSuccess(uploadData);
418430
} else {
419-
// The upload was a failure
420431
sendError(
421-
ackData.getString(UploadTask.KEY_OUTPUT_ID),
422-
ackData.getString(UploadTask.KEY_OUTPUT_FAILURE_REASON),
423-
ackData.getBoolean(UploadTask.KEY_OUTPUT_FAILURE_CANCELED, false)
432+
ackData.getString(UploadTask.KEY_OUTPUT_ID),
433+
ackData.getString(UploadTask.KEY_OUTPUT_FAILURE_REASON),
434+
ackData.getBoolean(UploadTask.KEY_OUTPUT_FAILURE_CANCELED, false)
424435
);
425436
}
426437
}

src/android/UploadTask.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public final class UploadTask extends Worker {
7979
public static final String KEY_OUTPUT_STATUS_CODE = "output_status_code";
8080
public static final String KEY_OUTPUT_FAILURE_REASON = "output_failure_reason";
8181
public static final String KEY_OUTPUT_FAILURE_CANCELED = "output_failure_canceled";
82+
public static final String KEY_OUTPUT_UPLOAD_START_TIME = "output_upload_start_time";
83+
public static final String KEY_OUTPUT_UPLOAD_FINISH_TIME = "output_upload_finish_time";
8284
// </editor-fold>
8385

8486
private static UploadNotification uploadNotification = null;
@@ -96,6 +98,8 @@ public void release() { }
9698
private static int concurrency = 1;
9799
private static Semaphore concurrentUploads = new Semaphore(concurrency, true);
98100
private static Mutex concurrencyLock = new Mutex();
101+
long startTime = 0;
102+
long endTime = 0;
99103

100104
public UploadTask(@NonNull Context context, @NonNull WorkerParameters workerParams) {
101105

@@ -189,6 +193,7 @@ public Result doWork() {
189193
return Result.retry();
190194
}
191195

196+
startTime = System.currentTimeMillis();
192197
// Register me
193198
uploadForegroundNotification.progress(getId(), 0f);
194199
handleNotification();
@@ -246,6 +251,7 @@ public Result doWork() {
246251
return Result.retry();
247252
}
248253
} finally {
254+
endTime = System.currentTimeMillis();
249255
// Always remove ourselves from the notification
250256
uploadForegroundNotification.done(getId());
251257
}
@@ -254,7 +260,9 @@ public Result doWork() {
254260
final Data.Builder outputData = new Data.Builder()
255261
.putString(KEY_OUTPUT_ID, id)
256262
.putBoolean(KEY_OUTPUT_IS_ERROR, false)
257-
.putInt(KEY_OUTPUT_STATUS_CODE, (!DEBUG_SKIP_UPLOAD) ? response.code() : 200);
263+
.putInt(KEY_OUTPUT_STATUS_CODE, (!DEBUG_SKIP_UPLOAD) ? response.code() : 200)
264+
.putLong(KEY_OUTPUT_UPLOAD_START_TIME, startTime)
265+
.putLong(KEY_OUTPUT_UPLOAD_FINISH_TIME, endTime);
258266

259267
// Try read the response body, if any
260268
try {

src/ios/FileUploader.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#import <Foundation/Foundation.h>
22
#import "UploadEvent.h"
33
#import <AFNetworking/AFNetworking.h>
4+
#import <math.h>
45
NS_ASSUME_NONNULL_BEGIN
56
@protocol FileUploaderDelegate <NSObject>
67
@optional

src/ios/FileUploader.m

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#import "FileUploader.h"
22
@interface FileUploader()
3-
@property (nonatomic, strong) NSMutableDictionary* responsesData;
3+
@property (nonatomic, strong) NSMutableDictionary<NSString *, NSDate *> *uploadStartTimes;
4+
@property (nonatomic, strong) NSMutableDictionary *responsesData;
45
@property (nonatomic, strong) AFURLSessionManager *manager;
56
@end
67

@@ -20,30 +21,44 @@ -(id)init{
2021
return nil;
2122
[UploadEvent setupStorage];
2223
self.responsesData = [[NSMutableDictionary alloc] init];
24+
self.uploadStartTimes = [[NSMutableDictionary alloc] init];
2325
NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:[[NSBundle mainBundle] bundleIdentifier]];
2426
configuration.HTTPMaximumConnectionsPerHost = FileUploader.parallelUploadsLimit;
2527
configuration.sessionSendsLaunchEvents = NO;
2628
self.manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
2729
__weak FileUploader *weakSelf = self;
2830
[self.manager setTaskDidCompleteBlock:^(NSURLSession * _Nonnull session, NSURLSessionTask * _Nonnull task, NSError * _Nullable error) {
2931
NSString* uploadId = [NSURLProtocol propertyForKey:kUploadUUIDStrPropertyKey inRequest:task.originalRequest];
32+
NSDate *startTime = weakSelf.uploadStartTimes[uploadId];
33+
NSDate *endUploadTime = [NSDate date];
34+
NSTimeInterval timeInterval = [endUploadTime timeIntervalSince1970];
35+
long long endUploadTimeInMS = (long long)(timeInterval * 1000);
36+
NSTimeInterval duration = [endUploadTime timeIntervalSinceDate:startTime];
3037
NSLog(@"[BackgroundUpload] Task %@ completed with error %@", uploadId, error);
3138
if (!error){
3239
NSData* serverData = weakSelf.responsesData[@(task.taskIdentifier)];
3340
NSString* serverResponse = serverData ? [[NSString alloc] initWithData:serverData encoding:NSUTF8StringEncoding] : @"";
3441
[weakSelf.responsesData removeObjectForKey:@(task.taskIdentifier)];
35-
[weakSelf saveAndSendEvent:@{
36-
@"id" : uploadId,
37-
@"state" : @"UPLOADED",
38-
@"statusCode" : @(((NSHTTPURLResponse *)task.response).statusCode),
39-
@"serverResponse" : serverResponse
40-
}];
42+
NSMutableDictionary *event = [@{
43+
@"id" : uploadId,
44+
@"state" : @"UPLOADED",
45+
@"statusCode" : @(((NSHTTPURLResponse *)task.response).statusCode),
46+
@"serverResponse" : serverResponse
47+
} mutableCopy];
48+
49+
if (!isnan(duration)) {
50+
event[@"uploadDuration"] = @(duration * 1000);
51+
event[@"finishUploadTime"] = @(endUploadTimeInMS);
52+
}
53+
54+
[weakSelf saveAndSendEvent:event];
4155
} else {
56+
[weakSelf.responsesData removeObjectForKey:@(task.taskIdentifier)];
4257
[weakSelf saveAndSendEvent:@{
4358
@"id" : uploadId,
4459
@"state" : @"FAILED",
4560
@"error" : error.localizedDescription,
46-
@"errorCode" : @(error.code)
61+
@"errorCode" : @(error.code),
4762
}];
4863
}
4964
}];
@@ -60,7 +75,7 @@ -(id)init{
6075
}
6176

6277
-(void)saveAndSendEvent:(NSDictionary*)data{
63-
UploadEvent*event = [UploadEvent create:data];
78+
UploadEvent* event = [UploadEvent create:data];
6479
[self sendEvent:[event dataRepresentation]];
6580
}
6681

@@ -89,6 +104,9 @@ -(void)addUpload:(NSDictionary *)payload completionHandler:(void (^)(NSError* er
89104
completionHandler:^(NSError *error, NSMutableURLRequest *request) {
90105
if (error)
91106
return handler(error);
107+
108+
weakSelf.uploadStartTimes[payload[@"id"]] = [NSDate date];
109+
92110
__block double lastProgressTimeStamp = 0;
93111

94112
[[weakSelf.manager uploadTaskWithRequest:request

0 commit comments

Comments
 (0)