Fix zipping large file freezes app

This commit is contained in:
Leon Böttger committed 2026-04-27 21:03:04 +02:00
1 parent e6d1c7b1a3
commit ce16bca415
2 files changed
+88 -48

No files matched your search

@@ -33,6 +33,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
private var outboundAppDelegates: [OutboundAppDelegate] = []
private var inboundAppDelegates: [InboundAppDelegate] = []
private var outgoingTransfers: [String: OutgoingTransferInfo] = [:]
private var pendingOutgoingTransferPreparations: [String: UUID] = [:]
private var startedDeviceDiscovery = false
private var startedAdvertising = false { didSet { informAboutStatus() }}
private var browsers: [NWBrowser] = []
@@ -515,6 +516,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
if let transfer = incomingConnections[id] {
transfer.cancel()
}
pendingOutgoingTransferPreparations.removeValue(forKey: id)
if let info = outgoingTransfers[id] {
info.connection.cancel()
}
@@ -699,28 +701,60 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
}
public func startOutgoingTransfer(deviceID: String, delegate: OutboundAppDelegate, urls: [URL], textToSend: String?) {
public func startOutgoingTransfer(
deviceID: String,
delegate: OutboundAppDelegate,
urls: [URL],
textToSend: String?,
preparationFinished: (() -> Void)? = nil
) {
log("Starting outgoing transfer to \(deviceID)")
guard let info = foundServices[deviceID] else { return }
do {
let localUrls = try saveFilesToTemp(urls: urls)
let tcp = NWProtocolTCP.Options()
tcp.noDelay = true
let nwconn = NWConnection(to: info.service.endpoint, using: NWParameters(tls: .none, tcp: tcp))
let conn = OutboundNearbyConnection(connection: nwconn, id: deviceID, urlsToSend: localUrls, textToSend: textToSend)
conn.delegate = self
conn.qrCodePrivateKey = qrCodePrivateKey
let transfer = OutgoingTransferInfo(service: info.service, device: info.device!, connection: conn, delegate: delegate)
outgoingTransfers[deviceID] = transfer
conn.start()
} catch {
log("[NearbyConnectionManager] Error storing URLs: \(error)")
outboundAppDelegates.forEach { delegate in
delegate.connectionFailed(error: error)
guard foundServices[deviceID] != nil else { return }
let preparationID = UUID()
pendingOutgoingTransferPreparations[deviceID] = preparationID
DispatchQueue.global(qos: .userInitiated).async { [weak self, weak delegate] in
guard let self else { return }
do {
let localUrls = try self.saveFilesToTemp(urls: urls)
DispatchQueue.main.async {
guard let info = self.foundServices[deviceID],
self.pendingOutgoingTransferPreparations[deviceID] == preparationID else {
return
}
self.pendingOutgoingTransferPreparations.removeValue(forKey: deviceID)
guard let delegate else { return }
preparationFinished?()
let tcp = NWProtocolTCP.Options()
tcp.noDelay = true
let nwconn = NWConnection(to: info.service.endpoint, using: NWParameters(tls: .none, tcp: tcp))
let conn = OutboundNearbyConnection(connection: nwconn, id: deviceID, urlsToSend: localUrls, textToSend: textToSend)
conn.delegate = self
conn.qrCodePrivateKey = self.qrCodePrivateKey
let transfer = OutgoingTransferInfo(service: info.service, device: info.device!, connection: conn, delegate: delegate)
self.outgoingTransfers[deviceID] = transfer
conn.start()
}
} catch {
log("[NearbyConnectionManager] Error storing URLs: \(error)")
DispatchQueue.main.async {
guard self.pendingOutgoingTransferPreparations[deviceID] == preparationID else {
return
}
self.pendingOutgoingTransferPreparations.removeValue(forKey: deviceID)
self.outboundAppDelegates.forEach { delegate in
delegate.connectionFailed(error: error)
}
}
}
}
}
+33 -27
View File
@@ -259,37 +259,43 @@ class ShareViewController: NSViewController, OutboundAppDelegate {
chosenDevice = device
runAfter(seconds: 0.3) {
NearbyConnectionManager.shared.startOutgoingTransfer(deviceID: device.id!, delegate: self, urls: self.urls, textToSend: self.textToSend)
self.progressState?.stringValue = "Connecting".localized()
let timeoutAlert = DispatchWorkItem {
if !self.connectionEstablished {
AudioManager.playErrorSound()
let alert = NSAlert()
alert.alertStyle = .critical
NearbyConnectionManager.shared.startOutgoingTransfer(
deviceID: device.id!,
delegate: self,
urls: self.urls,
textToSend: self.textToSend,
preparationFinished: {
self.progressState?.stringValue = "Connecting".localized()
alert.messageText = "TimeoutTitle".localized()
if #available(macOS 15.0, *) {
alert.informativeText = "TimeoutDescription".localized()
alert.addButton(withTitle: "TimeoutButton".localized())
alert.addButton(withTitle: "CloseAlert".localized())
} else {
alert.informativeText = "TimeoutDescriptionLegacy".localized()
alert.addButton(withTitle: "TimeoutButtonLegacy".localized())
}
alert.beginSheetModal(for: self.view.window!) { response in
if #available(macOS 15.0, *), response == .alertFirstButtonReturn {
openPrivacyAndSecuritySettings()
let timeoutAlert = DispatchWorkItem {
if !self.connectionEstablished {
AudioManager.playErrorSound()
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = "TimeoutTitle".localized()
if #available(macOS 15.0, *) {
alert.informativeText = "TimeoutDescription".localized()
alert.addButton(withTitle: "TimeoutButton".localized())
alert.addButton(withTitle: "CloseAlert".localized())
} else {
alert.informativeText = "TimeoutDescriptionLegacy".localized()
alert.addButton(withTitle: "TimeoutButtonLegacy".localized())
}
alert.beginSheetModal(for: self.view.window!) { response in
if #available(macOS 15.0, *), response == .alertFirstButtonReturn {
openPrivacyAndSecuritySettings()
}
}
}
}
self.timeoutDispatchWorkItem = timeoutAlert
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: timeoutAlert)
}
}
self.timeoutDispatchWorkItem = timeoutAlert
DispatchQueue.main.asyncAfter(deadline: .now() + 10.0, execute: timeoutAlert)
)
}
}