【问题标题】:Casting from Any to anything else fails从 Any 转换到其他任何东西都失败了
【发布时间】:2018-10-17 18:35:51
【问题描述】:

API 给了我一个类型为Any 的变量。打印出来是这样的。

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

我尝试使用SwiftyJSONlet mydata = JSON(data) 那样投射它,但它失败了。我尝试使用 Swift 4 解码技术,但也失败了。我尝试这样做let myData = data as? Dictionary<String, String>,但又失败了。

我不知道在这里做什么。任何提示或解决方案?

【问题讨论】:

  • String吗?什么API?文件怎么说?您也许可以使用type(of:) 来确定变量的实际值
  • 这太可怕了String。真是个面子。
  • ???? (不是笑你,而是和你在一起——去过那里)

标签: swift ably-realtime


【解决方案1】:

终于有机会展示Codable 协议中的隐藏宝石之一。请在 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)
}

定义如此复杂的解析器将一个凌乱的 JSON 字符串映射到您最喜欢的 struct 是多么容易,其纯粹的优雅几乎不会让我感到惊讶。不管你的日期格式看起来多么奇怪,在这个过程中它离被解析的距离几乎不超过 3 行。

关于强制转换,你应该注意一些事情:在 Swift 中,就像在大多数面向对象的语言中一样,只有当(且仅当)它已经 首先是别的东西(但这些知识已经在某个地方丢失了)。由于您的String“只是”一个String(可能伪装成Any),您将无法将其投射到其他任何东西。然而,Codable 协议为您提供了一种从Strings Datadecode 的极好方法,而且非常轻松。这个过程不应该被误认为是演员阵容,即使它看起来大致相同。它是从一个简单的 Data 中创建和初始化另一个结构更合适的对象,您很可能从您选择的普通 Web 服务中获得。

到目前为止很棒,至少在我的书中。

【讨论】:

    【解决方案2】:

    你可以像这样解析它,因为它是一个 json 字符串

    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)
         }
    }
    

    【讨论】:

    • 如果结果类型应该是数组或字典,请停止建议.allowFragments。删除options 参数。并且投射到NSError 的桥是多余的。只需catch { 就足够了。
    猜你喜欢
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-12-24
    相关资源
    最近更新 更多