Domina los métodos de clase en Swift con un ejemplo práctico: un LevelTracker que desbloquea niveles y un Player que avanza. Aquí verás cuándo usar static o class, cómo separar lógica compartida de la lógica por instancia y por qué mutating e init son clave para un sistema de niveles robusto.
¿Qué es un método de clase en Swift y cuándo usar static o class?
Un método es de clase cuando lo invoca la propia clase y no una instancia. La sintaxis es similar a las properties de tipo: antepones class o static a la declaración del método. Usa class si quieres permitir override en subclases; usa static si no quieres que se sobreescriba. En una estructura, no puedes usar class: solo static.
Un método de clase se llama con el nombre del tipo, no con una instancia.
class permite herencia en clases. static bloquea la sobreescritura.
En struct, solo se permite static.
¿Cómo se invoca un método de clase?
Ejemplo simple con print para mostrar la llamada desde el tipo.
classSomeClass{classfuncsomeMethod(){print("Hola")}staticfuncanotherMethod(){print("Hola")}}SomeClass.someMethod()// Invocado por la clase, no por una instancia.
¿Cómo funciona el LevelTracker con métodos estáticos?
Se define una estructura LevelTracker con estado compartido y de instancia. El estado global se maneja con propiedades estáticas y la lógica común con métodos estáticos. Para cambiar el nivel actual del jugador se usa un método mutating porque modifica la instancia.
highestUnlockedLevel: nivel máximo desbloqueado, compartido por todos los jugadores.
currentLevel: nivel actual de una instancia concreta.
unlock(level:): método estático para desbloquear niveles globalmente.
isUnlocked(level:): método estático que valida si un nivel está disponible.
advance(to:): método de instancia y mutating para actualizar el nivel del jugador.
No mezcles llamadas estáticas e instancia sin el tipo: usa el nombre del tipo para acceder a lo estático.
En struct no se usa class: solo static para métodos y propiedades de tipo.
Marca como mutating los métodos que cambian stored properties de la instancia.
¿Cómo integrar Player y completar niveles?
Player compone un LevelTracker y un nombre. Como hay una stored property sin valor inicial, necesitas un inicializador. Para completar un nivel, primero se desbloquea el siguiente con el método estático y luego se avanza con el método de instancia.
tracker: instancia de LevelTracker.
playerName: nombre del jugador.
init(name:): obliga a inicializar playerName.
complete(level:): desbloquea y avanza al siguiente nivel.
classPlayer{var tracker =LevelTracker()var playerName:Stringinit(name:String){self.playerName = name
}funccomplete(level:Int){// Desbloquear el siguiente nivel de forma global.LevelTracker.unlock(level: level +1)// Avanzar el nivel del jugador._= tracker.advance(to: level +1)}}var player =Player(name:"Juan Gabriel")print(player.tracker.currentLevel)// 1player.complete(level:1)print(player.tracker.currentLevel)// 2if player.tracker.advance(to:7){print("Podemos avanzar hasta el nivel siete")}else{print("El nivel siete sigue bloqueado por ahora")}LevelTracker.unlock(level:7)if player.tracker.advance(to:7){print("Podemos avanzar hasta el nivel siete")}
¿Por qué hace falta un inicializador?
Si una stored property no tiene valor por defecto, debes asignarla en init.
Un fix común es dar un valor vacío, pero es preferible un init(name:) claro.
¿Te gustaría extender este patrón con habilidades, experiencia o logros? Comparte tus ideas y casos de uso en los comentarios.
Me parece genial como exlpica las bases de swift con ejemplos realistas de la industria de video juegos, ya que con esta explicación no solo sabemos que existe determinada característica en swift, si no que además podremos saber en que contexto podemos utilizar dicha funcionalidad.
es el ejemplo de la doc oficial: oficial:
excelente ejemplo juan eres mi idolo
el ejemplo es de la doc oficial:
Si alguien está tomando este curso hoy en 2025 y está teniendo un problema con la struct de "LevelTracker", marquen esto en el principio
@MainActor struct LevelTracker{...}```Esto sucede porque Swift a partir de la versión 5.5 hizo cambios, si gustan pueden investigar sobre los actores y el manejo de hilos, pero por lo pronto solo hagan eso, ya que tendrían que modificar mucho el código si aplicamos esos conceptos, probablemente sería bueno que hubiese una actualización del curso, o verlo en un curso de SwiftAvanzado.
si ojala actualicen el curso... creo que este lenguaje me parece muy robusto la verdad seria interesante un bloque un path mas moderno y completo
Hola, si Xcode les lanza un error al momento de declarar highestLevelUnlocked, pueden agregar lo siguiente:
nonisolated(unsafe)staticvar highestLevelUnlocked =1```El error que lanza se debe a que Swift intenta advertirte que declarar una variable estática puede no ser seguro, ya que puede ser modificado desde cualquier lugar de tu aplicación.
bueno pues xcode tambien te da esta solucion
@MainActor en static var como bien dices si lanza un error... realmente no se que hace este decorador pero si da solucion al error que mencionas .... uso public es por que este codigo esta en sources/LvelTracker.swift y para acceder desde project/main.swift hay que declara public de por si son privadas
bueno pues ojala saquen este curso mas actualizado
Hola comunidad de Platzi e iOS, les comparto un link para que sigan profundizando la clase de métodos
En Swift, no se puede usar la palabra clave class en un método de un struct porque structs y classes son entidades diferentes en cuanto a su naturaleza y comportamiento. Los structs son tipos de valor que se copian cuando se asignan o pasan a funciones, mientras que las classes son tipos de referencia y comparten la misma instancia en memoria.
Dado que los structs no soportan herencia como las classes, los métodos en un struct deben estar relacionados directamente con su propia instancia. Así, cualquier método definido en un struct no puede ser un método de clase. Para métodos estáticos, se usa static en su lugar.
Super interesante
En este ejemplo me parece que tendria que haber una clase superior que tuviese el estado del jugador actual, puesto que si se crea otra instancia de player y se completan mas niveles, las variables estaticas en el level tracker cambiarian y se desconoceria el jugador actual.
Podemos tambien en level tracker poner a que retorne un (Bool, Int) que el bool sea el que te dice avanza y el int dice a donde y cuanto, esto evita referenciar la variable en otro lado