¿Cómo imprimo el tipo o clase de una variable en Swift?


335

¿Hay alguna manera de imprimir el tipo de tiempo de ejecución de una variable en swift? Por ejemplo:

var now = NSDate()
var soon = now.dateByAddingTimeInterval(5.0)

println("\(now.dynamicType)") 
// Prints "(Metatype)"

println("\(now.dynamicType.description()")
// Prints "__NSDate" since objective-c Class objects have a "description" selector

println("\(soon.dynamicType.description()")
// Compile-time error since ImplicitlyUnwrappedOptional<NSDate> has no "description" method

En el ejemplo anterior, estoy buscando una manera de mostrar que la variable "pronto" es de tipo ImplicitlyUnwrappedOptional<NSDate>, o al menos NSDate!.


43
@JasonMArcher Dime cómo es esto un duplicado si la pregunta que vinculaste se hizo 4 días después de esta.
akashivskyy

Hay una serie de preguntas sobre cómo probar el tipo de un objeto Swift o leer el tipo de un objeto Swift. Estamos encontrando las mejores preguntas para usar como preguntas "maestras" para este tema. El duplicado sugerido tiene una respuesta mucho más completa. Esto no quiere decir que hiciste algo mal, solo que estamos tratando de reducir el desorden.
JasonMArcher

44
El duplicado sugerido no responde la misma pregunta; Type.self no se puede imprimir en la consola con fines de depuración, se debe utilizar para pasar a otras funciones que toman Tipos como objetos.
Matt Bridges

2
OT: Muy extraño que Swift no ofrezca eso fuera de la caja y que uno deba jugar con bibliotecas C de tan bajo nivel. Vale la pena un informe de error?
qwerty_so

Chicos, he proporcionado mi respuesta a continuación. Eche un vistazo y avíseme si eso es lo que se espera.
DILIP KOSURI

Respuestas:


377

Actualización de septiembre de 2016

Swift 3.0: uso type(of:), p. Ej. type(of: someThing)(Ya que dynamicTypese eliminó la palabra clave)

Actualización de octubre de 2015 :

Actualicé los ejemplos a continuación a la nueva sintaxis de Swift 2.0 (por ejemplo, printlnse reemplazó por print, toString()ahora esString() ).

De las notas de la versión Xcode 6.3 :

@nschum señala en los comentarios que las notas de lanzamiento de Xcode 6.3 muestran otra forma:

Los valores de tipo ahora se imprimen como el nombre de tipo demandado completo cuando se usa con println o interpolación de cadenas.

import Foundation

class PureSwiftClass { }

var myvar0 = NSString() // Objective-C class
var myvar1 = PureSwiftClass()
var myvar2 = 42
var myvar3 = "Hans"

print( "String(myvar0.dynamicType) -> \(myvar0.dynamicType)")
print( "String(myvar1.dynamicType) -> \(myvar1.dynamicType)")
print( "String(myvar2.dynamicType) -> \(myvar2.dynamicType)")
print( "String(myvar3.dynamicType) -> \(myvar3.dynamicType)")

print( "String(Int.self)           -> \(Int.self)")
print( "String((Int?).self         -> \((Int?).self)")
print( "String(NSString.self)      -> \(NSString.self)")
print( "String(Array<String>.self) -> \(Array<String>.self)")

Qué salidas:

