El simulador de Xcode te permite correr tu app en un iPhone virtual sin necesitar un dispositivo físico.
En esta lección vas a construir una mini app completa que integra todo lo que aprendiste en el curso. Después vas a ejecutarla en el simulador de Xcode para verla funcionar en tiempo real.
Qué vas a construir
Vas a crear una app de lista de gastos personales. El usuario puede escribir un concepto y un monto, agregar el gasto a una lista, y ver el total acumulado.
Esta app usa:
- Variables y tipos de datos (
String,Double) - Condicionales (
if) - Arreglos y ciclos (
for) - Funciones
- Vistas SwiftUI (
VStack,TextField,Button,List) @Statepara manejar datos reactivos
Estructura del proyecto
Antes de escribir código, define la estructura. Una app bien organizada tiene:
| Archivo | Propósito |
|---|---|
ContentView.swift |
Vista principal con la interfaz |
GastoModel.swift |
Modelo de datos del gasto |
Assets.xcassets |
Íconos e imágenes |
AppEntry.swift |
Punto de entrada (@main) |
Xcode genera Assets.xcassets y AppEntry.swift automáticamente al crear el proyecto.
Paso 1 — Crea el proyecto en Xcode
- Abre Xcode y selecciona Create a new Xcode project.
- Elige la plantilla App dentro de la pestaña iOS.
- Llena los campos:
- Product Name:
MisGastos - Team: None (por ahora)
- Organization Identifier:
mx.tuapp - Interface: SwiftUI
- Language: Swift
- Product Name:
- Guarda el proyecto en tu carpeta de trabajo.
Xcode abre el proyecto con ContentView.swift listo para editar.
Paso 2 — Crea el modelo de datos
Crea un nuevo archivo Swift llamado GastoModel.swift. Escribe este código:
import Foundation
struct Gasto: Identifiable {
let id = UUID()
var concepto: String
var monto: Double
}
Identifiable es un protocolo que exige una propiedad id única. SwiftUI lo necesita para mostrar arreglos en List sin errores.
UUID() genera un identificador único automático cada vez que creas un Gasto.
Paso 3 — Construye la vista principal
Abre ContentView.swift y reemplaza todo el contenido con este código:
import SwiftUI
struct ContentView: View {
@State private var concepto: String = ""
@State private var montoTexto: String = ""
@State private var gastos: [Gasto] = []
var total: Double {
gastos.reduce(0) { $0 + $1.monto }
}
var body: some View {
NavigationStack {
VStack(spacing: 16) {
TextField("Concepto (ej: súper, gasolina)", text: $concepto)
.textFieldStyle(.roundedBorder)
.padding(.horizontal)
TextField("Monto en pesos", text: $montoTexto)
.textFieldStyle(.roundedBorder)
.keyboardType(.decimalPad)
.padding(.horizontal)
Button("Agregar gasto") {
agregarGasto()
}
.buttonStyle(.borderedProminent)
List(gastos) { gasto in
HStack {
Text(gasto.concepto)
Spacer()
Text("$\(gasto.monto, specifier: "%.0f")")
.foregroundColor(.secondary)
}
}
Text("Total: $\(total, specifier: "%.0f")")
.font(.headline)
.padding()
}
.navigationTitle("Mis Gastos")
}
}
func agregarGasto() {
guard let monto = Double(montoTexto), monto > 0 else { return }
if concepto.isEmpty { return }
let nuevo = Gasto(concepto: concepto, monto: monto)
gastos.append(nuevo)
concepto = ""
montoTexto = ""
}
}
Puntos clave de este código
@State private var gastos: [Gasto] = [] — Arreglo reactivo. Cada vez que agregues un gasto, SwiftUI redibuja la lista automáticamente.
var total: Double — Propiedad computada. Calcula la suma de todos los montos con reduce. No necesita @State porque su valor depende de gastos.
guard let monto = Double(montoTexto), monto > 0 else { return } — Valida que el texto sea un número mayor a cero antes de agregar el gasto. Sin esta validación, la app puede fallar con entradas inválidas.
Paso 4 — Ejecuta la app en el simulador
- En la barra superior de Xcode, selecciona el simulador. Elige iPhone 15 o iPhone 16.
- Presiona el botón Run (triángulo de reproducción) o usa el atajo
Cmd + R. - Xcode compila el proyecto. La primera vez tarda entre 30 y 60 segundos.
- El simulador abre y muestra tu app.
Prueba estos escenarios:
| Acción | Resultado esperado |
|---|---|
| Escribir "Súper" y "850" → Agregar | Aparece en la lista con total $850 |
| Escribir "Gasolina" y "600" → Agregar | Lista muestra 2 gastos, total $1,450 |
| Dejar concepto vacío → Agregar | No agrega nada (validación activa) |
| Escribir texto en monto → Agregar | No agrega nada (guard falla) |
Paso 5 — Mejora visual rápida
Agrega color al botón de eliminar gastos. Modifica el bloque List así:
List {
ForEach(gastos) { gasto in
HStack {
Text(gasto.concepto)
Spacer()
Text("$\(gasto.monto, specifier: "%.0f")")
.foregroundColor(.secondary)
}
}
.onDelete { indices in
gastos.remove(atOffsets: indices)
}
}
.onDelete habilita el gesto de deslizar para eliminar, igual que en las apps nativas de iOS como Recordatorios o Notas.
Con este cambio, el usuario puede deslizar un gasto hacia la izquierda y ver el botón rojo Eliminar.
Errores comunes
1. El simulador no arranca Verifica que Xcode tenga instalados los runtimes del simulador. Ve a Xcode → Settings → Platforms y descarga iOS 17 o iOS 18.
2. La lista no se actualiza al agregar gastos
Esto pasa cuando declaras gastos sin @State. Sin esa propiedad, SwiftUI no sabe que el arreglo cambió y no redibuja la vista.
3. El total muestra decimales inesperados
Usa specifier: "%.0f" para mostrar números sin decimales. Si ves $850 en pantalla, falta el specifier.
4. El teclado tapa los campos de texto
Agrega .ignoresSafeArea(.keyboard) al VStack o usa ScrollView como contenedor para que el contenido suba cuando el teclado aparece.
5. El botón no responde en el simulador Asegúrate de que el modo de interacción esté activo. En el simulador, ve a I/O → Input → Send Keyboard Input to Device si el teclado no aparece.
Lo que aprendiste en todo el curso
Este curso cubrió los bloques fundamentales para programar en Swift y construir apps para iPhone:
| Lección | Concepto clave |
|---|---|
| 1 | Variables, constantes y tipos de datos |
| 2 | Operadores y expresiones |
| 3 | Condicionales if, else, switch |
| 4 | Ciclos for y while |
| 5 | Funciones con parámetros y retorno |
| 6 | Arreglos y diccionarios |
| 7 | Vistas SwiftUI: Text, Button, VStack |
| 8 | @State, @Binding y navegación |
| 9 | App completa en el simulador |
Siguientes pasos recomendados
Ya tienes la base. Estos son los próximos temas para seguir avanzando:
@ObservableObjecty@EnvironmentObject— Para compartir datos entre varias vistas sin@Bindingen cadena.- Core Data o SwiftData — Para guardar los gastos aunque cierres la app.
- URLSession — Para conectar tu app a una API y mostrar datos en tiempo real (como el catálogo de Liverpool o precios de Mercado Libre).
- TestFlight — Para distribuir tu app a personas reales antes de publicarla en el App Store.
- App Store Connect — La plataforma de Apple para publicar tu app y llegar a millones de usuarios en México y el mundo.
El camino desde esta mini app hasta una app publicada es directo. Cada concepto que aprendiste aquí se usa en apps reales que generan ingresos.
Resumen final
Construiste una app funcional de cero. Usaste Swift, SwiftUI y el simulador de Xcode para crear algo real y probarlo sin un iPhone físico. Eso ya te pone por encima de la mayoría de personas que "quieren aprender a programar apps" pero nunca escriben una línea de código.