diff --git a/Sources/Apollo/JSONStandardTypeConversions.swift b/Sources/Apollo/JSONStandardTypeConversions.swift index 343f98b89d..2ead5a9a63 100644 --- a/Sources/Apollo/JSONStandardTypeConversions.swift +++ b/Sources/Apollo/JSONStandardTypeConversions.swift @@ -105,28 +105,20 @@ extension Optional: JSONEncodable { return NSNull() case .some(let wrapped as JSONEncodable): return wrapped.jsonValue - - // WORKAROUND: For reasons I don't totally understand, when the underlying type is `Any`, - // even though all of these conform to `JSONEncodable`, the `as JSONEncodable` above - // fails, and we need to handle them individually. - case .some(let wrapped as String): - return wrapped.jsonValue - case .some(let wrapped as Int): - return wrapped.jsonValue - case .some(let wrapped as Double): - return wrapped.jsonValue - case .some(let wrapped as Bool): - return wrapped.jsonValue - case .some(let wrapped as [String: Any?]): - return wrapped.jsonValue - case .some(let wrapped as [Any?]): - return wrapped.jsonValue default: fatalError("Optional is only JSONEncodable if Wrapped is") } } } +extension NSDictionary: JSONEncodable { + public var jsonValue: JSONValue { self } +} + +extension NSNull: JSONEncodable { + public var jsonValue: JSONValue { self } +} + extension Dictionary: JSONEncodable { public var jsonValue: JSONValue { return jsonObject diff --git a/Tests/ApolloTests/JSONTests.swift b/Tests/ApolloTests/JSONTests.swift index 83ea39f01b..a72e426b8e 100644 --- a/Tests/ApolloTests/JSONTests.swift +++ b/Tests/ApolloTests/JSONTests.swift @@ -70,7 +70,31 @@ class JSONTests: XCTestCase { let stringFromReserialized = try XCTUnwrap(String(bytes: reserialized, encoding: .utf8)) XCTAssertEqual(stringFromReserialized, """ -{"a_dict":{"a_bool":1,"a_null":null,"an_array":["one","two","three"],"another_dict":{"a_double":23.100000000000001,"a_string":"LOL wat","an_int":8}}} +{"a_dict":{"a_bool":true,"a_null":null,"an_array":["one","two","three"],"another_dict":{"a_double":23.100000000000001,"a_string":"LOL wat","an_int":8}}} """) } + + func testEncodingNSNullDoesNotCrash() throws { + let nsNull = ["aWeirdNull": NSNull()] + let serialized = try JSONSerializationFormat.serialize(value: nsNull) + let stringFromSerialized = try XCTUnwrap(String(data: serialized, encoding: .utf8)) + + XCTAssertEqual(stringFromSerialized, #"{"aWeirdNull":null}"#) + } + + func testEncodingOptionalNSNullDoesNotCrash() throws { + let optionalNSNull = ["aWeirdNull": Optional.some(NSNull())] + let serialized = try JSONSerializationFormat.serialize(value: optionalNSNull) + let stringFromSerialized = try XCTUnwrap(String(data: serialized, encoding: .utf8)) + + XCTAssertEqual(stringFromSerialized, #"{"aWeirdNull":null}"#) + } + + func testEncodingDoubleOptionalsDoesNotCrash() throws { + let doubleOptional = ["aWeirdNull": Optional.some(Optional.none)] + let serialized = try JSONSerializationFormat.serialize(value: doubleOptional) + let stringFromSerialized = try XCTUnwrap(String(data: serialized, encoding: .utf8)) + + XCTAssertEqual(stringFromSerialized, #"{"aWeirdNull":null}"#) + } }