String(myvar0.dynamicType) -> __NSCFConstantString
String(myvar1.dynamicType) -> PureSwiftClass
String(myvar2.dynamicType) -> Int
String(myvar3.dynamicType) -> String
String(Int.self)           -> Int
String((Int?).self         -> Optional<Int>
String(NSString.self)      -> NSString
String(Array<String>.self) -> Array<String>

Actualización para Xcode 6.3:

Puedes usar el _stdlib_getDemangledTypeName():

print( "TypeName0 = \(_stdlib_getDemangledTypeName(myvar0))")
print( "TypeName1 = \(_stdlib_getDemangledTypeName(myvar1))")
print( "TypeName2 = \(_stdlib_getDemangledTypeName(myvar2))")
print( "TypeName3 = \(_stdlib_getDemangledTypeName(myvar3))")

y obtener esto como salida:

TypeName0 = NSString
TypeName1 = __lldb_expr_26.PureSwiftClass
TypeName2 = Swift.Int
TypeName3 = Swift.String

Respuesta original:

Antes de Xcode 6.3 _stdlib_getTypeNameobtuvo el nombre de tipo destrozado de una variable. La entrada del blog de Ewan Swick ayuda a descifrar estas cadenas:

Por ejemplo, _TtSisignifica el Inttipo interno de Swift .

Mike Ash tiene una gran entrada de blog que cubre el mismo tema .


2
¿Cómo ha encontrado _stdlib_getTypeName()? El REPL integrado ya no existe, swift-ide-testtampoco existe, y la impresión de Xcode del módulo Swift _elimina los valores prefijados.
Lily Ballard

10
Parece que puedo buscar símbolos con lldbbastante facilidad en la respuesta. También hay _stdlib_getDemangledTypeName(), y _stdlib_demangleName().
Lily Ballard

1
Oh bien, no me di cuenta de que imageera un atajo target modules. Terminé usando target modules lookup -r -n _stdlib_, que por supuesto se expresa mejor comoimage lookup -r -n _stdlib_ libswiftCore.dylib
Lily Ballard

1
FYI - Parece que toString (...) ha sido reemplazado por String (...).
Nick

66
Swift 3.0: la dynamicTypepalabra clave se ha eliminado de Swift. En su lugar, type(of:)se ha agregado una nueva función primitiva al lenguaje: github.com/apple/swift/blob/master/CHANGELOG.md
Szu

46

Editar: se ha introducido una nueva toStringfunción en Swift 1.2 (Xcode 6.3) .

Ahora puede imprimir el tipo solicitado de cualquier tipo usando .selfy cualquier instancia usando .dynamicType:

struct Box<T> {}

toString("foo".dynamicType)            // Swift.String
toString([1, 23, 456].dynamicType)     // Swift.Array<Swift.Int>
toString((7 as NSNumber).dynamicType)  // __NSCFNumber

toString((Bool?).self)                 // Swift.Optional<Swift.Bool>
toString(Box<SinkOf<Character>>.self)  // __lldb_expr_1.Box<Swift.SinkOf<Swift.Character>>
toString(NSStream.self)                // NSStream

Intenta llamar YourClass.selfy yourObject.dynamicType.

Referencia: https://devforums.apple.com/thread/227425 .


2
Respondí a ese hilo, pero agregaré mi comentario aquí. Esos valores son del tipo "Metatype", pero no parece haber una manera fácil de averiguar qué tipo representa un objeto Metatype, que es lo que estoy buscando.
Matt Bridges

Son del tipo Metatipo, y son clases. Representan una clase. No estoy seguro exactamente cuál es su problema con eso. someInstance.dynamicType.printClassName()imprimirá el nombre de la clase.
Archivo analógico

18
El método printClassName () es solo un método de ejemplo que crearon en uno de los ejemplos en los documentos, no es una llamada a la API a la que puede acceder.
Dave Wood

44
FYI - Parece que toString (...) ha sido reemplazado por String (...)
Nick

33

Swift 3.0

let string = "Hello"
let stringArray = ["one", "two"]
let dictionary = ["key": 2]

print(type(of: string)) // "String"

// Get type name as a string
String(describing: type(of: string)) // "String"
String(describing: type(of: stringArray)) // "Array<String>"
String(describing: type(of: dictionary)) // "Dictionary<String, Int>"

// Get full type as a string
String(reflecting: type(of: string)) // "Swift.String"
String(reflecting: type(of: stringArray)) // "Swift.Array<Swift.String>"
String(reflecting: type(of: dictionary)) // "Swift.Dictionary<Swift.String, Swift.Int>"

1
La implementación de Swift 2 es particularmente agradable con casos de enumeración. ¿Alguien sabe si este comportamiento está documentado / garantizado por Apple? La biblioteca estándar simplemente incluye un comentario de que esto es adecuado para la depuración ...
milos

30

¿Es esto lo que estás buscando?

println("\(object_getClassName(now))");

Imprime "__NSDate"

ACTUALIZACIÓN : Tenga en cuenta que esto ya no parece funcionar a partir de Beta05


2
No funciona para clases rápidas. Devuelve "UnsafePointer (0x7FBB18D06DE0)"
aryaxt

44
Tampoco funciona para las clases de ObjC (al menos en Beta5), para un NSManagedObject solo obtengo "Builtin.RawPointer = address"
Kendall Helmstetter Gelner

23

Mi Xcode actual es la versión 6.0 (6A280e).

import Foundation

class Person { var name: String; init(name: String) { self.name = name }}
class Patient: Person {}
class Doctor: Person {}

var variables:[Any] = [
    5,
    7.5,
    true,
    "maple",
    Person(name:"Sarah"),
    Patient(name:"Pat"),
    Doctor(name:"Sandy")
]

for variable in variables {
    let typeLongName = _stdlib_getDemangledTypeName(variable)
    let tokens = split(typeLongName, { $0 == "." })
    if let typeName = tokens.last {
        println("Variable \(variable) is of Type \(typeName).")
    }
}

Salida:

Variable 5 is of Type Int.
Variable 7.5 is of Type Double.
Variable true is of Type Bool.
Variable maple is of Type String.
Variable Swift001.Person is of Type Person.
Variable Swift001.Patient is of Type Patient.
Variable Swift001.Doctor is of Type Doctor.

1
Bien, pero la pregunta también incluía Opcionales, la salida de los opcionales está configurada Optional(...), por lo que su código solo volvería Optionalcomo el Tipo. ¡También debería aparecer var optionalTestVar: Person? = Person(name:"Sarah")como Opcional (Persona) y var con Persona! as ImplícitamenteUnwrappedOptional (Person)
Binarian

18

A partir de Xcode 6.3 con Swift 1.2, simplemente puede convertir los valores de tipo al valor total requerido String.

toString(Int)                   // "Swift.Int"
toString(Int.Type)              // "Swift.Int.Type"
toString((10).dynamicType)      // "Swift.Int"
println(Bool.self)              // "Swift.Bool"
println([UTF8].self)            // "Swift.Array<Swift.UTF8>"
println((Int, String).self)     // "(Swift.Int, Swift.String)"
println((String?()).dynamicType)// "Swift.Optional<Swift.String>"
println(NSDate)                 // "NSDate"
println(NSDate.Type)            // "NSDate.Type"
println(WKWebView)              // "WKWebView"
toString(MyClass)               // "[Module Name].MyClass"
toString(MyClass().dynamicType) // "[Module Name].MyClass"

¿Es posible la otra dirección en 1.2? Para inicializar una instancia basada en el nombre de la clase?
user965972

@ user965972 Por lo que sé, no creo que haya ninguno.
Kiding

17

Todavía puede acceder a la clase, a través de className(que devuelve a String).

En realidad, hay varias maneras de obtener la clase, por ejemplo classForArchiver, classForCoder, classForKeyedArchiver(todos de retorno AnyClass!).

No se puede obtener el tipo de primitivo (un primitivo no es una clase).

Ejemplo:

var ivar = [:]
ivar.className // __NSDictionaryI

var i = 1
i.className // error: 'Int' does not have a member named 'className'

Si desea obtener el tipo de primitivo, debe usarlo bridgeToObjectiveC(). Ejemplo:

var i = 1
i.bridgeToObjectiveC().className // __NSCFNumber

Apuesto a que es un primitivo. Desafortunadamente no puedes obtener el tipo de primitivo.
Leandros

Esos ejemplos no parecen funcionar en el patio de recreo. Me sale el error para primitivas y no primitivas por igual.
Matt Bridges

intentar import Cocoa.
Leandros

99
className parece estar disponible solo para NSObjects cuando se desarrolla para OSX; no está disponible en el SDK de iOS para NSObjects u objetos "normales"
Matt Bridges

3
classNamees parte del soporte AppleScript de Cocoa y definitivamente no debe usarse para introspección genérica. Obviamente no está disponible en iOS.
Nikolai Ruhe

16

Puede usar reflect para obtener información sobre el objeto.
Por ejemplo, nombre de la clase de objeto:

var classname = reflect (now) .summary

En Beta 6, esto me dio el nombre de la aplicación + el nombre de la clase en una forma ligeramente alterada, pero es un comienzo. +1 por reflect(x).summary- ¡gracias!
Olie

no funcionó, imprime una línea en blanco en Swift 1.2 Xcode 6.4 y iOs 8.4
Juan Boero

13

Tuve suerte con:

let className = NSStringFromClass(obj.dynamicType)

@hdost amigo, nada funcionó, pero classForCoder funcionó.
Satheeshwaran

12

Tipo de uso de Xcode 8 Swift 3.0 (de :)

let className = "\(type(of: instance))"

10

En Xcode 8, Swift 3.0

Pasos:

1. Obtenga el tipo:

Opción 1:

let type : Type = MyClass.self  //Determines Type from Class

Opcion 2:

let type : Type = type(of:self) //Determines Type from self

2. Convertir tipo a cadena:

let string : String = "\(type)" //String

8

En Swift 3.0, puede usar type(of:), ya que la dynamicTypepalabra clave se ha eliminado.


7

SWIFT 5

Con la última versión de Swift 3 podemos obtener descripciones bonitas de los nombres de tipo a través del Stringinicializador. Me gusta, por ejemplo print(String(describing: type(of: object))). ¿Dónde object puede haber una variable de instancia como matriz, un diccionario, una Int, una NSDate, una instancia de una clase personalizada, etc.

Aquí está mi respuesta completa: obtener el nombre de clase del objeto como cadena en Swift

Esa pregunta está buscando una forma de obtener el nombre de clase de un objeto como una cadena, pero también propuse otra forma de obtener el nombre de clase de una variable que no es una subclase de NSObject. Aquí está:

class Utility{
    class func classNameAsString(obj: Any) -> String {
        //prints more readable results for dictionaries, arrays, Int, etc
        return String(describing: type(of: obj))
    }
}

Hice una función estática que toma como parámetro un objeto de tipo Anyy devuelve su nombre de clase como String:).

