Skip to content

Commit 6294cb3

Browse files
committed
Handling HTTP status
1 parent 85af055 commit 6294cb3

File tree

4 files changed

+61
-23
lines changed

4 files changed

+61
-23
lines changed

AlamofireJsonToObjects.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
88
#
99

1010
s.name = "AlamofireJsonToObjects"
11-
s.version = "2.3.2"
11+
s.version = "2.4.0"
1212
s.summary = "An Alamofire extension which converts JSON response data into swift objects using EVReflection"
1313
s.description = "An Alamofire extension which converts JSON response data into swift objects using EVReflection. "
1414
s.homepage = "https://github.com/evermeer/AlamofireJsonToObjects"

AlamofireJsonToObjects/AlamofireJsonToObjects.swift

+13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ import EVReflection
1212
import Alamofire
1313

1414

15+
open class EVNetworkingObject: EVObject {
16+
override open func initValidation(_ dict: NSDictionary) {
17+
if dict["__response_statusCode"] != nil {
18+
self.addStatusMessage(DeserializationStatus.Custom, message: "HTTP Status = \(dict["__response_statusCode"]!)")
19+
}
20+
}
21+
22+
override open func propertyMapping() -> [(String?, String?)] {
23+
return [("__response_statusCode", nil)]
24+
}
25+
}
26+
27+
1528
extension DataRequest {
1629

1730
enum ErrorCode: Int {

AlamofireJsonToObjectsTests/AlamofireJsonToObjectsTests.swift

+41-20
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import XCTest
1010
import Alamofire
1111
import EVReflection
1212

13-
class WeatherResponse: EVObject {
13+
class WeatherResponse: EVNetworkingObject {
1414
var location: String?
1515
var three_day_forecast: [Forecast] = [Forecast]()
1616
}
1717

18-
class Forecast: EVObject {
18+
class Forecast: EVNetworkingObject {
1919
var day: String?
2020
var temperature: NSNumber?
2121
var conditions: String?
@@ -44,7 +44,6 @@ class AlamofireJsonToObjectsTests: XCTestCase {
4444
Alamofire.request(URL)
4545
.responseObject { (response: DataResponse<WeatherResponse>) in
4646

47-
exp.fulfill()
4847
if let result = response.result.value {
4948
print("\(result.description)")
5049
XCTAssertNotNil(result.location, "Location should not be nil")
@@ -59,15 +58,38 @@ class AlamofireJsonToObjectsTests: XCTestCase {
5958
} else {
6059
XCTAssert(true, "no result from service")
6160
}
62-
63-
61+
exp.fulfill()
6462
}
6563

6664
waitForExpectations(timeout: 10) { error in
6765
XCTAssertNil(error, "\(error)")
6866
}
6967
}
7068

69+
70+
func testErrorResponse() {
71+
let URL: URLConvertible = "http://raw.githubusercontent.com/evermeer/AlamofireJsonToObjects/master/AlamofireJsonToObjectsTests/non_existing_file"
72+
let exp = expectation(description: "\(URL)")
73+
74+
Alamofire.request(URL)
75+
.responseObject { (response: DataResponse<WeatherResponse>) in
76+
77+
if let result = response.result.value {
78+
print("\(result.description)")
79+
print("\(result.evReflectionStatuses)")
80+
XCTAssertNotNil(result.evReflectionStatuses.first?.0 == DeserializationStatus.Custom, "A custom validation error should have been added")
81+
XCTAssertNotNil(result.evReflectionStatuses.first?.1 == "HTTP Status = 404", "The custom validation error should be for a 404 HTTP status error")
82+
} else {
83+
XCTAssert(true, "no result from service")
84+
}
85+
exp.fulfill()
86+
}
87+
88+
waitForExpectations(timeout: 10) { error in
89+
XCTAssertNil(error, "\(error)")
90+
}
91+
}
92+
7193

7294
func testResponseObject2() {
7395
// This is an example of a functional test case.
@@ -77,19 +99,19 @@ class AlamofireJsonToObjectsTests: XCTestCase {
7799
Alamofire.request(Router.list1())
78100
.responseObject { (response: DataResponse<WeatherResponse>) in
79101

80-
exp.fulfill()
81-
if let result = response.result.value {
82-
XCTAssertNotNil(result.location, "Location should not be nil")
83-
XCTAssertNotNil(result.three_day_forecast, "ThreeDayForcast should not be nil")
84-
XCTAssertEqual(result.three_day_forecast.count, 3, "ThreeDayForcast should have 2 items.")
85-
for forecast in result.three_day_forecast {
86-
XCTAssertNotNil(forecast.day, "day should not be nil")
87-
XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
88-
XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
89-
}
90-
} else {
91-
XCTAssert(true, "Could not get result from service")
102+
if let result = response.result.value {
103+
XCTAssertNotNil(result.location, "Location should not be nil")
104+
XCTAssertNotNil(result.three_day_forecast, "ThreeDayForcast should not be nil")
105+
XCTAssertEqual(result.three_day_forecast.count, 3, "ThreeDayForcast should have 2 items.")
106+
for forecast in result.three_day_forecast {
107+
XCTAssertNotNil(forecast.day, "day should not be nil")
108+
XCTAssertNotNil(forecast.conditions, "conditions should not be nil")
109+
XCTAssertNotNil(forecast.temperature, "temperature should not be nil")
92110
}
111+
} else {
112+
XCTAssert(true, "Could not get result from service")
113+
}
114+
exp.fulfill()
93115
}
94116

95117
waitForExpectations(timeout: 10) { error in
@@ -106,7 +128,6 @@ class AlamofireJsonToObjectsTests: XCTestCase {
106128
Alamofire.request(URL, method: HTTPMethod.get, parameters: nil, encoding: URLEncoding.default, headers: nil)
107129
.responseObject { (response: DataResponse<WeatherResponse>) in
108130

109-
exp.fulfill()
110131
if let result = response.result.value {
111132
XCTAssertNotNil(result.location, "Location should not be nil")
112133
XCTAssertNotNil(result.three_day_forecast, "ThreeDayForcast should not be nil")
@@ -119,6 +140,7 @@ class AlamofireJsonToObjectsTests: XCTestCase {
119140
} else {
120141
XCTAssert(true, "Could not get result from service")
121142
}
143+
exp.fulfill()
122144
}
123145

124146
waitForExpectations(timeout: 10) { error in
@@ -133,7 +155,6 @@ class AlamofireJsonToObjectsTests: XCTestCase {
133155

134156
Alamofire.request(URL)
135157
.responseArray { (response: DataResponse<[Forecast]>) in
136-
exp.fulfill()
137158

138159
if let result = response.result.value {
139160
for forecast in result {
@@ -144,7 +165,7 @@ class AlamofireJsonToObjectsTests: XCTestCase {
144165
} else {
145166
XCTAssert(true, "Service did not return a result")
146167
}
147-
168+
exp.fulfill()
148169
}
149170

150171
waitForExpectations(timeout: 10) { error in

README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ import AlamofireJsonToObjects
5454
## Sample code
5555

5656
```
57-
class WeatherResponse: EVObject {
57+
class WeatherResponse: EVNetworkingObject {
5858
var location: String?
5959
var three_day_forecast: [Forecast] = [Forecast]()
6060
}
6161
62-
class Forecast: EVObject {
62+
class Forecast: EVNetworkingObject {
6363
var day: String?
6464
var temperature: NSNumber?
6565
var conditions: String?
@@ -105,6 +105,10 @@ The code above will pass the folowing json to the objects:
105105
## Advanced object mapping
106106
AlamofireJsonToObjects is based on [EVReflection](https://github.com/evermeer/EVReflection) and you can use all [EVReflection](https://github.com/evermeer/EVReflection) features like property mapping, converters, validators and key kleanup. See [EVReflection](https://github.com/evermeer/EVReflection) for more information.
107107

108+
## Handling HTTP status >= 300
109+
When a network call returns a [HTTP error status](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) (300 or highter) then this will be added to the evReflectionStatuses as a custom error. see the unit test testErrorResponse as a sample. In order to make this work, you do have to set EVNetworkingObject as your bass class and not EVObject. You then also have to be aware that if you override the initValidation or the propertyMapping function, that you also have to call the super for that function.
110+
111+
108112
## License
109113

110114
AlamofireJsonToObjects is available under the MIT 3 license. See the LICENSE file for more info.

0 commit comments

Comments
 (0)