使用Swifty将字典中的JSON和String组合在一起

时间:2015-11-13 01:44:22

标签: json swift dictionary swifty-json

我想在Swifty中创建一个格式为:

的JSON对象
{
    "store": {
        "id": {
            "test": "test"
        },
        "type": "retail",
        "name": "store1"

    }
}

有没有办法将字典中的类型组合起来与Swifty(String和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()!
}

2 个答案:

答案 0 :(得分:4)

原因

storeJson["type"] = "retail"

的工作方式与

不同
storeJson["name"] = name

是因为第一个跟随代码中的不同路径。具体来说,它使用以下扩展名中的init(stringLiteral value: StringLiteralType)方法(source)。

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
由于可选的链接,

无法正常工作。现在,如果我们通过调试器运行它,我们就不会看到任何有意义的东西。事实上,我们会看到 nothing 。这有点令人担忧,可能意味着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 statement

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

当您致电storeJson["name"] = JSON(name)时,您正在跳过StringLiteralType init,只需进入switch

因此,您可以互换

storeJson["type"] = "retail"

storeJson["type"] = JSON("retail")

答案 1 :(得分:0)

事实证明它可以改变:

storeJson["name"] = name

storeJson["name"] = JSON(name)