Probé esta función con algunas variables como:

    let diccionary: [String: CGFloat] = [:]
    let array: [Int] = []
    let numInt = 9
    let numFloat: CGFloat = 3.0
    let numDouble: Double = 1.0
    let classOne = ClassOne()
    let classTwo: ClassTwo? = ClassTwo()
    let now = NSDate()
    let lbl = UILabel()

y la salida fue:

  • el diccionario es de tipo Diccionario
  • array es de tipo Array
  • numInt es de tipo Int
  • numFloat es del tipo CGFloat
  • numDouble es de tipo Double
  • classOne es de tipo: ClassOne
  • classTwo es de tipo: ClassTwo
  • ahora es de tipo: Fecha
  • lbl es de tipo: UILabel

5

Al usar Cocoa (no CocoaTouch), puede usar la classNamepropiedad para objetos que son subclases de NSObject.

println(now.className)

Esta propiedad no está disponible para objetos Swift normales, que no son subclases de NSObject (y de hecho, no hay identificación de raíz o tipo de objeto en Swift).

class Person {
    var name: String?
}

var p = Person()
println(person.className) // <- Compiler error

En CocoaTouch, en este momento no hay una manera de obtener una descripción de cadena del tipo de una variable dada. Funcionalidad similar tampoco existe para los tipos primitivos en Cocoa o CocoaTouch.

