example - nsdictionary swift 4
extensión del diccionario donde<String, AnyObject> (6)
> = 3.1
Desde 3.1, podemos hacer extensiones concretas, es decir:
extension Dictionary where Key == String {}
<3.1
No podemos conformar tipos concretos con genéricos concretos, es decir:
extension Dictionary where Key == String
Sin embargo, como Dictionary se ajusta a la secuencia y podemos conformar tipos de protocolos con genéricos concretos, podríamos hacer:
extension Sequence where Iterator.Element == (key: String, value: AnyObject) {
func doStuff() {...
De lo contrario, podemos restringir nuestra clave a un protocolo que la cadena cumpla con esto:
extension Dictionary where Key: StringLiteralConvertible, Value: AnyObject {
var jsonString: String {
return ""
}
}
Según su respuesta actualizada. La serialización Json necesita un objeto, los diccionarios Swift son estructuras. Necesita convertir a un NSDictionary
Debe especificar Key
para cumplir con NSObject
para convertirlo correctamente a un NSDictionary
.
Nota pequeña: los diccionarios ya
Hashable
restringirKey
para serHashable
, por lo que su restricción original no agregaba nada.
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 ""
}
}
Tenga en cuenta que los diccionarios deben ajustarse a este tipo para acceder a la extensión.
let dict = ["k" : "v"]
Se convertirá en el tipo [String : String]
, por lo que debe ser explícito al declarar:
let dict: [NSObject : AnyObject] = ["k" : "v"]
Intento crear una extensión de diccionario donde Diccionario sea del tipo <String, AnyObject>.
Estaba buscando en muchos lugares y probando diferentes enfoques, pero ninguno de ellos parecía funcionar. Este era uno de ellos:
extension Dictionary where <String, AnyObject>{
var jsonString:String {
return ""
}
}
Otro método que en realidad no funcionó por alguna razón:
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 ""
}
}
Obtenido: el tipo de argumento ''Diccionario'' no se ajusta al tipo esperado de ''AnyObject''
Agregando a la respuesta proporcionada por @Logan, para aquellos que buscan agregar propiedades personalizadas al Dictionary
cadenas de texto, eso también es posible (estaba buscando hacer esto cuando me encontré con esta pregunta 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)
}
}
Entonces, el Dictionary
es:
public struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible {..}
¿Qué tal una extensión de protocolo? :RE
extension CollectionType where Self: DictionaryLiteralConvertible, Self.Key == String, Self.Value == AnyObject, Generator.Element == (Self.Key, Self.Value) {
...
}
No pude hacer que ninguna de las soluciones ofrecidas funcionara en Swift 3, pero al aprovechar el puente entre Dictionary y NSDictionary pude hacer esto:
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 ""
}
}
Actualización para Swift 3
Aquí está mi ejemplo usando ExpressibleByStringLiteral
para Key
y 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
}
}
y luego lo uso así:
let dict: Dictionary<String, AnyObject> = [...]
let jsonString = dict.jsonString
Puede convertir uno mismo en AnyObject o NSObject, ambos trabajos, y luego desenvolver como Dictionary o cualquier otro tipo específico.
Enfoque Swift 3
extension Dictionary where Key: ExpressibleByStringLiteral, Value: AnyObject
Como StringLiteralConvertible ahora está en desuso y reemplazado por ExpressibleByStringLiteral