diff --git a/packages/connectivity_plus/connectivity_plus/CHANGELOG.md b/packages/connectivity_plus/connectivity_plus/CHANGELOG.md index 1e1df9b8f1..2d028ac494 100644 --- a/packages/connectivity_plus/connectivity_plus/CHANGELOG.md +++ b/packages/connectivity_plus/connectivity_plus/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.3.0 + +- Add iOS ConnectivityProvider based on NWPathMonitor for iOS 12+. + ## 2.2.2 - Reachability.swift ".unavailable" for iOS is deprecated. diff --git a/packages/connectivity_plus/connectivity_plus/ios/Classes/PathMonitorConnectivityProvider.swift b/packages/connectivity_plus/connectivity_plus/ios/Classes/PathMonitorConnectivityProvider.swift new file mode 100644 index 0000000000..40fe7d85a9 --- /dev/null +++ b/packages/connectivity_plus/connectivity_plus/ios/Classes/PathMonitorConnectivityProvider.swift @@ -0,0 +1,56 @@ +import Foundation +import Network + +@available(iOS 12, *) +public class PathMonitorConnectivityProvider: NSObject, ConnectivityProvider { + + private let queue = DispatchQueue.global(qos: .background) + + private var _pathMonitor: NWPathMonitor? + + public var currentConnectivityType: ConnectivityType { + let path = ensurePathMonitor().currentPath + if path.status == .satisfied { + if path.usesInterfaceType(.wifi) { + return .wifi + } else if path.usesInterfaceType(.cellular) { + return .cellular + } else if path.usesInterfaceType(.wiredEthernet) { + // .wiredEthernet is available in simulator + // but for consistency it is probably correct to report .wifi + return .wifi + } + } + return .none + } + + public var connectivityUpdateHandler: ConnectivityUpdateHandler? + + override init() { + super.init() + ensurePathMonitor() + } + + public func start() { + ensurePathMonitor() + } + + public func stop() { + _pathMonitor?.cancel() + _pathMonitor = nil + } + + private func ensurePathMonitor() -> NWPathMonitor { + if (_pathMonitor == nil) { + let pathMonitor = NWPathMonitor() + pathMonitor.start(queue: queue) + pathMonitor.pathUpdateHandler = pathUpdateHandler + _pathMonitor = pathMonitor + } + return _pathMonitor! + } + + private func pathUpdateHandler(path: NWPath) { + connectivityUpdateHandler?(currentConnectivityType) + } +} diff --git a/packages/connectivity_plus/connectivity_plus/ios/Classes/ReachabilityConnectivityProvider.swift b/packages/connectivity_plus/connectivity_plus/ios/Classes/ReachabilityConnectivityProvider.swift index b10000c13a..ae189644b6 100644 --- a/packages/connectivity_plus/connectivity_plus/ios/Classes/ReachabilityConnectivityProvider.swift +++ b/packages/connectivity_plus/connectivity_plus/ios/Classes/ReachabilityConnectivityProvider.swift @@ -2,11 +2,11 @@ import Foundation import Reachability public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider { - private var reachability: Reachability? + private var _reachability: Reachability? public var currentConnectivityType: ConnectivityType { - let reachability = try? self.reachability ?? Reachability() - switch reachability?.connection { + let reachability = ensureReachability() + switch reachability.connection { case .wifi: return .wifi case .cellular: @@ -18,8 +18,13 @@ public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider { public var connectivityUpdateHandler: ConnectivityUpdateHandler? + override init() { + super.init() + ensureReachability() + } + public func start() { - reachability = try? Reachability() + let reachability = ensureReachability() NotificationCenter.default.addObserver( self, @@ -27,17 +32,25 @@ public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider { name: .reachabilityChanged, object: reachability) - try? reachability?.startNotifier() + try? reachability.startNotifier() } public func stop() { NotificationCenter.default.removeObserver( self, name: .reachabilityChanged, - object: reachability) + object: _reachability) - reachability?.stopNotifier() - reachability = nil + _reachability?.stopNotifier() + _reachability = nil + } + + private func ensureReachability() -> Reachability { + if (_reachability == nil) { + let reachability = try? Reachability() + _reachability = reachability + } + return _reachability! } @objc private func reachabilityChanged(notification: NSNotification) { diff --git a/packages/connectivity_plus/connectivity_plus/ios/Classes/SwiftConnectivityPlusPlugin.swift b/packages/connectivity_plus/connectivity_plus/ios/Classes/SwiftConnectivityPlusPlugin.swift index 3908f5cbe0..c566902819 100644 --- a/packages/connectivity_plus/connectivity_plus/ios/Classes/SwiftConnectivityPlusPlugin.swift +++ b/packages/connectivity_plus/connectivity_plus/ios/Classes/SwiftConnectivityPlusPlugin.swift @@ -23,7 +23,12 @@ public class SwiftConnectivityPlusPlugin: NSObject, FlutterPlugin, FlutterStream name: "dev.fluttercommunity.plus/connectivity_status", binaryMessenger: registrar.messenger()) - let connectivityProvider = ReachabilityConnectivityProvider() + let connectivityProvider: ConnectivityProvider + if #available(iOS 12, *) { + connectivityProvider = PathMonitorConnectivityProvider() + } else { + connectivityProvider = ReachabilityConnectivityProvider() + } let instance = SwiftConnectivityPlusPlugin(connectivityProvider: connectivityProvider) streamChannel.setStreamHandler(instance) diff --git a/packages/connectivity_plus/connectivity_plus/pubspec.yaml b/packages/connectivity_plus/connectivity_plus/pubspec.yaml index f2438e3de5..03f6f43662 100644 --- a/packages/connectivity_plus/connectivity_plus/pubspec.yaml +++ b/packages/connectivity_plus/connectivity_plus/pubspec.yaml @@ -1,6 +1,6 @@ name: connectivity_plus description: Flutter plugin for discovering the state of the network (WiFi & mobile/cellular) connectivity on Android and iOS. -version: 2.2.2 +version: 2.3.0 homepage: https://plus.fluttercommunity.dev/ repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ @@ -30,7 +30,7 @@ dependencies: sdk: flutter connectivity_plus_platform_interface: ^1.2.0 connectivity_plus_linux: ^1.3.0 - connectivity_plus_macos: ^1.2.0 + connectivity_plus_macos: ^1.2.2 connectivity_plus_web: ^1.2.0 connectivity_plus_windows: ^1.2.0 diff --git a/packages/connectivity_plus/connectivity_plus_macos/CHANGELOG.md b/packages/connectivity_plus/connectivity_plus_macos/CHANGELOG.md index ff79ff1a0a..143043e893 100644 --- a/packages/connectivity_plus/connectivity_plus_macos/CHANGELOG.md +++ b/packages/connectivity_plus/connectivity_plus_macos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.2 + +- Fix connectivity stream can not be reused (after hot-restart) on MacOS 10.14+. + ## 1.2.1 - Update license headers. diff --git a/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/PathMonitorConnectivityProvider.swift b/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/PathMonitorConnectivityProvider.swift index 4f9e0e0117..8b96ae0f80 100644 --- a/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/PathMonitorConnectivityProvider.swift +++ b/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/PathMonitorConnectivityProvider.swift @@ -3,10 +3,13 @@ import Network @available(macOS 10.14, *) public class PathMonitorConnectivityProvider: NSObject, ConnectivityProvider { - private let pathMonitor = NWPathMonitor() + + private let queue = DispatchQueue.global(qos: .background) + + private var _pathMonitor: NWPathMonitor? public var currentConnectivityType: ConnectivityType { - let path = pathMonitor.currentPath + let path = ensurePathMonitor().currentPath if path.status == .satisfied { if path.usesInterfaceType(.wifi) { return .wifi @@ -23,15 +26,26 @@ public class PathMonitorConnectivityProvider: NSObject, ConnectivityProvider { override init() { super.init() - pathMonitor.pathUpdateHandler = pathUpdateHandler + ensurePathMonitor() } public func start() { - pathMonitor.start(queue: .main) + ensurePathMonitor() } public func stop() { - pathMonitor.cancel() + _pathMonitor?.cancel() + _pathMonitor = nil + } + + private func ensurePathMonitor() -> NWPathMonitor { + if (_pathMonitor == nil) { + let pathMonitor = NWPathMonitor() + pathMonitor.start(queue: queue) + pathMonitor.pathUpdateHandler = pathUpdateHandler + _pathMonitor = pathMonitor + } + return _pathMonitor! } private func pathUpdateHandler(path: NWPath) { diff --git a/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/ReachabilityConnectivityProvider.swift b/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/ReachabilityConnectivityProvider.swift index 72bb0f19c5..df7d36caa4 100644 --- a/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/ReachabilityConnectivityProvider.swift +++ b/packages/connectivity_plus/connectivity_plus_macos/macos/Classes/ReachabilityConnectivityProvider.swift @@ -2,11 +2,11 @@ import Foundation import Reachability public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider { - private var reachability: Reachability? + private var _reachability: Reachability? public var currentConnectivityType: ConnectivityType { - let reachability = try? self.reachability ?? Reachability() - switch reachability?.connection ?? .unavailable { + let reachability = ensureReachability() + switch reachability.connection ?? .unavailable { case .wifi: return .wifi case .cellular: @@ -18,8 +18,13 @@ public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider { public var connectivityUpdateHandler: ConnectivityUpdateHandler? + override init() { + super.init() + ensureReachability() + } + public func start() { - reachability = try? Reachability() + let reachability = ensureReachability() NotificationCenter.default.addObserver( self, @@ -27,17 +32,25 @@ public class ReachabilityConnectivityProvider: NSObject, ConnectivityProvider { name: .reachabilityChanged, object: reachability) - try? reachability?.startNotifier() + try? reachability.startNotifier() } public func stop() { NotificationCenter.default.removeObserver( self, name: .reachabilityChanged, - object: reachability) + object: _reachability) - reachability?.stopNotifier() - reachability = nil + _reachability?.stopNotifier() + _reachability = nil + } + + private func ensureReachability() -> Reachability { + if (_reachability == nil) { + let reachability = try? Reachability() + _reachability = reachability + } + return _reachability! } @objc private func reachabilityChanged(notification: NSNotification) { diff --git a/packages/connectivity_plus/connectivity_plus_macos/pubspec.yaml b/packages/connectivity_plus/connectivity_plus_macos/pubspec.yaml index 60d33145e5..f6cbd36807 100644 --- a/packages/connectivity_plus/connectivity_plus_macos/pubspec.yaml +++ b/packages/connectivity_plus/connectivity_plus_macos/pubspec.yaml @@ -1,6 +1,6 @@ name: connectivity_plus_macos description: macOS implementation of the connectivity_plus plugin. -version: 1.2.1 +version: 1.2.2 homepage: https://plus.fluttercommunity.dev/ repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/