【问题标题】:Vapor JSON from `[String: Any]` Dictionary来自 `[String: Any]` 字典的蒸汽 JSON
【发布时间】:2017-01-26 23:14:09
【问题描述】:

如果我构建一个 Swift 字典,即[String: Any],我如何将它作为 JSON 返回?我试过这个,但它给了我错误:Argument labels '(node:)' do not match any available overloads

drop.get("test") { request in
    var data: [String: Any] = [:]

    data["name"] = "David"
    data["state"] = "CA"

    return try JSON(node: data)
}

【问题讨论】:

  • 您没有名为 JSON 且第一个参数名为 node 的方法。如果 JSON 是一个类,那么它没有带有名为 node 的第一个参数的 init 方法。
  • 更简单:让 data = ["name": "David", "state": "CA"]
  • JSON 有一个带有node 的init 方法:vapor.github.io/documentation/guide/json.html#response

标签: json swift vapor


【解决方案1】:

令人费解,但这允许您使用 [String:Any].makeNode(),只要内部是 NodeRepresentable、基于 NSNumber 或 NSNull :) --

import Node

enum NodeConversionError : LocalizedError {
    case invalidValue(String,Any)
    var errorDescription: String? {
        switch self {
        case .invalidValue(let key, let value): return "Value for \(key) is not NodeRepresentable - " + String(describing: type(of: value))
        }
    }
}

extension NSNumber : NodeRepresentable {
    public func makeNode(context: Context = EmptyNode) throws -> Node {
        return Node.number(.double(Double(self)))
    }
}

extension NSString : NodeRepresentable {
    public func makeNode(context: Context = EmptyNode) throws -> Node {
        return Node.string(String(self))
    }
}

extension KeyAccessible where Key == String, Value == Any {
    public func makeNode(context: Context = EmptyNode) throws -> Node {
        var mutable: [String : Node] = [:]
        try allItems.forEach { key, value in
            if let _ = value as? NSNull {
                mutable[key] = Node.null
            } else {
                guard let nodeable = value as? NodeRepresentable else { throw NodeConversionError.invalidValue(key, value) }
                mutable[key] = try nodeable.makeNode()
            }
        }
        return .object(mutable)
    }

    public func converted<T: NodeInitializable>(to type: T.Type = T.self) throws -> T {
        return try makeNode().converted()
    }
}

使用该标题,您可以:

return try JSON(node: data.makeNode())

【讨论】:

    【解决方案2】:

    无法从[String : Any] 字典初始化JSON,因为Any 不能转换为Node

    Node 可以是有限数量的类型。 (See Node source)。如果您知道您的对象都将是相同的类型,请使用只允许该类型的字典。因此,对于您的示例,[String : String]

    如果您要从请求中获取数据,您可以尝试使用 request.json,正如文档 here 中所使用的那样。

    编辑:

    另一个(可能更好)的解决方案是让你的字典[String: Node] 然后你可以包含任何符合Node 的类型。不过,您可能必须调用对象的 makeNode() 函数才能将其添加到字典中。

    【讨论】:

    • 仍然没有解决办法?
    猜你喜欢
    • 1970-01-01
    • 2018-06-25
    • 1970-01-01
    • 2020-10-17
    • 2017-10-18
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多