Swift REPL puede imprimir un resumen de valores, incluido su tipo, por lo que es posible que esta forma de introspección sea posible a través de una API en el futuro.

EDITAR : dump(object)parece hacer el truco.


Incluso a partir de Xcode 10 y Swift 4.2, dump(object)es realmente poderoso. Gracias.
Alex Zavatone

5

La respuesta principal no tiene un ejemplo funcional de la nueva forma de hacer esto usando type(of:. Entonces, para ayudar a los novatos como yo, aquí hay un ejemplo de trabajo, tomado principalmente de los documentos de Apple aquí: https://developer.apple.com/documentation/swift/2885064-type

doubleNum = 30.1

func printInfo(_ value: Any) {
    let varType = type(of: value)
    print("'\(value)' of type '\(varType)'")
}

printInfo(doubleNum)
//'30.1' of type 'Double'

4

He intentado algunas de las otras respuestas aquí, pero parece que Milage sabe muy bien cuál es el objeto subyacente.

Sin embargo, encontré una forma de obtener el nombre de la clase Object-C para un objeto haciendo lo siguiente:

now?.superclass as AnyObject! //replace now with the object you are trying to get the class name for

Aquí hay un ejemplo de cómo lo usarías:

let now = NSDate()
println("what is this = \(now?.superclass as AnyObject!)")

En este caso, imprimirá NSDate en la consola.


4

Encontré esta solución que, con suerte, podría funcionar para otra persona. Creé un método de clase para acceder al valor. Tenga en cuenta que esto funcionará solo para la subclase NSObject. Pero al menos es una solución limpia y ordenada.

class var className: String!{
    let classString : String = NSStringFromClass(self.classForCoder())
    return classString.componentsSeparatedByString(".").last;
}

4

En el último XCode 6.3 con Swift 1.2, esta es la única forma en que encontré:

if view.classForCoder.description() == "UISegment" {
    ...
}

NOTA: description () devuelve el nombre de la clase en el formato <swift module name>.<actual class name>, por lo que desea dividir la cadena con a .y obtener el último token.
Matthew Quiros

4

Muchas de las respuestas aquí no funcionan con el último Swift (Xcode 7.1.1 al momento de escribir).

La forma actual de obtener la información es crear un Mirrore interrogarlo. Para el nombre de clase es tan simple como:

let mirror = Mirror(reflecting: instanceToInspect)
let classname:String = mirror.description

También se puede recuperar información adicional sobre el objeto de Mirror. Ver http://swiftdoc.org/v2.1/type/Mirror/ para más detalles.


¿Qué hay de malo con las respuestas stackoverflow.com/a/25345480/1187415 y stackoverflow.com/a/32087449/1187415 ? Ambos parecen funcionar bastante bien con Swift 2. (No he comprobado los otros.)
Martin R

Me gusta esto como una solución general, pero obtener "Mirror for ViewController" ("Mirror for" extraño) - espera, ¡parece que usar ".subjectType" es el truco!
David H

3

En lldb a partir de beta 5, puede ver la clase de un objeto con el comando:

fr v -d r shipDate

que produce algo como:

(DBSalesOrderShipDate_DBSalesOrderShipDate_ *) shipDate = 0x7f859940

El comando expandido significa algo como:

Frame Variable (imprimir una variable de cuadro) -d run_target (expandir tipos dinámicos)

Algo útil para saber es que el uso de "Frame Variable" para generar valores de variables garantiza que no se ejecute ningún código.


3

He encontrado una solución para las clases de desarrollo propio (o a las que tiene acceso).

Coloque la siguiente propiedad calculada dentro de su definición de clase de objetos:

var className: String? {
    return __FILE__.lastPathComponent.stringByDeletingPathExtension
}

Ahora puede simplemente llamar el nombre de la clase en su objeto de la siguiente manera:

myObject.className

Tenga en cuenta que esto solo funcionará si su definición de clase se realiza dentro de un archivo que se llama exactamente como la clase de la que desea el nombre.

Como este es comúnmente el caso, la respuesta anterior debería hacerlo para la mayoría de los casos . Pero en algunos casos especiales, es posible que deba encontrar una solución diferente.


Si necesita el nombre de la clase dentro de la clase (archivo), simplemente puede usar esta línea:

let className = __FILE__.lastPathComponent.stringByDeletingPathExtension

Quizás este método ayude a algunas personas.


3

Basado en las respuestas y comentarios dados por Klass y Kevin Ballard arriba, iría con:

println(_stdlib_getDemangledTypeName(now).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon?).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(soon!).componentsSeparatedByString(".").last!)

