diff --git a/NearbyShare/Connection/NearbyConnectionManager.swift b/NearbyShare/Connection/NearbyConnectionManager.swift index dcdd3b3..82f5565 100644 --- a/NearbyShare/Connection/NearbyConnectionManager.swift +++ b/NearbyShare/Connection/NearbyConnectionManager.swift @@ -29,6 +29,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb private var shareExtensionDelegates: [OutboundAppDelegate] = [] private var outgoingTransfers: [String: OutgoingTransferInfo] = [:] private var startedDeviceDiscovery = false + private var startedAdvertising = false private var browsers: [NWBrowser] = [] private let serviceTypes = ["_FC9F5ED42C8A._tcp."] private var qrCodePrivateKey: ECPrivateKey? @@ -56,11 +57,16 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb public func becomeVisible() { - startTCPListener() - } - - - private func startTCPListener() { + if startedAdvertising { + log("[NearbyConnectionManager] Already advertising, skipping") + return + } + + log("[NearbyConnectionManager] Becoming visible") + + tcpListener = try! NWListener(using: NWParameters(tls: .none)) + startedAdvertising = true + tcpListener.stateUpdateHandler = { (state: NWListener.State) in if case .ready = state { self.initMDNS() @@ -77,6 +83,20 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb } + public func becomeInvisible() { + if !startedAdvertising { + print("[NearbyConnectionManager] Already invisible, ignoring becomeInvisible()") + return + } + + log("[NearbyConnectionManager] Becoming invisible") + + startedAdvertising = false + self.stopMDNS() + tcpListener.cancel() + } + + private static func generateEndpointID() -> [UInt8] { let userDefaultsKey = UserDefaultsKeys.endpointID.rawValue @@ -125,6 +145,15 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb } + private func stopMDNS() { + // Gracefully stop each published service + for service in mdnsServices { + service.stop() + } + mdnsServices.removeAll() + } + + func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, connection _: InboundNearbyConnection) { mainAppDelegate?.obtainUserConsent(for: transfer, from: device) } @@ -188,7 +217,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb public func stopDeviceDiscovery() { if startedDeviceDiscovery { - log("Stopping device discovery") + log("[NearbyConnectionManager] Stopping device discovery") for browser in browsers { browser.cancel() @@ -196,6 +225,15 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb browsers.removeAll() startedDeviceDiscovery = false + + + for delegate in shareExtensionDelegates { + + foundServices.values.forEach { service in + guard let device = service.device, let id = device.id else { return } + delegate.removeDevice(id: id) + } + } } } diff --git a/NearbyShare/Util/Logger.swift b/NearbyShare/Util/Logger.swift index 027f195..5aef397 100644 --- a/NearbyShare/Util/Logger.swift +++ b/NearbyShare/Util/Logger.swift @@ -24,14 +24,8 @@ final class LogManager { /// Private initializer private init() { - - #if os(macOS) // Use the App Group container let directory = getAppGroupDirectory() - #else - // On iOS, use the library directory, to not let the logs appear in the files app - let directory = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first - #endif // Create file name from date let formatter = DateFormatter() @@ -133,7 +127,7 @@ public func log(_ text: String) { /// Returns the shared App Group directory -fileprivate func getAppGroupDirectory() -> URL? { +func getAppGroupDirectory() -> URL? { let groupIdentifier = "group.com.leonboettger.neardrop" return FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupIdentifier) } diff --git a/QuickDrop.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/QuickDrop.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index bc436ff..2006c69 100644 --- a/QuickDrop.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/QuickDrop.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -43,7 +43,7 @@ "location" : "https://github.com/leonboe1/LUI.git", "state" : { "branch" : "main", - "revision" : "b4a9766db0f328c8251b1fa8bed2472c783d7128" + "revision" : "0fa79d937a5948c59f44c64b12af21c7d3b408e5" } }, { diff --git a/QuickDropiOS/Configuration.swift b/QuickDropiOS/Configuration.swift index e8369e6..909ee8a 100644 --- a/QuickDropiOS/Configuration.swift +++ b/QuickDropiOS/Configuration.swift @@ -14,6 +14,8 @@ let configuration = LUIConfiguration( copyrightInformation: licenseText, + loggingUrl: getAppGroupDirectory(), + introductionViewInformation: "QuickDropWelcomeDescription", usesAutomaticReviewPrompt: false, diff --git a/QuickDropiOS/ContentView.swift b/QuickDropiOS/ContentView.swift index ab3575e..faa7cd4 100644 --- a/QuickDropiOS/ContentView.swift +++ b/QuickDropiOS/ContentView.swift @@ -10,6 +10,8 @@ import LUI struct ContentView: View { + @Environment(\.scenePhase) var scenePhase + var body: some View { AppRootView(isPlus: .constant(true), phoneView: { DeviceListView() @@ -23,6 +25,21 @@ struct ContentView: View { } } }) + .onChange(of: scenePhase) { newValue in + if newValue == .active { + #if !EXTENSION + NearbyConnectionManager.shared.becomeVisible() + #endif + NearbyConnectionManager.shared.startDeviceDiscovery() + } + + if newValue == .background { + #if !EXTENSION + NearbyConnectionManager.shared.becomeInvisible() + #endif + NearbyConnectionManager.shared.stopDeviceDiscovery() + } + } } } diff --git a/iOSShareExtension/ShareViewController.swift b/iOSShareExtension/ShareViewController.swift index 102486d..bf6de4d 100644 --- a/iOSShareExtension/ShareViewController.swift +++ b/iOSShareExtension/ShareViewController.swift @@ -29,6 +29,7 @@ class ShareViewController: UIViewController { }) // skip introduction for share extension + LUIInit(configuration: configuration) LUISettings.sharedInstance.appLaunchedBefore = true // Replace with your app’s SwiftUI entry view