diff --git a/example/integration_test/downloader_integration_test.dart b/example/integration_test/downloader_integration_test.dart index 78de461..4539535 100644 --- a/example/integration_test/downloader_integration_test.dart +++ b/example/integration_test/downloader_integration_test.dart @@ -2443,6 +2443,7 @@ void main() { taskStatusUpdate = TaskStatusUpdate(task, TaskStatus.failed); // reset FileDownloader().registerCallbacks( taskStatusCallback: (update) => taskStatusUpdate = update); + await Future.delayed(const Duration(milliseconds: 500)); await downloader.retrieveLocallyStoredData(); // triggers status update await Future.delayed(const Duration(milliseconds: 500)); expect(taskStatusUpdate.status, equals(TaskStatus.complete)); @@ -2478,6 +2479,7 @@ void main() { taskStatusUpdate = TaskStatusUpdate(task, TaskStatus.canceled); // reset FileDownloader().registerCallbacks( taskStatusCallback: (update) => taskStatusUpdate = update); + await Future.delayed(const Duration(milliseconds: 500)); await downloader.retrieveLocallyStoredData(); // triggers status update await Future.delayed(const Duration(milliseconds: 500)); expect(taskStatusUpdate.status, equals(TaskStatus.failed)); diff --git a/ios/Classes/Helpers.swift b/ios/Classes/Helpers.swift index 07490d6..10257f6 100644 --- a/ios/Classes/Helpers.swift +++ b/ios/Classes/Helpers.swift @@ -18,3 +18,16 @@ extension URL { } } } + +/// Converts the [map] to a [String:String] map with lowercased keys +func lowerCasedStringStringMap(_ map: [AnyHashable: Any]?) -> [String: String]? { + if map == nil {return nil} + var result: [String: String] = [:] + for (key, value) in map! { + if let stringKey = key as? String, let stringValue = value as? String { + result[stringKey.lowercased()] = stringValue + } + } + return result +} + diff --git a/ios/Classes/Task.swift b/ios/Classes/Task.swift index 4ef88f9..0088f10 100644 --- a/ios/Classes/Task.swift +++ b/ios/Classes/Task.swift @@ -200,6 +200,28 @@ enum TaskStatus: Int, Codable { struct TaskStatusUpdate: Encodable { var task: Task var taskStatus: TaskStatus + var exception: TaskException? + var responseBody: String? + var responseStatusCode: Int? + var responseHeaders: [String: String]? + var mimeType: String? + var charSet: String? + + func argList() -> [Any?] { + let finalState = isFinalState(status: taskStatus) + return taskStatus == .failed + ? [taskStatus.rawValue, + exception?.type.rawValue, + exception?.description, + exception?.httpResponseCode, + responseBody] + : [taskStatus.rawValue, + finalState ? responseBody : nil, + finalState ? responseHeaders : nil, + (taskStatus == .complete || taskStatus == .notFound) ? responseStatusCode : nil, + finalState ? mimeType : nil, + finalState ? charSet : nil] + } } /** Holds data associated with a task progress update, for local storage */ @@ -216,7 +238,7 @@ struct ResumeData: Encodable { } /// The type of [TaskException] -enum ExceptionType: String { +enum ExceptionType: String, Encodable { case // General error @@ -248,7 +270,7 @@ enum ExceptionType: String { * The [description] is typically taken from the platform-generated * error message, or from the plugin. The localization is undefined */ -struct TaskException { +struct TaskException : Encodable { var type: ExceptionType var httpResponseCode: Int = -1 var description: String diff --git a/ios/Classes/TaskFunctions.swift b/ios/Classes/TaskFunctions.swift index 97dbefc..7f9f586 100644 --- a/ios/Classes/TaskFunctions.swift +++ b/ios/Classes/TaskFunctions.swift @@ -364,12 +364,20 @@ func processStatusUpdate(task: Task, status: TaskStatus, taskException: TaskExce let finalTaskException = taskException == nil ? TaskException(type: .general, httpResponseCode: -1, description: "") : taskException - let arg: [Any?] = status == .failed - ? [status.rawValue, finalTaskException!.type.rawValue, finalTaskException!.description, finalTaskException!.httpResponseCode, responseBody] as [Any?] - : [status.rawValue, responseBody, responseHeaders, finalResponseStatusCode, mimeType, charSet] as [Any?] + let statusUpdate = isFinalState(status: status) + ? TaskStatusUpdate(task: task, + taskStatus: status, + exception: status == .failed ? finalTaskException : nil, + responseBody: responseBody, + responseStatusCode: (status == .complete || status == .notFound) ? finalResponseStatusCode : nil, + responseHeaders: lowerCasedStringStringMap(responseHeaders), + mimeType: mimeType, + charSet: charSet) + : TaskStatusUpdate(task: task, taskStatus: status) + let arg = statusUpdate.argList() if !postOnBackgroundChannel(method: "statusUpdate", task: task, arg: arg) { // store update locally as a merged task/status JSON string, without error info - guard let jsonData = try? JSONEncoder().encode(TaskStatusUpdate(task: task, taskStatus: status)) + guard let jsonData = try? JSONEncoder().encode(statusUpdate) else { os_log("Could not store status update locally", log: log, type: .debug) return }