println(_stdlib_getDemangledTypeName(myvar0).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar1).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar2).componentsSeparatedByString(".").last!)
println(_stdlib_getDemangledTypeName(myvar3).componentsSeparatedByString(".").last!)

que imprimirá:

"NSDate"
"ImplicitlyUnwrappedOptional"
"Optional"
"NSDate"

"NSString"
"PureSwiftClass"
"Int"
"Double"

Creo que esta es la mejor respuesta.
maschall 02 de

Terminé usando en Swift 1.2 lo siguiente:, toString(self.dynamicType).componentsSeparatedByString(".").last!obviamente, estaba en un contexto de objeto y podía hacer referencia self.
Joe

3
let i: Int = 20


  func getTypeName(v: Any) -> String {
    let fullName = _stdlib_demangleName(_stdlib_getTypeName(i))
    if let range = fullName.rangeOfString(".") {
        return fullName.substringFromIndex(range.endIndex)
    }
    return fullName
}

println("Var type is \(getTypeName(i)) = \(i)")

3

Swift versión 4:

print("\(type(of: self)) ,\(#function)")
// within a function of a class

Gracias @Joshua Dance


3

Swift 4:

// "TypeName"
func stringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(describing: some) : String(describing: type(of: some))
    return string
}

// "ModuleName.TypeName"
func fullStringType(of some: Any) -> String {
    let string = (some is Any.Type) ? String(reflecting: some) : String(reflecting: type(of: some))
    return string
}

