From 1d7f17d6cd9017fe7e86418b8739a1c0c6d83223 Mon Sep 17 00:00:00 2001 From: Nikolay Morev Date: Fri, 14 Apr 2023 17:41:51 +0300 Subject: [PATCH] Fix 0 and 1 encoded as bool in JSON --- Sources/AnyCodable/AnyEncodable.swift | 11 +++++++++-- Tests/AnyCodableTests/AnyEncodableTests.swift | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Sources/AnyCodable/AnyEncodable.swift b/Sources/AnyCodable/AnyEncodable.swift index d5530e5..c166319 100644 --- a/Sources/AnyCodable/AnyEncodable.swift +++ b/Sources/AnyCodable/AnyEncodable.swift @@ -58,6 +58,10 @@ extension _AnyEncodable { #endif case is Void: try container.encodeNil() + #if canImport(Foundation) + case let number as NSNumber: + try encode(nsnumber: number, into: &container) + #endif case let bool as Bool: try container.encode(bool) case let int as Int: @@ -87,8 +91,6 @@ extension _AnyEncodable { case let string as String: try container.encode(string) #if canImport(Foundation) - case let number as NSNumber: - try encode(nsnumber: number, into: &container) case let date as Date: try container.encode(date) case let url as URL: @@ -108,6 +110,11 @@ extension _AnyEncodable { #if canImport(Foundation) private func encode(nsnumber: NSNumber, into container: inout SingleValueEncodingContainer) throws { + if CFGetTypeID(nsnumber) == CFBooleanGetTypeID() { + try container.encode(nsnumber.boolValue) + return + } + switch Character(Unicode.Scalar(UInt8(nsnumber.objCType.pointee))) { case "B": try container.encode(nsnumber.boolValue) diff --git a/Tests/AnyCodableTests/AnyEncodableTests.swift b/Tests/AnyCodableTests/AnyEncodableTests.swift index bd81b70..71c2067 100644 --- a/Tests/AnyCodableTests/AnyEncodableTests.swift +++ b/Tests/AnyCodableTests/AnyEncodableTests.swift @@ -124,6 +124,17 @@ class AnyEncodableTests: XCTestCase { XCTAssert(encodedJSONObject["double"] is Double) } + func testEncodeNSNumberOneAndZeroAsInt() throws { + let dictionary: [NSNumber] = [0, 1] + + let encoder = JSONEncoder() + + let json = try encoder.encode(AnyEncodable(dictionary)) + let jsonString = String(data: json, encoding: .utf8)! + + XCTAssertEqual(jsonString, "[0,1]") + } + func testStringInterpolationEncoding() throws { let dictionary: [String: AnyEncodable] = [ "boolean": "\(true)",