Dictionary的扩展名为<string,anyobject =“”>

时间:2015-09-16 13:35:00

标签: swift dictionary swift2

我正在尝试创建一个字典扩展,其中Dictionary的类型为&lt; String,AnyObject&gt;。

在许多地方寻找并尝试不同的方法,但它们似乎都没有效果。这是其中之一:

extension Dictionary where <String, AnyObject>{
    var jsonString:String {
        return ""
    }
}

另一种因某种原因无法正常工作的方法:

extension Dictionary where Key:Hashable, Value:AnyObject {

    var jsonString:String {

        do {
           let stringData = try NSJSONSerialization.dataWithJSONObject(self, options: NSJSONWritingOptions.PrettyPrinted)
            if let string = String(data: stringData, encoding: NSUTF8StringEncoding){
                return string
            }
        }catch _ {

        }
        return ""
    }
}

获得:参数类型&#39;字典&#39;不符合'AnyObject&#39;

的预期类型

7 个答案:

答案 0 :(得分:83)

&GT = 3.1

从3.1开始,我们可以进行具体扩展,即:

extension Dictionary where Key == String {}

&LT; 3.1

我们不能使用具体的泛型符合具体类型,即:

extension Dictionary where Key == String

但是,因为Dictionary符合序列,我们可以使用具体的泛型符合协议类型,我们可以这样做:

extension Sequence where Iterator.Element == (key: String, value: AnyObject) {
    func doStuff() {...

否则,我们可以将密钥限制为字符串符合的协议:

extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
    var jsonString: String {
        return ""
    }
}

根据您更新的答案。 Json序列化需要一个对象,Swift Dictionaries是结构。您需要转换为NSDictionary您必须指定Key以符合NSObject才能正确转换为NSDictionary

  

小注意:字典已将约束Key键入Hashable,因此您的原始约束不会添加任何内容。

extension Dictionary where Key: NSObject, Value:AnyObject {

    var jsonString:String {

        do {
            let stringData = try NSJSONSerialization.dataWithJSONObject(self as NSDictionary, options: NSJSONWritingOptions.PrettyPrinted)
            if let string = String(data: stringData, encoding: NSUTF8StringEncoding){
                return string
            }
        }catch _ {

        }
        return ""
    }
}

请注意,字典必须符合此类型才能访问扩展名。

let dict = ["k" : "v"]

将成为[String : String]类型,因此您必须明确声明:

let dict: [NSObject : AnyObject] = ["k" : "v"]

答案 1 :(得分:5)

Swift 3方法

extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject

As StringLiteralConvertible现已弃用,并由ExpressibleByStringLiteral取代

答案 2 :(得分:4)

添加@Logan提供的答案,对于那些希望将自定义属性添加到字符串下标Dictionary的人来说,这也是可能的(当我遇到这个SO问题时,我希望这样做):

extension Dictionary where Key: StringLiteralConvertible {

    var somePropertyThatIsAColor:UIColor? {
        get {
            return self["someKey"] as? UIColor
        }
        set {
            // Have to cast as optional Value
            self["someKey"] = (newValue as? Value)
    }

}

答案 3 :(得分:3)

Swift 3的更新
以下是ExpressibleByStringLiteral使用KeyAny使用Value的示例。

extension Dictionary where Key: StringLiteralConvertible, Value: Any {
    var jsonString: String? {
        if let dict = (self as AnyObject) as? Dictionary<String, AnyObject> {
            do {
                let data = try JSONSerialization.data(withJSONObject: dict, options: JSONSerialization.WritingOptions(rawValue: UInt.allZeros))
                if let string = String(data: data, encoding: String.Encoding.utf8) {
                    return string
                }
            } catch {
                print(error)
            }
        }
        return nil
    }
}

然后我像这样使用它:

let dict: Dictionary<String, AnyObject> = [...]
let jsonString = dict.jsonString

您可以将self转换为AnyObject或NSObject,两者都有效,然后您将打开为Dictionary或任何其他特定类型。

答案 4 :(得分:2)

所以,Dictionary是:

public struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible {..}

协议扩展如何? :d

extension CollectionType where Self: DictionaryLiteralConvertible, Self.Key == String, Self.Value == AnyObject, Generator.Element == (Self.Key, Self.Value) {
...
}

答案 5 :(得分:1)

我无法让任何提供的解决方案在Swift 3中运行,但是通过利用Dictionary和NSDictionary之间的桥接,我可以做到这一点:

extension NSDictionary {

    var jsonString:String {

        do {
            let stringData = try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
            if let string = String(data: stringData, encoding: .utf8) {
                return string
            }
        }catch _ {

        }
        return ""
    }
}

答案 6 :(得分:1)

使用[String:Any]而不是Dictionary的任何人都可以使用以下扩展名

extension Dictionary where Key == String, Value == Any {

    mutating func append(anotherDict:[String:Any]) {
        for (key, value) in anotherDict {
            self.updateValue(value, forKey: key)
        }
    }
}