Add support for media uploading progress

- replace the ProgressTracker with a combination of currentValueSubjects and currentValuePublishers
This commit is contained in:
Stefan Ceriu
2023-06-21 12:55:49 +03:00
committed by Stefan Ceriu
parent 9cf2aba16d
commit 8b11a0a5ec
13 changed files with 130 additions and 150 deletions
@@ -100,7 +100,7 @@ class BugReportService: NSObject, BugReportServiceProtocol {
// swiftlint:disable:next function_body_length cyclomatic_complexity
func submitBugReport(_ bugReport: BugReport,
progressListener: ProgressListener?) async -> Result<SubmitBugReportResponse, BugReportServiceError> {
progressListener: CurrentValueSubject<Double, Never>) async -> Result<SubmitBugReportResponse, BugReportServiceError> {
var params = [
MultipartFormData(key: "user_id", type: .text(value: bugReport.userID)),
MultipartFormData(key: "text", type: .text(value: bugReport.text))
@@ -148,17 +148,13 @@ class BugReportService: NSObject, BugReportServiceProtocol {
request.httpMethod = "POST"
request.httpBody = body as Data
var delegate: URLSessionTaskDelegate?
if let progressListener {
progressSubject
.receive(on: DispatchQueue.main)
.weakAssign(to: \.value, on: progressListener.progressSubject)
.store(in: &cancellables)
delegate = self
}
progressSubject
.receive(on: DispatchQueue.main)
.weakAssign(to: \.value, on: progressListener)
.store(in: &cancellables)
do {
let (data, response) = try await session.dataWithRetry(for: request, delegate: delegate)
let (data, response) = try await session.dataWithRetry(for: request, delegate: self)
guard let httpResponse = response as? HTTPURLResponse else {
let errorDescription = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines) ?? "Unknown"
@@ -14,6 +14,7 @@
// limitations under the License.
//
import Combine
import Foundation
import UIKit
@@ -63,5 +64,5 @@ protocol BugReportServiceProtocol {
func crash()
func submitBugReport(_ bugReport: BugReport,
progressListener: ProgressListener?) async -> Result<SubmitBugReportResponse, BugReportServiceError>
progressListener: CurrentValueSubject<Double, Never>) async -> Result<SubmitBugReportResponse, BugReportServiceError>
}
+30 -8
View File
@@ -276,7 +276,7 @@ class RoomProxy: RoomProxyProtocol {
}
}
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo) async -> Result<Void, RoomProxyError> {
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
@@ -284,7 +284,9 @@ class RoomProxy: RoomProxyProtocol {
return await Task.dispatch(on: userInitiatedDispatchQueue) {
do {
try self.room.sendImage(url: url.path(), thumbnailUrl: thumbnailURL.path(), imageInfo: imageInfo, progressWatcher: nil)
try self.room.sendImage(url: url.path(), thumbnailUrl: thumbnailURL.path(), imageInfo: imageInfo, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
return .success(())
} catch {
return .failure(.failedSendingMedia)
@@ -292,7 +294,7 @@ class RoomProxy: RoomProxyProtocol {
}
}
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo) async -> Result<Void, RoomProxyError> {
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
@@ -300,7 +302,9 @@ class RoomProxy: RoomProxyProtocol {
return await Task.dispatch(on: userInitiatedDispatchQueue) {
do {
try self.room.sendVideo(url: url.path(), thumbnailUrl: thumbnailURL.path(), videoInfo: videoInfo, progressWatcher: nil)
try self.room.sendVideo(url: url.path(), thumbnailUrl: thumbnailURL.path(), videoInfo: videoInfo, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
return .success(())
} catch {
return .failure(.failedSendingMedia)
@@ -308,7 +312,7 @@ class RoomProxy: RoomProxyProtocol {
}
}
func sendAudio(url: URL, audioInfo: AudioInfo) async -> Result<Void, RoomProxyError> {
func sendAudio(url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
@@ -316,7 +320,9 @@ class RoomProxy: RoomProxyProtocol {
return await Task.dispatch(on: userInitiatedDispatchQueue) {
do {
try self.room.sendAudio(url: url.path(), audioInfo: audioInfo, progressWatcher: nil)
try self.room.sendAudio(url: url.path(), audioInfo: audioInfo, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
return .success(())
} catch {
return .failure(.failedSendingMedia)
@@ -324,7 +330,7 @@ class RoomProxy: RoomProxyProtocol {
}
}
func sendFile(url: URL, fileInfo: FileInfo) async -> Result<Void, RoomProxyError> {
func sendFile(url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer {
sendMessageBackgroundTask?.stop()
@@ -332,7 +338,9 @@ class RoomProxy: RoomProxyProtocol {
return await Task.dispatch(on: userInitiatedDispatchQueue) {
do {
try self.room.sendFile(url: url.path(), fileInfo: fileInfo, progressWatcher: nil)
try self.room.sendFile(url: url.path(), fileInfo: fileInfo, progressWatcher: UploadProgressListener { progress in
progressSubject?.send(progress)
})
return .success(())
} catch {
return .failure(.failedSendingMedia)
@@ -611,3 +619,17 @@ private class RoomTimelineListener: TimelineListener {
onUpdateClosure(diff)
}
}
private class UploadProgressListener: ProgressWatcher {
private let onUpdateClosure: (Double) -> Void
init(_ onUpdateClosure: @escaping (Double) -> Void) {
self.onUpdateClosure = onUpdateClosure
}
func transmissionProgress(progress: TransmissionProgress) {
DispatchQueue.main.async { [weak self] in
self?.onUpdateClosure(Double(progress.current) / Double(progress.total))
}
}
}
@@ -93,13 +93,13 @@ protocol RoomProxyProtocol {
func sendReaction(_ reaction: String, to eventID: String) async -> Result<Void, RoomProxyError>
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo) async -> Result<Void, RoomProxyError>
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo) async -> Result<Void, RoomProxyError>
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>
func sendAudio(url: URL, audioInfo: AudioInfo) async -> Result<Void, RoomProxyError>
func sendAudio(url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>
func sendFile(url: URL, fileInfo: FileInfo) async -> Result<Void, RoomProxyError>
func sendFile(url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>
/// Retries sending a failed message given its transaction ID
func retrySend(transactionID: String) async