certmundo.
es‑mx

7 min de lectura

¿Cómo crear y ejecutar tu primera app completa en el simulador de iPhone?

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)
  • @State para 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

  1. Abre Xcode y selecciona Create a new Xcode project.
  2. Elige la plantilla App dentro de la pestaña iOS.
  3. Llena los campos:
    • Product Name: MisGastos
    • Team: None (por ahora)
    • Organization Identifier: mx.tuapp
    • Interface: SwiftUI
    • Language: Swift
  4. 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

  1. En la barra superior de Xcode, selecciona el simulador. Elige iPhone 15 o iPhone 16.
  2. Presiona el botón Run (triángulo de reproducción) o usa el atajo Cmd + R.
  3. Xcode compila el proyecto. La primera vez tarda entre 30 y 60 segundos.
  4. 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:

  • @ObservableObject y @EnvironmentObject — Para compartir datos entre varias vistas sin @Binding en 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.

Puntos clave

  • El simulador de Xcode corre tu app en un iPhone virtual. No necesitas un dispositivo físico para probar tu código durante el desarrollo.
  • Una app completa combina modelo de datos (`struct`), vistas SwiftUI y `@State`. Estos tres elementos trabajan juntos para mostrar y actualizar información en pantalla.
  • `.onDelete` con `ForEach` es la forma estándar de habilitar el gesto deslizar-para-eliminar en listas de iOS.
  • Valida siempre los datos del usuario con `guard` antes de procesarlos. Esto evita errores en tiempo de ejecución cuando el usuario ingresa texto inválido.
  • Los siguientes pasos después de este curso son `@ObservableObject`, persistencia con SwiftData, consumo de APIs con `URLSession` y publicación en el App Store.

Comparte esta lección: