【问题标题】:Check a [String: AnyObject] dictionary for a list of keys with values of specific types?检查 [String: AnyObject] 字典以获取具有特定类型值的键列表?
【发布时间】:2016-09-01 05:22:29
【问题描述】:

我的一个 Web 服务返回 [String: AnyObject] 的字典。我正在尝试编写一个包装器来验证字典是否包含预期的键和值类型。我怎样才能做到这一点?

例子

let val1 = "A String"
let val2 = 0
let val3 = 3.14
let dict = ["key1" : val1 as AnyObject,
            "key2" : val2 as AnyObject,
            "key3" : val3 as AnyObject]

// Search for "key1" : String and "key2" : Int

示例 2

有些人问我是如何得到字典的。

Alamofire.request(address, withMethod: .post, parameters: params, encoding: .url, headers: nil)
        .responseJSON { response in
            guard response.result.error == nil else {
                print(response.result.error!)
                return
            }

            guard let value = response.result.value as? [String: AnyObject] else
            {
                print("Malformed data received from the service")
                return
            }

【问题讨论】:

  • 返回字典还是json?
  • JSON,但我将其转换为 Dictionary 类型的字典
  • 如果它返回 json,那么你可以使用 swiftyjson 来解析那个 json 响应
  • 好的。这不是我的问题。
  • @GoldenJoe 你能显示你的api调用代码吗?

标签: swift dictionary key-value-coding


【解决方案1】:

一种方法是通过泛型和异常:

enum ExtractErrors: ErrorType {
    case KeyNotFound, TypeMismatch
}

extension Dictionary {
    func extract<T>(key: Key) throws -> T {
        guard let value = self[key] else { throw ExtractErrors.KeyNotFound }
        guard let result = value as? T else { throw ExtractErrors.TypeMismatch }
        return result
    }
}

// this will throw an exception if an Int is not present at the "id" key
let id: Int = try dict["id"]

使用这种方法从该 JSON 构建模型很容易:

struct Person {
    let id: Int
    let name: String

    static func fromDict(dict: [String:AnyObject]) -> Person? {
        do {
            return Person(id: try dict.extract("id"),
                          name: try dict.extract("name"))
        } catch {
            return nil
        }
    }
}

如果字典无效,则函数返回 nil。

您可以更进一步,使用枚举上的关联值来找出哪个键有问题:

enum ExtractErrors<Key>: ErrorType {
    case KeyNotFound(key: Key)
    case TypeMismatch(key: Key, expected: String, received: String)
}

extension Dictionary {
    func  extract<T>(key: Key) throws -> T {
        guard let value = self[key] else { throw ExtractErrors.KeyNotFound(key: key) }
        guard let result = value as? T else { throw ExtractErrors.TypeMismatch(key: key, expected: "\(T.self)", received: "\(value.dynamicType)") }
        return result
    }
}

let d = ["id":"aStringNotANumber","name":"John"]
do {
    let id: Int = try d.extract("name")
} catch let err {
    print("Invalid dictionary: \(err)")
}

以上印刷品

无效的字典:TypeMismatch("name", "Int", "String")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-06
    • 2021-02-10
    • 1970-01-01
    • 2017-10-23
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多