Kira
Kira

Reputation: 1603

Casting from Any to anything else fails

API gives me back a variable that has type Any. It looks like this when I print it.

{
  "sender" : "Kira",
  "created" : "08.05.2018",
  "text" : "Cncncm"
}

I tried to use SwiftyJSON to cast it like this let mydata = JSON(data) but it failes. I tried to use Swift 4 decoding technique but that failed as well. I tried to do this let myData = data as? Dictionary<String, String> but it fails again.

I am clueless what to do here. Any tips or solutions?

Upvotes: 0

Views: 84

Answers (2)

Patru
Patru

Reputation: 4551

Finally a chance to demonstrate one of the Codable protocols hidden gems. Please run the following in a Playground:

import Cocoa

let jsonData = """
    {
      "sender" : "Kira",
      "created" : "08.05.2018",
      "text" : "Cncncm"
    }
    """.data(using: .utf8)!

struct SenderText: Codable {
    let sender: String
    let created: Date
    let text: String
}

let dayFormatter = DateFormatter()
dayFormatter.dateFormat = "dd.MM.yyyy"
let date = dayFormatter.date(from:"08.05.2018")
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dayFormatter)

do {
    let sendText = try decoder.decode(SenderText.self, from: jsonData)
    print(sendText)
} catch {
    print(error)
}

The sheer elegance of how easy it is to define such an intricate parser mapping a messy JSON-string to your favourite struct will hardly ever stop to amaze me. No matter how weird your date format looks, it is hardly more than 3 lines away from being parsed during the process.

There is something in regard to casting you should note though: In Swift, as in most object oriented languages, you can only cast something to something else if (and only if) it already is something else in the first place (but that knowledge has been lost somewhere). Since your String is "just" a String (in disguise of an Any maybe) you won't be able to cast it to anything else. However the Codable protocol provides you with a terrific means to decode from the Strings Data with astonishing ease. This process should not be mistaken as a cast, even if it looks largely the same. It is the creation and initialisation of another, more fittingly structured object from a simple piece of Data that you are likely to have gotten from your average web service of choice.

Great so far, at least in my book.

Upvotes: 1

Shehata Gamal
Shehata Gamal

Reputation: 100503

You can parse it like this as it's a json string

let trd = yourVar as? String

if let data = trd?.data(using: String.Encoding.utf8) {

   do {
           var content = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:String]

           print(content)

      } 
      catch let error as NSError {

           print(error)
     }
}

Upvotes: 0

Related Questions