bignerdranch / Freddy

A reusable framework for parsing JSON in Swift.
MIT License
1.09k stars 120 forks source link

JSONSerialization.makeJSON fails on Linux due to no toll-free bridging #273

Closed mlilback closed 6 years ago

mlilback commented 6 years ago

I'm using swift 4.0.2 on ubuntu 16.04.

JSONSerialization.makeJSON (JSONParsing.swift:57) uses toll-free bridging to get the CFNumberType from an NSNumber.

  1. First, this requires an import CoreFoundation.
  2. this fails with an error message that a NSNumber cannot be converted to CFNumber because of lack of toll-free bridging on Linux.

In my testing, the following switch provides the same functionality ignoring the special #if for 32 bit platforms.

let json = "{\"age\": 44, \"fval\": 3.14, \"cool\": true, \"big\": 34292343589452343}"

let jsonDict = try! JSONSerialization.jsonObject(with: json.data(using: .utf8)!) as! [String: Any]

for aKey in jsonDict.keys {
    switch jsonDict[aKey] {
        case let ival as Int:
            print("got int \(ival)")
        case let dval as Double:
            print("got double \(dval)")
        case let bval as Bool:
            print("got bool \(bval)")
        default:
            print("unsuported type")
    }
}
This outputs 

got double 3.14
got bool true
got int 44
got int 34292343589452343

Looking at the source code it looks like the current implementation uses value types, not NSNumber (unless the undocumented reading option useReferenceNumericTypes is used). The code has conditionals for Apple platforms, but based on commit messages it looks like this is only used with non-Apple platforms and swift 4. However, the switch code does work with swift 3.1 on linux. I have no way to test on 32 bit linux.

I'm happy to make a patch for this, but should it be for Linux only? What about Windows and FreeeBSD? Swift 4 only? Is there a way to limit code to non-Apple platforms for when new platforms are added?

Personally I'm inclined to use the current approach on 32 bit platforms, and one without NSNumber on all 64 bit platforms. Or just ignore 32 bit and use casting on all platforms. That's what the open source version of JSONSerialization does.

zwaldowski commented 6 years ago

Addressed via #279 and #280. Please reopen if there are any problems.