From 2bf09f9601dd8ace2ec7cb596aa653f3637c9bb1 Mon Sep 17 00:00:00 2001 From: Harlan Kellaway Date: Tue, 1 Sep 2020 09:02:01 -0400 Subject: [PATCH 1/3] Method to create JSON Array from Data --- Sources/Gloss/ExtensionArray.swift | 29 +++++++++++++++++++++++++++++ Sources/GlossTests/GlossTests.swift | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/Sources/Gloss/ExtensionArray.swift b/Sources/Gloss/ExtensionArray.swift index b149068..17b11ea 100644 --- a/Sources/Gloss/ExtensionArray.swift +++ b/Sources/Gloss/ExtensionArray.swift @@ -53,6 +53,35 @@ public extension Array where Element: JSONDecodable & Decodable { return models } + /** + Returns array of new objects created from provided data. + If creation of JSON or any decodings fail, nil is returned. + + - parameter data: Raw JSON data. + - parameter jsonDecoder: A `Swift.JSONDecoder`. + - parameter serializer: Serializer to use when creating JSON from data. + - parameter ooptions: Options for reading the JSON data. + - parameter logger: Logs issues with `Swift.Decodable`. + + - returns: Object or nil. + */ + static func from(decodableData data: Data, jsonDecoder: JSONDecoder = JSONDecoder(), serializer: JSONSerializer = GlossJSONSerializer(), options: JSONSerialization.ReadingOptions = .mutableContainers, logger: GlossLogger = GlossLogger()) -> [Element]? { + do { + let jsonArray = try jsonDecoder.decode([Element].self, from: data) + return jsonArray + } catch { + logger.log(message: "Swift.Decodable error: \(error)") + + guard + let jsonArray = serializer.jsonArray(from: data, options: options), + let models = [Element].from(jsonArray: jsonArray) else { + return nil + } + + return models + } + } + } public extension Array where Element: JSONEncodable & Encodable { diff --git a/Sources/GlossTests/GlossTests.swift b/Sources/GlossTests/GlossTests.swift index 0723c00..bfa7114 100644 --- a/Sources/GlossTests/GlossTests.swift +++ b/Sources/GlossTests/GlossTests.swift @@ -332,7 +332,7 @@ class GlossTests: XCTestCase { func testModelArrayFromJSONArrayRawData() { let data = try! JSONSerialization.data(withJSONObject: testJSONArray!, options: []) - let modelArray = [TestModel].from(data: data) + let modelArray: [TestModel]? = .from(decodableData: data) XCTAssertNotNil(modelArray, "Model array from Data should not be nil.") } From d2c16d88e969be6d77eccf4d02ab55424a48327f Mon Sep 17 00:00:00 2001 From: Harlan Kellaway Date: Tue, 1 Sep 2020 08:52:34 -0400 Subject: [PATCH 2/3] Fix not using param --- Sources/Gloss/ExtensionArray.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Gloss/ExtensionArray.swift b/Sources/Gloss/ExtensionArray.swift index 17b11ea..13803e4 100644 --- a/Sources/Gloss/ExtensionArray.swift +++ b/Sources/Gloss/ExtensionArray.swift @@ -167,7 +167,7 @@ public extension Array where Element: JSONDecodable { */ static func from(data: Data, serializer: JSONSerializer = GlossJSONSerializer(), options: JSONSerialization.ReadingOptions = .mutableContainers) -> [Element]? { guard - let jsonArray = (try? JSONSerialization.jsonObject(with: data, options: options)) as? [JSON], + let jsonArray = serializer.jsonArray(from: data, options: options), let models = [Element].from(jsonArray: jsonArray) else { return nil } From ec176609b6c3f72a547cc335c2049fc054f32e41 Mon Sep 17 00:00:00 2001 From: Harlan Kellaway Date: Tue, 1 Sep 2020 09:02:09 -0400 Subject: [PATCH 3/3] Consistent syntax in tests --- Sources/GlossTests/GlossTests.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/GlossTests/GlossTests.swift b/Sources/GlossTests/GlossTests.swift index bfa7114..455a64d 100644 --- a/Sources/GlossTests/GlossTests.swift +++ b/Sources/GlossTests/GlossTests.swift @@ -143,7 +143,7 @@ class GlossTests: XCTestCase { } func testModelsFromJSONArrayProducesValidModels() { - let result = [TestModel].from(decodableJSONArray: testJSONArray!) + let result: [TestModel]? = .from(decodableJSONArray: testJSONArray!) let model1: TestModel = result![0] let model2: TestModel = result![1] @@ -206,7 +206,7 @@ class GlossTests: XCTestCase { func testModelsFromJSONArrayReturnsNilIfDecodingFails() { testJSONArray![0].removeValue(forKey: "bool") - let result = [TestModel].from(decodableJSONArray: testJSONArray!) + let result: [TestModel]? = .from(decodableJSONArray: testJSONArray!) XCTAssertNil(result, "Model array from JSON array should be nil is any decoding fails.") } @@ -303,7 +303,7 @@ class GlossTests: XCTestCase { invalidJSON.removeValue(forKey: "bool") var jsonArray = testJSONArray! jsonArray.append(invalidJSON) - let result = [TestModel].from(decodableJSONArray: jsonArray) + let result: [TestModel]? = .from(decodableJSONArray: jsonArray) XCTAssertNil(result, "JSON array from model array should be nil is any encoding fails.") } @@ -325,7 +325,7 @@ class GlossTests: XCTestCase { func testModelFromJSONRawData() { let data = try! JSONSerialization.data(withJSONObject: testModelsJSON!, options: []) - let model = TestModel(data: data) + let model: TestModel? = .from(decodableData: data) XCTAssertNotNil(model, "Model from Data should not be nil.") }