[swift]结合 JSON 和字符串字典瞎话

标签: json Swift
发布时间: 2017/3/5 15:23:22
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我想在瞎话了窗体中创建一个 JSON 对象︰

{
    "store": {
        "id": {
            "test": "test"
        },
        "type": "retail",
        "name": "store1"

    }
}

有一种结合中与瞎话 (字符串和 JSON) 使用词典的类型吗? 引用作品,但是当我试图分配一个变量,它抱怨︰ Cannot assign value of type 'String' to type 'JSON?' :

func jsonTest()->String {
    var storeJson = [String: JSON]()
    var someJson = JSON(["test":"test"])
    storeJson["id"] = someJson
    storeJson["type"] = "retail" // <-- works fine
    var name = "store1"
    storeJson["name"] = name // <-- Doesn't work
    var store = JSON(storeJson)
    return store.rawString()!
}

解决方法 1:

原因

storeJson["type"] = "retail"

不同于

storeJson["name"] = name

是因为第一个遵循不同的道路,在代码中。具体来说,它使用 init(stringLiteral value: StringLiteralType) 方法在下列扩展名 ()。

extension JSON: Swift.StringLiteralConvertible {

    public init(stringLiteral value: StringLiteralType) {
        self.init(value)
    }

    public init(extendedGraphemeClusterLiteral value: StringLiteralType) {
        self.init(value)
    }

    public init(unicodeScalarLiteral value: StringLiteralType) {
        self.init(value)
    }
}

之后我们谈论如何解决您特定的问题,我会进一步解释。

可能的解决办法 #1:

storeJson["name"]?.string = name

输出︰

{
  "id" : {
    "test" : "test"
  },
  "type" : "retail"
}

原因

storeJson["name"]?.string = name

不工作,因为我们可能会认为由于可选链接。右现在,如果我们跑这通过调试器,我们不会看到任何有意义的事情。事实上,我们会看到什么。这是一位关于和可能都意味着 storeJson["name"]nil ,所以该语句不执行任何进一步。让我们来验证我们的假说,通过使它炸毁。我们会将行更改为︰

storeJson["name"]!.string = name

在这种情况下,与你当前的代码,你可能会得到

fatal error: unexpectedly found nil while unwrapping an Optional value

你应该这样因为 storeJson["name"] 其实是 nil 。因此,这种解决方案不工作

可能的解决方案 #2:

正如你正确地指出在你的答案,如果你添加 storeJson["name"] = JSON(name) ,你会得到所需的行为︰

func jsonTest()->String {
    var storeJson = [String: JSON]()
    var someJson = JSON(["test":"test"])
    storeJson["id"] = someJson
    storeJson["type"] = "retail" // <-- works fine
    var name = "store1"
    storeJson["name"] = JSON(name) // <-- works!
    var store = JSON(storeJson)
    return store.rawString()!
}

输出︰

{
  "id" : {
    "test" : "test"
  },
  "name" : "store1",
  "type" : "retail"
}

太好了 !因此,此解决方案的工作!现在,在您的代码后面你可以改变它不过你想要使用 .string 等。

解释

回到为什么字符串文字作品。你会注意到在 init ,它有

self.init(value)

穿过了对象 init ,然后穿过case 语句

        ...
        case let string as String:
            _type = .String
            self.rawString = string
        ...

当您调用 storeJson["name"] = JSON(name) ,你要逃出 StringLiteralType init 和简单地进入 switch

因此,你可以互换

storeJson["type"] = "retail"

storeJson["type"] = JSON("retail")
赞助商