Skip to content
This repository was archived by the owner on Oct 29, 2021. It is now read-only.

Commit aef26b8

Browse files
author
Alex Rupérez
committed
Release 0.1.2 with network reachability.
1 parent cd7ba6d commit aef26b8

File tree

6 files changed

+238
-14
lines changed

6 files changed

+238
-14
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
# Release 0.1.2
2+
3+
- [x] Network reachability
4+
- [x] HTTP body bug fixed
5+
16
# Release 0.1.1
27

38
- [x] [Alamofire](https://github.com/Alamofire/Alamofire) Implementation
49
- [x] [Moya](https://github.com/Moya/Moya)Provider Compatible
510

611
# Release 0.1.0
712

8-
- [x] First public release.
13+
- [x] First public release

Core/NetReachability.swift

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
//
2+
// NetReachability.swift
3+
// Net
4+
//
5+
// Created by Alex Rupérez on 25/4/17.
6+
//
7+
//
8+
9+
#if !os(watchOS)
10+
import SystemConfiguration
11+
12+
public class NetReachability {
13+
14+
public enum Connection {
15+
case ethernetOrWiFi, wwan
16+
}
17+
18+
public enum Status {
19+
case unknown, unreachable, reachable(Connection)
20+
}
21+
22+
public typealias ReachabilityClosure = (Status) -> Swift.Void
23+
24+
public static let shared = NetReachability()
25+
26+
public var reachable: Bool { return reachableWWAN || reachableEthernetOrWiFi }
27+
28+
public var reachableWWAN: Bool { return current == .reachable(.wwan) }
29+
30+
public var reachableEthernetOrWiFi: Bool { return current == .reachable(.ethernetOrWiFi) }
31+
32+
public var queue = DispatchQueue.main
33+
34+
public var listener: ReachabilityClosure?
35+
36+
public var current: Status {
37+
guard let flags = self.flags else {
38+
return .unknown
39+
}
40+
return status(flags)
41+
}
42+
43+
private var flags: SCNetworkReachabilityFlags? {
44+
var flags = SCNetworkReachabilityFlags()
45+
guard SCNetworkReachabilityGetFlags(reachability, &flags) else {
46+
return nil
47+
}
48+
return flags
49+
}
50+
51+
private let reachability: SCNetworkReachability
52+
private var previous: SCNetworkReachabilityFlags
53+
54+
public convenience init?() {
55+
var address = sockaddr_in()
56+
address.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
57+
address.sin_family = sa_family_t(AF_INET)
58+
59+
guard let reachability = withUnsafePointer(to: &address, { pointer in
60+
return pointer.withMemoryRebound(to: sockaddr.self, capacity: MemoryLayout<sockaddr>.size) {
61+
return SCNetworkReachabilityCreateWithAddress(nil, $0)
62+
}
63+
}) else {
64+
return nil
65+
}
66+
67+
self.init(reachability)
68+
}
69+
70+
public convenience init?(_ host: String) {
71+
guard let reachability = SCNetworkReachabilityCreateWithName(nil, host) else {
72+
return nil
73+
}
74+
75+
self.init(reachability)
76+
}
77+
78+
private init(_ reachability: SCNetworkReachability) {
79+
self.reachability = reachability
80+
self.previous = SCNetworkReachabilityFlags()
81+
}
82+
83+
deinit {
84+
stop()
85+
}
86+
87+
@discardableResult public func start() -> Bool {
88+
var context = SCNetworkReachabilityContext()
89+
context.info = Unmanaged.passUnretained(self).toOpaque()
90+
91+
let callbackEnabled = SCNetworkReachabilitySetCallback(reachability, { (_, flags, info) in
92+
let reachability = Unmanaged<NetReachability>.fromOpaque(info!).takeUnretainedValue()
93+
reachability.notify(flags)
94+
}, &context)
95+
96+
let queueEnabled = SCNetworkReachabilitySetDispatchQueue(reachability, queue)
97+
98+
queue.async {
99+
self.previous = SCNetworkReachabilityFlags()
100+
self.notify(self.flags ?? SCNetworkReachabilityFlags())
101+
}
102+
103+
return callbackEnabled && queueEnabled
104+
}
105+
106+
public func stop() {
107+
SCNetworkReachabilitySetCallback(reachability, nil, nil)
108+
SCNetworkReachabilitySetDispatchQueue(reachability, nil)
109+
}
110+
111+
func notify(_ flags: SCNetworkReachabilityFlags) {
112+
guard previous != flags else {
113+
return
114+
}
115+
116+
previous = flags
117+
listener?(status(flags))
118+
}
119+
120+
func status(_ flags: SCNetworkReachabilityFlags) -> Status {
121+
guard flags.contains(.reachable) else {
122+
return .unreachable
123+
}
124+
125+
var networkStatus: Status = .unreachable
126+
127+
if !flags.contains(.connectionRequired) {
128+
networkStatus = .reachable(.ethernetOrWiFi)
129+
}
130+
131+
if flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic) {
132+
if !flags.contains(.interventionRequired) {
133+
networkStatus = .reachable(.ethernetOrWiFi)
134+
}
135+
}
136+
137+
#if os(iOS)
138+
if flags.contains(.isWWAN) {
139+
networkStatus = .reachable(.wwan)
140+
}
141+
#endif
142+
143+
return networkStatus
144+
}
145+
146+
}
147+
148+
extension NetReachability.Status: Equatable {
149+
150+
public static func ==(lhs: NetReachability.Status, rhs: NetReachability.Status) -> Bool {
151+
switch (lhs, rhs) {
152+
case (.unknown, .unknown):
153+
return true
154+
case (.unreachable, .unreachable):
155+
return true
156+
case let (.reachable(lhsConnectionType), .reachable(rhsConnectionType)):
157+
return lhsConnectionType == rhsConnectionType
158+
default:
159+
return false
160+
}
161+
}
162+
163+
}
164+
165+
extension NetReachability.Status: CustomStringConvertible {
166+
167+
public var description: String {
168+
switch self {
169+
case .reachable(let connection):
170+
return "Reachable: \(connection)"
171+
case .unreachable:
172+
return "Unreachable"
173+
default:
174+
return "Unknown"
175+
}
176+
}
177+
178+
}
179+
180+
extension NetReachability.Status: CustomDebugStringConvertible {
181+
182+
public var debugDescription: String {
183+
return description
184+
}
185+
186+
}
187+
188+
extension NetReachability.Connection: CustomStringConvertible {
189+
190+
public var description: String {
191+
switch self {
192+
case .ethernetOrWiFi:
193+
return "Ethernet/WiFi"
194+
default:
195+
return "WWAN"
196+
}
197+
}
198+
199+
}
200+
201+
extension NetReachability.Connection: CustomDebugStringConvertible {
202+
203+
public var debugDescription: String {
204+
return description
205+
}
206+
207+
}
208+
#endif

Example/Info.plist

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
33
<plist version="1.0">
44
<dict>
5-
<key>NSAppTransportSecurity</key>
6-
<dict>
7-
<key>NSAllowsArbitraryLoads</key>
8-
<true/>
9-
</dict>
105
<key>CFBundleDevelopmentRegion</key>
116
<string>en</string>
127
<key>CFBundleExecutable</key>
@@ -22,9 +17,14 @@
2217
<key>CFBundleShortVersionString</key>
2318
<string>1.0</string>
2419
<key>CFBundleVersion</key>
25-
<string>1.0</string>
20+
<string>$(CURRENT_PROJECT_VERSION)</string>
2621
<key>LSRequiresIPhoneOS</key>
2722
<true/>
23+
<key>NSAppTransportSecurity</key>
24+
<dict>
25+
<key>NSAllowsArbitraryLoads</key>
26+
<true/>
27+
</dict>
2828
<key>UILaunchStoryboardName</key>
2929
<string>LaunchScreen</string>
3030
<key>UIMainStoryboardFile</key>

Net.xcodeproj/project.pbxproj

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
81ACB7E71E84020F006D05DD /* NetContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81ACB7E21E83D0C8006D05DD /* NetContentType.swift */; };
5353
81ACB8041E85443F006D05DD /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 81ACB8021E85443F006D05DD /* Info.plist */; };
5454
81ACB8061E854565006D05DD /* NetRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81ACB8031E85443F006D05DD /* NetRequestTests.swift */; };
55+
81D1C30E1EAF965C008DB282 /* NetReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81D1C30D1EAF965C008DB282 /* NetReachability.swift */; };
56+
81D1C30F1EAF965C008DB282 /* NetReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81D1C30D1EAF965C008DB282 /* NetReachability.swift */; };
57+
81D1C3101EAF965C008DB282 /* NetReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81D1C30D1EAF965C008DB282 /* NetReachability.swift */; };
58+
81D1C3111EAF965C008DB282 /* NetReachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81D1C30D1EAF965C008DB282 /* NetReachability.swift */; };
5559
C588218FED700E8243A6592A /* Pods_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F272790255D2800FEC64E9AC /* Pods_macOS.framework */; };
5660
D51B42421E9D74AE0029620C /* NetCacheControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51B42411E9D74AE0029620C /* NetCacheControl.swift */; };
5761
D51B42431E9D74AE0029620C /* NetCacheControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D51B42411E9D74AE0029620C /* NetCacheControl.swift */; };
@@ -254,6 +258,7 @@
254258
81ACB7E21E83D0C8006D05DD /* NetContentType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetContentType.swift; sourceTree = "<group>"; };
255259
81ACB8021E85443F006D05DD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
256260
81ACB8031E85443F006D05DD /* NetRequestTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetRequestTests.swift; sourceTree = "<group>"; };
261+
81D1C30D1EAF965C008DB282 /* NetReachability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetReachability.swift; sourceTree = "<group>"; };
257262
9F7D88A9A8889F4F28FF0F2E /* Pods_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
258263
B9AE96E101962D64F0C19898 /* Pods-watchOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-watchOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-watchOS/Pods-watchOS.release.xcconfig"; sourceTree = "<group>"; };
259264
BDEBF5187C4616AAB70C6601 /* Pods-watchOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-watchOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-watchOS/Pods-watchOS.debug.xcconfig"; sourceTree = "<group>"; };
@@ -513,6 +518,7 @@
513518
D5468BE91EAD3CAF00E1354D /* NetResponse+Cached​URLResponse.swift */,
514519
D579EE681EAE813A00A2F311 /* NetResponse+HTTPURLResponse.swift */,
515520
818FC92C1E82BFD800FEC5A3 /* NetError.swift */,
521+
81D1C30D1EAF965C008DB282 /* NetReachability.swift */,
516522
);
517523
path = Core;
518524
sourceTree = "<group>";
@@ -1007,6 +1013,7 @@
10071013
files = (
10081014
D579EE111EAE3AF500A2F311 /* NetAlamofire.swift in Sources */,
10091015
818FC9341E82C26200FEC5A3 /* NetResponse.swift in Sources */,
1016+
81D1C30E1EAF965C008DB282 /* NetReachability.swift in Sources */,
10101017
D579EE301EAE7E3200A2F311 /* NetAlamofire+Download.swift in Sources */,
10111018
D5468BE51EAD3C5E00E1354D /* NetRequest+URLRequest.swift in Sources */,
10121019
D579EE7B1EAE8E1C00A2F311 /* NetURLSession+Upload.swift in Sources */,
@@ -1054,6 +1061,7 @@
10541061
files = (
10551062
D579EE121EAE3AF500A2F311 /* NetAlamofire.swift in Sources */,
10561063
818FC9351E82C26300FEC5A3 /* NetResponse.swift in Sources */,
1064+
81D1C30F1EAF965C008DB282 /* NetReachability.swift in Sources */,
10571065
D579EE311EAE7E3200A2F311 /* NetAlamofire+Download.swift in Sources */,
10581066
D5468BE61EAD3C5E00E1354D /* NetRequest+URLRequest.swift in Sources */,
10591067
D579EE831EAE8E1D00A2F311 /* NetURLSession+Upload.swift in Sources */,
@@ -1093,6 +1101,7 @@
10931101
files = (
10941102
D579EE131EAE3AF500A2F311 /* NetAlamofire.swift in Sources */,
10951103
818FC9361E82C26400FEC5A3 /* NetResponse.swift in Sources */,
1104+
81D1C3101EAF965C008DB282 /* NetReachability.swift in Sources */,
10961105
D579EE321EAE7E3200A2F311 /* NetAlamofire+Download.swift in Sources */,
10971106
D5468BE71EAD3C5E00E1354D /* NetRequest+URLRequest.swift in Sources */,
10981107
D579EE8B1EAE8E1E00A2F311 /* NetURLSession+Upload.swift in Sources */,
@@ -1132,6 +1141,7 @@
11321141
files = (
11331142
D579EE141EAE3AF500A2F311 /* NetAlamofire.swift in Sources */,
11341143
818FC9371E82C26400FEC5A3 /* NetResponse.swift in Sources */,
1144+
81D1C3111EAF965C008DB282 /* NetReachability.swift in Sources */,
11351145
D579EE331EAE7E3200A2F311 /* NetAlamofire+Download.swift in Sources */,
11361146
D5468BE81EAD3C5E00E1354D /* NetRequest+URLRequest.swift in Sources */,
11371147
D579EE931EAE8E1E00A2F311 /* NetURLSession+Upload.swift in Sources */,
@@ -1260,8 +1270,8 @@
12601270
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
12611271
CURRENT_PROJECT_VERSION = "$(DYLIB_CURRENT_VERSION)";
12621272
DEVELOPMENT_TEAM = 3VW789WSMP;
1263-
DYLIB_COMPATIBILITY_VERSION = 0.1.0;
1264-
DYLIB_CURRENT_VERSION = 0.1.1;
1273+
DYLIB_COMPATIBILITY_VERSION = 0.1.2;
1274+
DYLIB_CURRENT_VERSION = 0.1.2;
12651275
ENABLE_STRICT_OBJC_MSGSEND = YES;
12661276
ENABLE_TESTABILITY = YES;
12671277
GCC_C_LANGUAGE_STANDARD = gnu99;
@@ -1306,8 +1316,8 @@
13061316
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
13071317
CURRENT_PROJECT_VERSION = "$(DYLIB_CURRENT_VERSION)";
13081318
DEVELOPMENT_TEAM = 3VW789WSMP;
1309-
DYLIB_COMPATIBILITY_VERSION = 0.1.0;
1310-
DYLIB_CURRENT_VERSION = 0.1.1;
1319+
DYLIB_COMPATIBILITY_VERSION = 0.1.2;
1320+
DYLIB_CURRENT_VERSION = 0.1.2;
13111321
ENABLE_STRICT_OBJC_MSGSEND = YES;
13121322
GCC_C_LANGUAGE_STANDARD = gnu99;
13131323
GCC_NO_COMMON_BLOCKS = YES;

NetClient.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'NetClient'
3-
s.version = '0.1.1'
3+
s.version = '0.1.2'
44
s.summary = 'Versatile HTTP networking library written in Swift 3.'
55

66
s.homepage = 'https://github.com/intelygenz/NetClient-iOS'

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
- [x] Request and Response Interceptors
2626
- [x] Asynchronous and synchronous task execution
2727
- [x] Inference of response object type
28+
- [x] Network reachability
2829
- [x] watchOS Compatible
2930
- [x] tvOS Compatible
3031
- [x] macOS Compatible
@@ -70,12 +71,12 @@ let request = NetRequest.builder("YOUR_URL")!
7071
.setCache(.reloadIgnoringLocalCacheData)
7172
.setMethod(.PATCH)
7273
.setTimeout(20)
73-
.setStringBody("body")
74+
.setJSONBody(["foo", "bar"])
7475
.setContentType(.json)
7576
.setServiceType(.background)
7677
.setCacheControls([.maxAge(500)])
7778
.setURLParameters(["foo": "bar"])
78-
.setAcceptEncodings([.gzip])
79+
.setAcceptEncodings([.gzip, .deflate])
7980
.setBasicAuthorization(user: "user", password: "password")
8081
.setHeaders(["foo": "bar"])
8182
.build()

0 commit comments

Comments
 (0)