When compiling with Swift 3, serializing with JSONSerialization translates boolean (Bool) values to 1 or 0 instead of true or false

Originator:jbrayton
Number:rdar://27937005 Date Originated:2016-08-20
Status:Duplicate of 27897683 (Open) Resolved:Fixed in Xcode 8 GM
Product:Developer Tools Product Version:Xcode Version 8.0 beta 6 (8S201h) on Sierra (macOs 10.12 Beta (16A294a))
Classification:Serious Bug Reproducible:Always
 
When using Swift 2.3, NSJSONSerialization serializes the dictionary ["first": true, "second": false] as:

{"first":true,"second":false}

When using Swift 3.0, JSONSerialization serializes the same dictionary as:

{"first":1,"second":0}

Some web service APIs, including the Gmail API, will reject 1 or 0 when expecting a boolean value.


Steps to reproduce:

1.  In a Swift 2.3 project, run this unit test. It will pass.

    func testJson() {
        
        let inputJsonDictionary = ["first": true, "second": false]
        
        guard let data = try? NSJSONSerialization.dataWithJSONObject(inputJsonDictionary, options: []) else {
            XCTFail()
            return
        }
        
        guard let jsonString = String(data: data, encoding: NSUTF8StringEncoding) else {
            XCTFail()
            return
        }
        print(jsonString)
        XCTAssertTrue(jsonString == "{\"first\":true,\"second\":false}" || jsonString == "{\"second\":false},\"first\":true")
    }

2.  In a Swift 3.0 project, run this unit test

    func testJson() {
        
        let inputJsonDictionary = ["first": true, "second": false]
        
        guard let data = try? JSONSerialization.data(withJSONObject: inputJsonDictionary, options: []) else {
            XCTFail()
            return
        }
        
        guard let jsonString = String(data: data, encoding: String.Encoding.utf8) else {
            XCTFail()
            return
        }
        print(jsonString)
        XCTAssertTrue(jsonString == "{\"first\":true,\"second\":false}" || jsonString == "{\"second\":false},\"first\":true")
    }
    

Expected Results:

I would expect the Swift 3.0 unit test to pass.


Actual Results:

The Swift 3.0 unit test fails. The value of jsonString is:

{"first":1,"second":0}  - or -  {"second":0,"first":1}


Configuration:

I encountered this using Xcode 8.0 beta 6 while developing an iOS app. I can reproduce the bug both on the simulator and on an iPod Touch running iOS 10 beta 7 (14A5345a). I am not certain, but I believe this is a change in behavior since Xcode 8.0 beta 5.

Additional Notes:

I think this is an important bug. Many app developers write apps that talk to web services outside of their control.

Thank you for taking a look.

Comments

Fixed in Xcode 8 GM

This is fixed in the Xcode 8 GM.

bugs.swift.org status

I also filed this as: https://bugs.swift.org/browse/SR-2441

It was marked as a duplicate of https://bugs.swift.org/browse/SR-2381 - which is marked as "Resolved". I hope that means the issue will be addressed in the next beta.


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!