extension of Dictionary where <String, AnyObject>
>=3.1
From 3.1, we can do concrete extensions, ie:
extension Dictionary where Key == String {}
<3.1
We can not conform concrete types w/ concrete generics, ie:
extension Dictionary where Key == String
However, because Dictionary conforms to sequence and we can conform protocol types w/ concrete generics, we could do:
extension Sequence where Iterator.Element == (key: String, value: AnyObject) {
func doStuff() {...
Otherwise, we can constrain our key to a protocol that string conforms to like this:
extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
var jsonString: String {
return ""
}
}
As per your updated answer. Json serialization needs an object, Swift Dictionaries are structs. You need to convert to an NSDictionary
You must specify Key
to conform to NSObject
to properly convert to an NSDictionary
.
Small note: Dictionaries already type constrain
Key
to beHashable
, so your original constraint wasn't adding anything.
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 ""
}
}
Note, that the dictionaries must conform to this type to access the extension.
let dict = ["k" : "v"]
Will become type [String : String]
, so you must be explicit in declaring:
let dict: [NSObject : AnyObject] = ["k" : "v"]
Update for Swift 3
Here is my example using ExpressibleByStringLiteral
for Key
and Any
for 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
}
}
and then I use it like this:
let dict: Dictionary<String, AnyObject> = [...]
let jsonString = dict.jsonString
You can convert self to AnyObject or NSObject, both works, then you do unwrap as Dictionary or any other specific type.
Swift 3 Approach
extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject
As StringLiteralConvertible is now deprecated and replaced by ExpressibleByStringLiteral