@@ -10,49 +10,80 @@ import Foundation
1010import Connectivity
1111import EmitterKit
1212class Networking {
13- static let connectivity = Connectivity ( )
13+ static private let connectivity = Connectivity ( )
14+
15+ static var status : ConnectivityStatus = . determining {
16+ didSet {
17+ if oldValue != status {
18+ statusChanged. emit ( status)
19+ }
20+ }
21+ }
1422 static let statusChanged = Event < ConnectivityStatus > ( )
23+
1524 static func startMonitor ( ) {
1625 connectivity. whenConnected = { connectivity in
17- Networking . statusChanged . emit ( connectivity. status)
26+ Networking . status = connectivity. status
1827 }
19-
28+
2029 connectivity. whenDisconnected = { connectivity in
21- Networking . statusChanged . emit ( connectivity. status)
30+ Networking . status = connectivity. status
2231 }
2332 connectivity. startNotifier ( )
2433 }
25- static func isConnected ( _ completion: @escaping ( Bool ) -> Void ) {
34+
35+ static func checkConnected ( _ completion: @escaping ( Bool ) -> Void ) {
2636 if ( connectivity. status == . notConnected) {
2737 return completion ( false )
2838 }
2939 var returned = false
3040 connectivity. checkConnectivity { connectivity in
3141 if ( !returned) {
3242 returned = true
33- let accepted : [ ConnectivityStatus ] = [
34- . connected,
35- . connectedViaCellular,
36- . connectedViaWiFi
37- ]
38- completion ( accepted. contains ( connectivity. status) )
43+
44+ completion ( statusConsideredConnected ( connectivity. status) )
3945 }
4046 }
41-
42- Utilities . delay ( 2000 ) {
47+
48+ Utilities . delay ( 1000 ) {
4349 if ( !returned) {
4450 returned = true
4551 completion ( false )
4652 }
4753 }
4854 }
49-
55+
56+ static func whenConnected ( _ completion: @escaping ( ) -> Void ) {
57+ checkConnected { connected in
58+ if ( connected) { return completion ( ) }
59+
60+ statusChanged. once { status in
61+ if ( isConnected) { return completion ( ) }
62+ whenConnected ( completion)
63+ }
64+ }
65+
66+ }
67+
68+ static var isConnected : Bool {
69+ return statusConsideredConnected ( status)
70+ }
71+
72+ static func statusConsideredConnected ( _ status: ConnectivityStatus ) -> Bool {
73+ let accepted : [ ConnectivityStatus ] = [
74+ . connected,
75+ . connectedViaCellular,
76+ . connectedViaWiFi
77+ ]
78+ return accepted. contains ( connectivity. status)
79+ }
80+
5081 static func tcpPortIsAvailable( _ port: UInt ) -> Bool {
5182 let socketFileDescriptor = socket ( AF_INET, SOCK_STREAM, 0 )
5283 if socketFileDescriptor == - 1 {
5384 return false
5485 }
55-
86+
5687 var addr = sockaddr_in ( )
5788 let sizeOfSockkAddr = MemoryLayout< sockaddr_in> . size
5889 addr. sin_len = __uint8_t ( sizeOfSockkAddr)
@@ -62,7 +93,7 @@ class Networking {
6293 addr. sin_zero = ( 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 )
6394 var bind_addr = sockaddr ( )
6495 memcpy ( & bind_addr, & addr, Int ( sizeOfSockkAddr) )
65-
96+
6697 if Darwin . bind ( socketFileDescriptor, & bind_addr, socklen_t ( sizeOfSockkAddr) ) == - 1 {
6798 release ( socket: socketFileDescriptor)
6899 return false
@@ -74,15 +105,15 @@ class Networking {
74105 release ( socket: socketFileDescriptor)
75106 return true
76107 }
77-
108+
78109 static func getAvailabilePort ( _ start: UInt ) -> UInt {
79110 var port = start
80111 while !tcpPortIsAvailable( port) {
81112 port += 1
82113 }
83114 return port
84115 }
85-
116+
86117 static func release( socket: Int32 ) {
87118 Darwin . shutdown ( socket, SHUT_RDWR)
88119 close ( socket)
0 commit comments