Uso:

print(stringType(of: SomeClass()))     // "SomeClass"
print(stringType(of: SomeClass.self))  // "SomeClass"
print(stringType(of: String()))        // "String"
print(fullStringType(of: String()))    // "Swift.String"

2

Parece que no hay una forma genérica de imprimir el nombre del tipo de un valor arbitrario. Como otros han señalado, para las instancias de clase puede imprimirvalue.className pero para valores primitivos parece que en tiempo de ejecución, la información de tipo se ha ido.

Por ejemplo, parece que no hay una forma de escribir: 1.something()y salir Intpor cualquier valor de something. (Puede, como se sugirió otra respuesta, el uso i.bridgeToObjectiveC().classNamea dar una pista, pero __NSCFNumberes no realmente el tipo dei -. Sólo lo que se convertirá en cuando se cruza el límite de una llamada a la función de Objective-C)

Me encantaría que me demuestren que estoy equivocado, pero parece que la verificación de tipos se realiza en tiempo de compilación, y como C ++ (con RTTI deshabilitado), gran parte de la información de tipos desaparece en tiempo de ejecución.


¿Puede dar un ejemplo del uso de className para imprimir "NSDate" para la variable "ahora" en mi ejemplo que funciona en el patio de juegos de Xcode6? Por lo que puedo decir, className no está definido en los objetos Swift, incluso aquellos que son subclases de NSObject.
Matt Bridges

Parece que 'className' está disponible para objetos que descienden de NSObject, pero solo cuando se desarrolla para mac, no para iOS. Parece que no hay ninguna solución para iOS.
Matt Bridges

1
Sí, la verdadera conclusión aquí parece ser que, en el caso general, la información de tipo desaparece rápidamente en tiempo de ejecución.
ipmcc

Sin embargo, tengo curiosidad por saber cómo REPL puede imprimir los tipos de valores.
Matt Bridges

Es casi seguro que el REPL se interpreta y no se compila, lo que lo explicaría fácilmente
ipmcc

2

Así es como se obtiene una cadena de tipo de su objeto o Tipo que es coherente y tiene en cuenta a qué módulo pertenece o está anidada la definición del objeto. Funciona en Swift 4.x.

@inline(__always) func typeString(for _type: Any.Type) -> String {
    return String(reflecting: type(of: _type))
}

@inline(__always) func typeString(for object: Any) -> String {
    return String(reflecting: type(of: type(of: object)))
}

struct Lol {
    struct Kek {}
}

// if you run this in playground the results will be something like
typeString(for: Lol.self)    //    __lldb_expr_74.Lol.Type
typeString(for: Lol())       //    __lldb_expr_74.Lol.Type
typeString(for: Lol.Kek.self)//    __lldb_expr_74.Lol.Kek.Type
typeString(for: Lol.Kek())   //    __lldb_expr_74.Lol.Kek.Type

2

Para obtener un tipo de objeto o clase de objeto en Swift , debe usar un tipo (de: yourObject)

tipo (de: suObjeto)


1

No es exactamente lo que busca, pero también puede verificar el tipo de la variable con los tipos Swift de la siguiente manera:

let object: AnyObject = 1

if object is Int {
}
else if object is String {
}

Por ejemplo.


1

Xcode 7.3.1, Swift 2.2:

String(instanceToPrint.self).componentsSeparatedByString(".").last

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.