对于来自Objective-C解析器的JSON字典,Swift泛型不能像预期的那样工作

对于来自Objective-C解析器的JSON字典,Swift泛型不能像预期的那样工作,objective-c,json,swift,generics,Objective C,Json,Swift,Generics,我有一个从JSON字典中检索非可选值的函数。 如果字典中没有值或值的类型错误,则需要3个参数:dictionary、key和default值 func valueFromJSONDict<T>(dict:[NSObject: AnyObject]?, key: NSObject, defaultValue: T) -> T { if let value = dict?[key] as? T { return value } return

我有一个从JSON字典中检索非可选值的函数。 如果字典中没有值或值的类型错误,则需要3个参数:dictionary、key和default值

func valueFromJSONDict<T>(dict:[NSObject: AnyObject]?, key: NSObject, defaultValue: T) -> T {
    if let value = dict?[key] as? T {
        return value
    }
    return defaultValue
}
但如果我在没有泛型的情况下做同样的事情,它会很好:

title = { () -> String 
   if let value = dict?["title"] as? String {
      title = value
   } else {
      return ""
   }
}()
这个解析后的JSON dict来自Objective-C解析器,如果我打印dict中的值的dynamicType类似于_CFNSString,但是T.self是Swift.String,所以Swift可能无法识别类型

如何使其工作?

您的dict对象看起来像什么

以下是我的建议:

typealias JSONObject = [String: AnyObject]

func valueFromJSON<T>(json: JSONObject?, key: String, defaultValue: T) -> T
{
    if let value = json?[key] as? T {
        return value
    }
    return defaultValue
}

let json = ["Name": "Sir Lancelot",
            "Quest": "To seek the Holy Grail",
            "Favorite Color": "Blue..."]

let name = valueFromJSON(json, "Name", "Sir Not Appearing In This Film")

我发现,这种方法的实际工作原理是我将结果分配给某个var或let:

但如果我将结果指定给属性,则不起作用:


最后,我通过将属性类型从非可选的@NSManaged var title:String替换为隐式展开的可选@NSManaged var title:String,解决了这个问题

关于代码风格的好建议,我一定会使用它。但是这里的键类型没有意义。我认为问题在于JSON来自Objective-C解析器,因此Swift无法正常识别类型。您可能是对的,但在不知道dict内容的情况下很难进行测试。此外,我建议尽可能多地使用Swift类型String、Int、Float等。。。而不是Obj-C对应物。我认为Swift有更好的转换/桥接逻辑和它自己的原生类型。同意,但这篇文章来自AFNetworking,它是Objective-C。
typealias JSONObject = [String: AnyObject]

func valueFromJSON<T>(json: JSONObject?, key: String, defaultValue: T) -> T
{
    if let value = json?[key] as? T {
        return value
    }
    return defaultValue
}

let json = ["Name": "Sir Lancelot",
            "Quest": "To seek the Holy Grail",
            "Favorite Color": "Blue..."]

let name = valueFromJSON(json, "Name", "Sir Not Appearing In This Film")
let value = valueFromJSONDict(dict, "title", "") // value from JSON
title = valueFromJSONDict(dict, "title", "") // always ""