Casting in Swift doesn't work as expected
| Originator: | mihirpmehta | ||
| Number: | rdar://32072227 | Date Originated: | 09-May-2017 03:54 PM |
| Status: | Open | Resolved: | No |
| Product: | iOS + SDK | Product Version: | 10.3.1 |
| Classification: | Core Foundation | Reproducible: | Everytime |
I have created a custom protocol,which i am planning to use in place of Any
But i doesn't work when i try to cast it from JSONSerialization.jsonObject
import Foundation
import CoreFoundation
//MARK:- Protocol
public protocol StringOrNumber {}
//MARK:- Protocol Extension
extension String:StringOrNumber {}
extension NSNumber:StringOrNumber {}
extension Bool:StringOrNumber {}
extension Float:StringOrNumber {}
extension Int32:StringOrNumber {}
extension Int64:StringOrNumber {}
extension Int:StringOrNumber {}
extension Double:StringOrNumber {}
extension Dictionary:StringOrNumber {}
extension Array:StringOrNumber {}
extension NSDictionary:StringOrNumber {}
extension NSArray:StringOrNumber {}
extension NSString:StringOrNumber {}
extension NSNull:StringOrNumber {}
//MARK:- Code
private func readJson() {
let d = ["first":"john", "last":"doe"] as [String:Any]
if let data = try? JSONSerialization.data(withJSONObject: d, options: []) {
if let json = try? JSONSerialization.jsonObject(with: data, options: []) {
// This Code Works ↓ ↓ ↓ ↓ ↓
if let object = json as? [String: Any] {
// json is a dictionary
print("Hello World: \(object)")
if let newObject:[String:StringOrNumber] = object as? [String:StringOrNumber] {
// json is a newer dictionary
print(newObject)
}
}
//This Code Doesn't work ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
let object:[String: StringOrNumber]? = json as? [String: StringOrNumber]
// json is a dictionary
print(object ?? "Dictionary is Empty")
}
}
}
readJson()
I don't understand why the first piece of code doesn't works and 2nd one does ...
Thanks
Comments
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!
Because downcasting can fail
Use optional value of the type you are trying to downcast to.
let object:[String: StringOrNumber?]? = json as? [String: StringOrNumber?] // json is a dictionary print(object ?? "Dictionary is Empty")
It will print below: ["first": Optional(john), "last": Optional(doe)]