Reputation: 2858
Let's say we have something like this:
static func convertBoolToString(source: [String: AnyObject]) -> [String:AnyObject]? {
var destination = [String:AnyObject]()
for (key, value) in source {
switch value {
case is Bool:
destination[key] = "\(value as! Bool)"
default:
destination[key] = value
}
}
if destination.isEmpty {
return nil
}
return destination
}
The problem is that if value is Double
or Int
or anything convertible to Bool
it will pass the first case
.
Pls, check the doc: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TypeCasting.html
How to check the value to be exactly and only a Bool
?
Upvotes: 1
Views: 2623
Reputation: 2197
Swift 3 version:
static func convertBoolToString(_ source: [String: Any]?) -> [String:Any]? {
guard let source = source else {
return nil
}
var destination = [String:Any]()
let theTrue = NSNumber(value: true)
let theFalse = NSNumber(value: false)
for (key, value) in source {
switch value {
case let x as NSNumber where x === theTrue || x === theFalse:
destination[key] = "\(x.boolValue)"
default:
destination[key] = value
}
}
return destination
}
Upvotes: 2
Reputation: 130102
This is a tricky problem. Note that neither Bool
, Double
or Int
are AnyObject
, they are all value types. That means they are represented in the dictionary as NSNumber
. However, NSNumber
can convert any value it holds to a Bool
.
Checking which type is inside NSNumber
is not easy. One way to check is to compare references with the result of NSNumber(bool:)
constructors because NSNumber
returns always the same instance:
func convertBoolToString(source: [String: AnyObject]) -> [String:AnyObject]? {
var destination = [String:AnyObject]()
let theTrue = NSNumber(bool: true)
let theFalse = NSNumber(bool: false)
for (key, value) in source {
switch value {
case let x where x === theTrue || x === theFalse:
destination[key] = "\(value as! Bool)"
default:
destination[key] = "not a bool"
}
}
if destination.isEmpty {
return nil
}
return destination
}
let dictionary: [String: AnyObject] = ["testA": true, "testB": 0, "testC": NSNumber(bool: true)]
print("Converted: \(convertBoolToString(dictionary))")
For other options, see get type of NSNumber
Upvotes: 2