From 83a6ed70401172898906dd93fe6ba19cb01cd143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6ttger?= Date: Fri, 25 Jul 2025 14:35:37 +0200 Subject: [PATCH] Remove progress if file was aborted --- NearbyShare/InboundNearbyConnection.swift | 34 +++++++++++------------ NearbyShare/NearbyConnection.swift | 23 +++++++++------ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/NearbyShare/InboundNearbyConnection.swift b/NearbyShare/InboundNearbyConnection.swift index 494cf38..6253a25 100644 --- a/NearbyShare/InboundNearbyConnection.swift +++ b/NearbyShare/InboundNearbyConnection.swift @@ -114,7 +114,7 @@ class InboundNearbyConnection: NearbyConnection { let id = frame.payloadHeader.id - guard let fileInfo = transferredFiles[id] else { throw NearbyError.protocolError("File payload ID \(id) is not known") } + guard let fileInfo = filesToBeTransferred[id] else { throw NearbyError.protocolError("File payload ID \(id) is not known") } let currentOffset = fileInfo.bytesTransferred @@ -125,8 +125,8 @@ class InboundNearbyConnection: NearbyConnection { if frame.payloadChunk.body.count > 0 { do { try fileInfo.fileHandle?.write(contentsOf: frame.payloadChunk.body) - transferredFiles[id]!.bytesTransferred += Int64(frame.payloadChunk.body.count) - fileInfo.progress?.completedUnitCount = transferredFiles[id]!.bytesTransferred + filesToBeTransferred[id]!.bytesTransferred += Int64(frame.payloadChunk.body.count) + fileInfo.progress?.completedUnitCount = filesToBeTransferred[id]!.bytesTransferred } catch { log("Error occurred during writing file: \(error.localizedDescription)") @@ -135,13 +135,13 @@ class InboundNearbyConnection: NearbyConnection { } else if (frame.payloadChunk.flags & 1) == 1 { try fileInfo.fileHandle?.close() - transferredFiles[id]!.fileHandle = nil + filesToBeTransferred[id]!.fileHandle = nil fileInfo.progress?.unpublish() SaveFilesManager.shared.registerFileFinishedDownloading(fileInfo.destinationURL) - transferredFiles.removeValue(forKey: id) + filesToBeTransferred.removeValue(forKey: id) - if transferredFiles.isEmpty { + if filesToBeTransferred.isEmpty { log("All files received, sending disconnection frame and disconnecting.") try sendDisconnectionAndDisconnect() } @@ -169,14 +169,14 @@ class InboundNearbyConnection: NearbyConnection { try sendDisconnectionAndDisconnect() return true } - else if let fileInfo = transferredFiles[id] { + else if let fileInfo = filesToBeTransferred[id] { fileInfo.fileHandle?.write(payload) - transferredFiles[id]!.bytesTransferred += Int64(payload.count) - fileInfo.progress?.completedUnitCount = transferredFiles[id]!.bytesTransferred + filesToBeTransferred[id]!.bytesTransferred += Int64(payload.count) + fileInfo.progress?.completedUnitCount = filesToBeTransferred[id]!.bytesTransferred try fileInfo.fileHandle?.close() - transferredFiles[id]!.fileHandle = nil + filesToBeTransferred[id]!.fileHandle = nil fileInfo.progress?.unpublish() - transferredFiles.removeValue(forKey: id) + filesToBeTransferred.removeValue(forKey: id) SaveFilesManager.shared.registerFileFinishedDownloading(fileInfo.destinationURL) log("Received file payload. Disconnecting...") @@ -368,9 +368,9 @@ class InboundNearbyConnection: NearbyConnection { let info = InternalFileInfo(meta: FileMetadata(name: file.name, size: file.size, mimeType: file.mimeType), payloadID: file.payloadID, destinationURL: dest) - transferredFiles[file.payloadID] = info + filesToBeTransferred[file.payloadID] = info } - let metadata = TransferMetadata(files: transferredFiles.map { $0.value.meta }, id: id, pinCode: pinCode) + let metadata = TransferMetadata(files: filesToBeTransferred.map { $0.value.meta }, id: id, pinCode: pinCode) DispatchQueue.main.async { self.delegate?.obtainUserConsent(for: metadata, from: self.remoteDeviceInfo!, connection: self) } @@ -429,12 +429,12 @@ class InboundNearbyConnection: NearbyConnection { try FileManager.default.createDirectory(at: SaveFilesManager.shared.tempDirectory, withIntermediateDirectories: true) } - for (id, file) in transferredFiles { + for (id, file) in filesToBeTransferred { let targetURL = storeInTemp ? SaveFilesManager.shared.tempDirectory.appendingPathComponent(file.destinationURL.lastPathComponent) : file.destinationURL FileManager.default.createFile(atPath: targetURL.path, contents: nil) let handle = try FileHandle(forWritingTo: targetURL) - transferredFiles[id]!.fileHandle = handle + filesToBeTransferred[id]!.fileHandle = handle let progress = Progress() progress.fileURL = targetURL @@ -442,8 +442,8 @@ class InboundNearbyConnection: NearbyConnection { progress.kind = .file progress.isPausable = false progress.publish() - transferredFiles[id]!.progress = progress - transferredFiles[id]!.created = true + filesToBeTransferred[id]!.progress = progress + filesToBeTransferred[id]!.created = true } var frame = Sharing_Nearby_Frame() diff --git a/NearbyShare/NearbyConnection.swift b/NearbyShare/NearbyConnection.swift index 609d513..99f46c5 100644 --- a/NearbyShare/NearbyConnection.swift +++ b/NearbyShare/NearbyConnection.swift @@ -18,13 +18,15 @@ class NearbyConnection { static let SANE_FRAME_LENGTH = 5 * 1024 * 1024 private static let dispatchQueue = DispatchQueue(label: "com.leonboettger.quickdrop.queue", qos: .utility) // FIFO (non-concurrent) queue to avoid those exciting concurrency bugs - let connection: NWConnection - var remoteDeviceInfo: RemoteDeviceInfo? - private var payloadBuffers: [Int64: NSMutableData] = [:] - var encryptionDone: Bool = false - var transferredFiles: [Int64: InternalFileInfo] = [:] public let id: String + let connection: NWConnection + + var remoteDeviceInfo: RemoteDeviceInfo? + var encryptionDone: Bool = false + var filesToBeTransferred: [Int64: InternalFileInfo] = [:] var lastError: Error? + + private var payloadBuffers: [Int64: NSMutableData] = [:] private var connectionClosed: Bool = false private var inactivityTimer: DispatchSourceTimer? @@ -321,7 +323,7 @@ class NearbyConnection { let chunk = payloadTransfer.payloadChunk guard header.hasType, header.hasID else { throw NearbyError.requiredFieldMissing("payloadHeader.type|id") } - guard payloadTransfer.hasPayloadChunk, chunk.hasOffset, chunk.hasFlags else { throw NearbyError.requiredFieldMissing("payloadTransfer.payloadChunk|offset|flags") } + guard payloadTransfer.hasPayloadChunk, chunk.hasOffset, chunk.hasFlags else { throw NearbyError.requiredFieldMissing("File transfer was likely canceled.") } if case .bytes = header.type { @@ -364,7 +366,7 @@ class NearbyConnection { } else if offlineFrame.hasV1, offlineFrame.v1.hasType, case .keepAlive = offlineFrame.v1.type { - log("Sent keep-alive, current transfer progress: \(transferredFiles.values.reduce(0) { $0 + $1.bytesTransferred }) bytes") + log("Sent keep-alive, current transfer progress: \(filesToBeTransferred.values.reduce(0) { $0 + $1.bytesTransferred }) bytes") sendKeepAlive(ack: true) } else { @@ -544,7 +546,12 @@ class NearbyConnection { } private func deletePartiallyReceivedFiles() { - for (_, file) in transferredFiles { + for (_, file) in filesToBeTransferred { + + if let progress = file.progress { + progress.unpublish() + } + guard file.created else { continue } do { try FileManager.default.removeItem(at: file.destinationURL)