Add alert handler for outgoing connections to iOS app

This commit is contained in:
Leon Böttger committed 2025-08-15 11:53:45 +02:00
1 parent c781af554f
commit 9a3f6c81c7
3 files changed
+61 -19

No files matched your search

+2
View File
@@ -97,6 +97,7 @@
EB886E5E2E4F13EB0052B7D9 /* Zip.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBCC27F82D80C9F70079C478 /* Zip.swift */; };
EB886E672E4F2F800052B7D9 /* License.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB886E662E4F2F7C0052B7D9 /* License.swift */; };
EB886E682E4F2F800052B7D9 /* License.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB886E662E4F2F7C0052B7D9 /* License.swift */; };
EB886E6A2E4F37B90052B7D9 /* ErrorAlertHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C5A2E33936C00EECC18 /* ErrorAlertHandler.swift */; };
EB96ED8B2D7F7CF7004B3FF1 /* SmallSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB96ED8A2D7F7CF4004B3FF1 /* SmallSheetView.swift */; };
EB96ED8C2D7F7E7B004B3FF1 /* SmallSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB96ED8A2D7F7CF4004B3FF1 /* SmallSheetView.swift */; };
EB96ED8D2D7F7EA3004B3FF1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69DA9A1329E0BF5200A442DA /* Assets.xcassets */; };
@@ -775,6 +776,7 @@
EB5C37FC2E377CE70052EFD7 /* OutboundNearbyConnection.swift in Sources */,
EB5C37FD2E377CE70052EFD7 /* Logger.swift in Sources */,
EB5C37FE2E377CE70052EFD7 /* offline_wire_formats.pb.swift in Sources */,
EB886E6A2E4F37B90052B7D9 /* ErrorAlertHandler.swift in Sources */,
EB886E5E2E4F13EB0052B7D9 /* Zip.swift in Sources */,
EB5C383D2E38C2D90052EFD7 /* AudioManager.swift in Sources */,
EB5C38402E38C49D0052EFD7 /* LaunchAtLogin.swift in Sources */,
+38 -11
View File
@@ -6,25 +6,34 @@
//
import AudioToolbox
import BezelNotification
import Cocoa
import Network
import StoreKit
import SwiftUI
import UserNotifications
#if os(macOS)
import BezelNotification
import Cocoa
#else
import LUI
#endif
class ErrorAlertHandler {
private init() {}
static let shared = ErrorAlertHandler()
private var isAlertShown = false
#if os(macOS)
private var firewallAlertWindow: NSWindow?
private var apIsolationAlertWindow: NSWindow?
private var networkFilterAlertWindow: NSWindow?
#endif
func showErrorAlert(for deviceName: String, error: Error) {
#if os(macOS)
NSApp.activate(ignoringOtherApps: true)
#endif
var description = ""
let fixInstructions = " " + "Error.FixInstructions".localized()
@@ -36,11 +45,19 @@ class ErrorAlertHandler {
case .protocolError(errorMessage: let errorMessage):
description = errorMessage + fixInstructions
case .packetFilterError:
#if os(macOS)
openAlert(type: .NetworkFilter)
return
#else
description = error.localizedDescription
#endif
case .firewallError:
#if os(macOS)
openAlert(type: .Firewall)
return
#else
description = error.localizedDescription
#endif
case .requiredFieldMissing(errorMessage: let errorMessage):
description = errorMessage + fixInstructions
case .ukey2:
@@ -57,13 +74,6 @@ class ErrorAlertHandler {
description = error.localizedDescription
}
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = String(format: "TransferError".localized(), arguments: [deviceName])
alert.informativeText = description
alert.addButton(withTitle: "InformDeveloper".localized())
alert.addButton(withTitle: "CloseAlert".localized())
// Prevent multiple alerts at the same time
if self.isAlertShown {
log("Skipping alert for error \(error.localizedDescription) because one is already shown")
@@ -71,10 +81,20 @@ class ErrorAlertHandler {
}
else {
AudioManager.playErrorSound()
self.isAlertShown = true
log("Showing alert with message: \"\(alert.messageText)\" and description: \"\(alert.informativeText)\"")
let title = String(format: "TransferError".localized(), arguments: [deviceName])
log("Showing alert with title: \"\(title)\" and description: \"\(description)\"")
log("Unsuccessful transmission. Already successful transmissions: \(transmissionCount())")
#if os(macOS)
self.isAlertShown = true
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = title
alert.informativeText = description
alert.addButton(withTitle: "InformDeveloper".localized())
alert.addButton(withTitle: "CloseAlert".localized())
let result = alert.runModal()
self.isAlertShown = false
@@ -82,10 +102,14 @@ class ErrorAlertHandler {
log("Sending logging string")
sendLoggingString()
}
#else
showAlert(title: title, message: description)
#endif
}
}
#if os(macOS)
func openAlert(type: AlertType) {
log("Opening Alert for \(type)")
AudioManager.playErrorSound()
@@ -130,9 +154,11 @@ class ErrorAlertHandler {
self.apIsolationAlertWindow = nil
}
}
#endif
}
#if os(macOS)
func sendLoggingString() {
// If we're in an extension, redirect to the main app
if Bundle.main.bundlePath.hasSuffix(".appex") {
@@ -195,6 +221,7 @@ func copyToClipboard(_ text: String) {
pasteboard.clearContents()
pasteboard.setString(text, forType: .string)
}
#endif
enum AlertType: String {
+21 -8
View File
@@ -11,7 +11,6 @@ class ShareViewModel: ObservableObject, ShareExtensionDelegate {
@Published var foundDevices: [RemoteDeviceInfo] = []
@Published var selectedDevice: RemoteDeviceInfo?
@Published var lastError: Error?
@Published var progressState: String? = nil
@Published var progressValue: Double? = nil
@@ -25,6 +24,7 @@ class ShareViewModel: ObservableObject, ShareExtensionDelegate {
init() {
NearbyConnectionManager.shared.startDeviceDiscovery()
NearbyConnectionManager.shared.becomeVisible()
NearbyConnectionManager.shared.addShareExtensionDelegate(self)
}
@@ -47,10 +47,11 @@ class ShareViewModel: ObservableObject, ShareExtensionDelegate {
}
func connectionFailed(with error: any Error) {
progressValue = nil
lastError = error
//ErrorAlertHandler.shared.showErrorAlert(for: chosenDevice?.name ?? "", error: error)
ErrorAlertHandler.shared.showErrorAlert(for: selectedDevice?.name ?? "?", error: error)
progressValue = nil
selectedDevice = nil
}
func transferAccepted() {
@@ -62,6 +63,8 @@ class ShareViewModel: ObservableObject, ShareExtensionDelegate {
}
func transferFinished() {
progressValue = 0
selectedDevice = nil
progressState = "TransferFinished".localized()
}
@@ -70,9 +73,19 @@ class ShareViewModel: ObservableObject, ShareExtensionDelegate {
}
func selectDevice(device: RemoteDeviceInfo) {
progressValue = 0
progressState = "Connecting".localized()
selectedDevice = device
NearbyConnectionManager.shared.startOutgoingTransfer(deviceID: device.id!, delegate: self, urls: urls, textToSend: textToSend)
// already selected, cancel transfer
if device == selectedDevice {
progressValue = 0
progressState = nil
selectedDevice = nil
NearbyConnectionManager.shared.cancelOutgoingTransfer(id: device.id!)
}
else {
progressValue = 0
progressState = "Connecting".localized()
selectedDevice = device
NearbyConnectionManager.shared.startOutgoingTransfer(deviceID: device.id!, delegate: self, urls: urls, textToSend: textToSend)
}
}
}