[swift-users] Foundation on Linux `CFBooleanGetTypeID`/`CFGetTypeID`

Ryan Lovelett swift-dev at ryan.lovelett.me
Tue May 24 14:57:10 CDT 2016


On Tue, May 24, 2016, at 02:03 PM, Tony Parker wrote:
> Hi Ryan,
> 
> NSNumber basically exists to hide the underlying number type.
> 
> Why not use `func boolValue` instead, if you need a true/false answer?

It's not so much that I need a bool _answer_. Its more that I need to
know what _type_ the NSNumber represents.

I started playing around with this as a stand alone quandary. I tried to
come up with portable code that ran on _both_ Darwin and Glibc (i.e.,
OSX and Linux). And think I'm even more perplexed than I was before.

Ok so the goal. To turn JSON into Swift base types (e.g., Int, Bool,
String, etc...). For example, given the JSON below I'd like to end up
with two variables `bool` and `number` that are both correctly typed
(e.g., `bool: Bool` and `number: Int`).

{
  "number": 1234567890,
  "bool": false
}

I came up with the following code.

import Foundation

let jsonStr = "{\"number\": 1234567890, \"bool\": false}"
let jsonData = jsonStr.data(using: NSUTF8StringEncoding)
let obj = jsonData.flatMap({ try? NSJSONSerialization.jsonObject(with:
$0) })!
let v = obj as! [String : Any]
let bool = v["bool"] as? Bool
let number = v["number"] as? Bool

This is the closest to a "portable" solution as I could get in an hour
of trying. And to top it off: it isn't portable. The biggest portability
issue is that on Glibc `obj` is `[String : Any]` where on Darwin it is
`[String : AnyObject]`. But the real head scratcher is:

let number = v["number"] as? Bool

On Glibc `number` is `Bool? = nil` 🎉
On Darwin `number` is `Bool? = true` 😤

The rub is that the way Glibc worked in that example is what I was
trying to achieve `CFBooleanGetTypeID` and `CFGetTypeID` originally. I
was _expecting_ the Darwin behavior since that has always been the
behavior. I was _not expecting_ the Glibc behavior as this is different
than Darwin. All that having been said: I prefer the Glibc behavior.

I'm not sure if this is expected behavior a bug. Or something else
entirely.

> 
> - Tony
> 
>> On May 23, 2016, at 2:01 PM, Ryan Lovelett via swift-users <swift-users at swift.org> wrote:
>> 
>> On Mon, May 23, 2016, at 04:33 PM, Jens Alfke wrote:
>>>  
>>>> On May 23, 2016, at 12:25 PM, Ryan Lovelett via swift-users <swift-users at swift.org> wrote:
>>>>  
>>>> However it seems that Foundation on Linux has neither
>>>> `CFBooleanGetTypeID` or `CFGetTypeID`.
>>>  
>>> Those are part of CoreFoundation, the C library on which the Mac/iOS Foundation framework is built. The two have a complicated relationship; Foundation exposes most but not all of the CoreFoundation APIs as Objective-C, but there are still some features you have to drop down to C to use. This is one.
>>>  
>>> But I think you’re using the in-development Swift Foundation? That’s a different implementation entirely. Presumably it will have some API of its own to determine the type of a number.
>>  
>> Yes I'm using the in-development Swift Foundation. From what I can tell this version is the one that will be used on non-Darwin platforms.
>>  
>> Assuming that such an API does not currently exist on NSNumber, I'm reasonably confident that it does not, does this mean that a Swift Evolution thread has to be started to add it?
>>  
>>>  
>>> —Jens
>>  
>> _______________________________________________
>> swift-users mailing list
>> swift-users at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-users


More information about the swift-users mailing list