Skip to content

Commit

Permalink
Merge pull request SwiftyJSON#833 from wongzigii/error-handling
Browse files Browse the repository at this point in the history
[4.0.0] Better Error handling
  • Loading branch information
wongzigii authored Apr 16, 2017
2 parents 9b32547 + 06477da commit f9afe96
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 25 deletions.
4 changes: 2 additions & 2 deletions Example/Playground.playground/Contents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ let jsonString = String(data: jsonData!, encoding: .utf8)
*/
import SwiftyJSON

let json1 = JSON(data: jsonData!)
let json1 = try? JSON(data: jsonData!)
/*:
or
*/
Expand All @@ -40,7 +40,7 @@ let json2 = JSON(jsonObject)
or
*/
let dataFromString = jsonString?.data(using: .utf8)
let json3 = JSON(data: dataFromString!)
let json3 = try? JSON(data: dataFromString!)

/*:
### Subscript
Expand Down
23 changes: 10 additions & 13 deletions Source/SwiftyJSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,14 @@ public struct JSON {
Creates a JSON using the data.

- parameter data: The NSData used to convert to json.Top level object in data is an NSArray or NSDictionary
- parameter opt: The JSON serialization reading options. `.AllowFragments` by default.
- parameter opt: The JSON serialization reading options. `[]` by default.
- parameter error: The NSErrorPointer used to return the error. `nil` by default.

- returns: The created JSON
*/
public init(data: Data, options opt: JSONSerialization.ReadingOptions = .allowFragments, error: NSErrorPointer = nil) {
do {
let object: Any = try JSONSerialization.jsonObject(with: data, options: opt)
self.init(jsonObject: object)
} catch let aError as NSError {
if error != nil {
error?.pointee = aError
}
self.init(jsonObject: NSNull())
}
public init(data: Data, options opt: JSONSerialization.ReadingOptions = []) throws {
let object: Any = try JSONSerialization.jsonObject(with: data, options: opt)
self.init(jsonObject: object)
}

/**
Expand All @@ -85,7 +78,11 @@ public struct JSON {
public init(_ object: Any) {
switch object {
case let object as Data:
self.init(data: object)
do {
try self.init(data: object)
} catch {
self.init(jsonObject: NSNull())
}
default:
self.init(jsonObject: object)
}
Expand Down Expand Up @@ -113,7 +110,7 @@ public struct JSON {
@available(*, deprecated: 3.2, message: "Use instead `init(parseJSON: )`")
public static func parse(_ json: String) -> JSON {
return json.data(using: String.Encoding.utf8)
.flatMap { JSON(data: $0) } ?? JSON(NSNull())
.flatMap { try? JSON(data: $0) } ?? JSON(NSNull())
}

/**
Expand Down
31 changes: 27 additions & 4 deletions Tests/SwiftyJSONTests/BaseTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@ class BaseTests: XCTestCase {
}

func testInit() {
let json0 = JSON(data:self.testData)
guard let json0 = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}
XCTAssertEqual(json0.array!.count, 3)
XCTAssertEqual(JSON("123").description, "123")
XCTAssertEqual(JSON(["1": "2"])["1"].string!, "2")
Expand Down Expand Up @@ -76,7 +79,11 @@ class BaseTests: XCTestCase {
}

func testJSONDoesProduceValidWithCorrectKeyPath() {
let json = JSON(data:self.testData)

guard let json = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}

let tweets = json
let tweets_array = json.array
Expand Down Expand Up @@ -225,7 +232,10 @@ class BaseTests: XCTestCase {
}

func testErrorHandle() {
let json = JSON(data:self.testData)
guard let json = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}
if json["wrong-type"].string != nil {
XCTFail("Should not run into here")
} else {
Expand All @@ -245,7 +255,10 @@ class BaseTests: XCTestCase {
}

func testReturnObject() {
let json = JSON(data:self.testData)
guard let json = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}
XCTAssertNotNil(json.object)
}

Expand All @@ -260,4 +273,14 @@ class BaseTests: XCTestCase {
XCTAssertEqual(NSNumber(value: true), NSNumber(value:true))
}

func testErrorThrowing() {
let invalidJson = "{\"foo\": 300]" // deliberately incorrect JSON
let invalidData = invalidJson.data(using: .utf8)!
do {
_ = try JSON(data: invalidData)
XCTFail("Should have thrown error; we should not have gotten here")
} catch {
// everything is OK
}
}
}
25 changes: 20 additions & 5 deletions Tests/SwiftyJSONTests/PerformanceTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,20 @@ class PerformanceTests: XCTestCase {
func testInitPerformance() {
self.measure {
for _ in 1...100 {
let json = JSON(data:self.testData)
guard let json = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}
XCTAssertTrue(json != JSON.null)
}
}
}

func testObjectMethodPerformance() {
let json = JSON(data:self.testData)
guard let json = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}
self.measure {
for _ in 1...100 {
let object:Any? = json.object
Expand All @@ -62,7 +68,10 @@ class PerformanceTests: XCTestCase {
}

func testArrayMethodPerformance() {
let json = JSON(data:self.testData)
guard let json = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}
self.measure {
for _ in 1...100 {
autoreleasepool {
Expand All @@ -75,7 +84,10 @@ class PerformanceTests: XCTestCase {
}

func testDictionaryMethodPerformance() {
let json = JSON(data:testData)[0]
guard let json = try? JSON(data: self.testData)[0] else {
XCTFail("Unable to parse testData")
return
}
self.measure {
for _ in 1...100 {
autoreleasepool {
Expand All @@ -88,7 +100,10 @@ class PerformanceTests: XCTestCase {
}

func testRawStringMethodPerformance() {
let json = JSON(data:testData)
guard let json = try? JSON(data: self.testData) else {
XCTFail("Unable to parse testData")
return
}
self.measure {
for _ in 1...100 {
autoreleasepool {
Expand Down
5 changes: 4 additions & 1 deletion Tests/SwiftyJSONTests/SequenceTypeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ class SequenceTypeTests: XCTestCase {
func testJSONFile() {
if let file = Bundle(for:BaseTests.self).path(forResource: "Tests", ofType: "json") {
let testData = try? Data(contentsOf: URL(fileURLWithPath: file))
let json = JSON(data:testData!)
guard let json = try? JSON(data: testData!) else {
XCTFail("Unable to parse the data")
return
}
for (index, sub) in json {
switch (index as NSString).integerValue {
case 0:
Expand Down

0 comments on commit f9afe96

Please sign in to comment.