Estudio de caso

Cada repetición. Queda constancia.

Un registro de entrenamiento de fuerza, rápido y privado, en el App Store para iPhone, iPad y Apple Watch.

Lanzada el 12 de julio de 2026. Construí Reps porque la quería para mi propio entrenamiento: un registro lo bastante discreto como para entrenar con él, días que se bloquean cuando el trabajo está hecho y un conector que le permite a Claude leer mi historial y planificar la próxima sesión sin tocar la base de datos. Treinta y seis mil líneas de Swift y 185 pruebas después, se lanza en diecisiete idiomas. Así fue como tomó forma.

941 Reps a mitad del entrenamiento: dos series marcadas en verde con tachones dibujados a mano
Producto

Toca un círculo, bloquea el día.

Un registro de entrenamiento tiene una sola tarea: capturar la serie antes de que la olvides. Reps es el registro que quería para mí. Se abre en el día de hoy, muestra el split que planifiqué y registra una serie con un solo toque en un círculo. No hay feed ni números de otros, porque nunca iba a usar ninguna de las dos cosas entre series.

Una serie es un peso y un número de repeticiones. El RPE, los temporizadores de descanso y las notas existen para quienes los quieren y no estorban a nadie más. Los récords personales se calculan solos a partir de las series completadas: el peso máximo, más un máximo de una repetición estimado con la fórmula de Brzycki.

La función que conservaría si tuviera que recortar todo lo demás son los días bloqueados. Termina un día, bloquéalo, y la app rechaza cualquier edición hasta que tú mismo lo desbloquees. Desbloquear es un acto explícito dentro de la app, y una automatización que actúe en tu nombre no puede editar un día bloqueado en absoluto. Cuando revisas un mes de entrenamiento, un día bloqueado se lee exactamente como lo registraste.

El modelo de negocio sigue la misma regla. El registro es gratuito, para siempre, y tu historial nunca queda detrás de un muro de pago. La suscripción Reps Pro vende exactamente una cosa: planificación con IA gestionada, para quienes quieren el planificador sin traer su propia clave de API.

Entrenamiento bloqueado en 941 Reps: series completadas tachadas y el candado del día cerrado
Un día bloqueado se lee exactamente como lo registraste.
Diseño

Escritura a mano sobre una pizarra.

Los cuadernos de entrenamiento en papel acertaron en una cosa: una fecha, un ejercicio y números garabateados debajo. Reps conserva el objeto completo. Las fechas y los pesos se muestran en Bradley Hand y Noteworthy, la paleta se mantiene en tinta sobre casi negro con un solo verde, y los separadores no son un asset de textura. Oscilan porque un Shape de dieciséis líneas desplaza cada segmento fuera de la línea media:

Swift · Theme.swift:143-158
struct RepsHandDrawnLine: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
        let segments = max(Int(rect.width / 12), 8)
        let segmentWidth = rect.width / CGFloat(segments)
        path.move(to: CGPoint(x: 0, y: rect.midY))

        for index in 1...segments {
            let x = CGFloat(index) * segmentWidth
            let y = rect.midY + (index.isMultiple(of: 2) ? -0.8 : 0.9)
            path.addLine(to: CGPoint(x: x, y: y))
        }

        return path
    }
}

Prueba la fila de abajo. Reconstruye la interacción central de la app para esta página: toca un círculo para completar una serie, luego bloquea el día y mira cómo te rechaza.

Viernes, 12 de junio

Pecho / Espalda

Remo invertido

Toca los círculos. Bloquea el día. Inténtalo de nuevo.

Donde termina la escritura a mano.

Diez de los diecisiete idiomas del lanzamiento usan las tipografías manuscritas. El japonés, el coreano, el chino, el árabe, el hindi y el tailandés recurren a SF Rounded, porque Bradley Hand no tiene glifos para esas escrituras y una fuente CJK de falsa caligrafía se lee como un disfraz. El color sigue la misma disciplina: el verde de la marca es claro, así que el texto de acento sobre superficies claras se oscurece a sí mismo para mantener una relación de contraste de 5.4:1, y los estados de foco en tvOS llevan su propia tinta. Cada objetivo táctil respeta el mínimo de 44 puntos de Apple, porque tocas estos controles entre series con fatiga en las manos, no en un escritorio.

Las partes que nunca ves vienen de Kit941, el sistema de diseño en SwiftUI que comparten las apps de 941: tokens de espaciado, movimiento y hápticos, componentes probados con snapshots y el Liquid Glass de Apple envuelto detrás de un solo estilo. Reps nunca llama a .glassEffect() directamente. El aspecto de cuaderno pertenece a Reps; los huesos son compartidos.

Plataformas

iPhone, iPad y Apple Watch, en diecisiete idiomas.

Reps funciona en iPhone, iPad y Apple Watch desde una sola base de código en SwiftUI. La app del Watch se mantiene deliberadamente pequeña: muestra las series del día y las marca como hechas desde la muñeca, y WatchConnectivity lleva cada cambio al teléfono en segundos. En un gimnasio, una lista de verificación le gana a un teclado.

Siri y Atajos se conectan a través de App Intents. Di «registra una serie» y la serie queda guardada sin abrir la app, porque el intent se envía por la misma ruta de escritura validada que usa la interfaz.

941 Reps en iPad: la sesión de pecho y espalda de hoy con las series completadas tachadas
iPad
941 Reps en Apple Watch: las series de hoy como lista de verificación, press de banca con barra 260 lb por 6
Apple Watch
941 Reps en Mac: el cuaderno manuscrito en una ventana de escritorio
Mac, en desarrollo.
941 Reps en Apple TV: el entrenamiento del día con una fila de serie enfocada
Apple TV, en desarrollo.
  • English
  • Deutsch
  • Español
  • Français
  • Italiano
  • Nederlands
  • Português
  • Svenska
  • Bahasa Indonesia
  • Tiếng Việt
  • 日本語
  • 한국어
  • 简体中文
  • 繁體中文
  • العربية
  • हिन्दी
  • ไทย

Diecisiete idiomas desde el primer día, con metadatos del App Store en 22 configuraciones regionales. Un script de verificación somete cada build a una sola regla: cero claves faltantes en 735 cadenas.

Las versiones para Mac y Apple TV existen y funcionan. Se lanzarán cuando estén listas.

Ingeniería

Una sola puerta de entrada.

Reps incluye un conector: una CLI y un servidor MCP que le dan a un agente acceso real a tu registro. Claude lee tu historial, nota qué se estancó y planifica el viernes. Desde la terminal:

reps — zsh
$ reps last
Friday, June 26 — Chest / Back  [locked]
  Barbell Bench Press   255 lb × 6, 6, 6, 5
  Weighted Pull-Up      25 lb × 5, 5, 4
  Weighted Dip          60 lb × 10, 10, 10

$ claude "I started BJJ twice a week. What should change?"
Reading your last 8 weeks via the reps connector… pulling
volume is high for a grappling schedule. Suggesting: drop one
row day, add hip hinge + neck work. Plan Friday around this?

Las lecturas y las escrituras toman caminos distintos. Las lecturas abren una réplica local sincronizada de tus datos, de solo lectura, de modo que una consulta no puede corromper nada y funciona sin conexión. Las escrituras nunca tocan ese almacén. Cada mutación llega a la app como un comando; la app lo valida con las mismas reglas que aplica la interfaz, lo aplica, lo sincroniza y devuelve un recibo. Un día bloqueado rechaza la edición de un agente exactamente igual que rechaza la yema de un dedo.

Hoja del planificador de 941 Reps: comandos rápidos y un compositor en lenguaje natural
El planificador: comandos rápidos, o pide en lenguaje natural.

Cada comando que acepta el conector pasa por la misma validación que un toque, y un día bloqueado lanza un error antes de que nada toque el almacén:

Swift · ConnectorCommandHandler.swift:438-448
guard let session = try sessionForDay(date, modelContext: modelContext) else {
    throw CommandError.validationFailed("no workout exists on \(dayLabel)")
}
guard !session.isLocked else {
    throw CommandError.dayIsLocked(dayLabel)
}
guard let target = (session.sets ?? []).first(where: {
    $0.exerciseName.caseInsensitiveCompare(exerciseName) == .orderedSame
        && $0.setNumber == setNumber
}) else {
    throw CommandError.validationFailed("no set \(setNumber) of \(exerciseName)")
}

El planificador con IA recibe el mismo trato. El modelo, gestionado o con tu propia clave, solo interpreta la intención: qué tipo de día, qué enfatizar, qué evitar. Un motor determinista en el teléfono hace la programación real: elige ejercicios del corpus de 42 levantamientos, aplica esquemas de repeticiones acordes a tu objetivo, progresa las cargas a partir de tu historial registrado y revisa el resultado antes de que llegue al registro. La IA nunca escribe un entrenamiento directamente.

Dos arquitecturas funcionales murieron en el camino: una extensión de Claude Desktop basada en archivos y, después, un servidor emparejado en la red local con TLS pinning y su propio bus RPC. Cada una agregaba una segunda puerta a los datos, así que cada una salió. La app publicada tiene una sola.

El conector expone 23 herramientas MCP, desde get_exercise_history hasta set_custom_program. He pasado el año escribiendo sobre software cuyo primer lector es un asistente; Reps es ese argumento convertido en producto. Get Bananas puso un servidor MCP en una lista de compras. Reps le entrega al agente un planificador y conserva las barreras de seguridad.

Privacidad

Dónde viven los datos.

Las promesas de privacidad cuestan poco, así que aquí está la configuración misma del almacén. Los datos de entrenamiento se replican en tu base de datos privada de iCloud; las métricas de salud viven en un segundo almacén que nunca se sincroniza y nunca entra en un respaldo:

Swift · RepsModelContainer.swift:67-78 (condensed)
// No explicit name: the synced configuration keeps the historical
// default.store path, which the Mac connector reads directly.
let modelConfiguration = ModelConfiguration(
    schema: syncedSchema,
    isStoredInMemoryOnly: false,
    cloudKitDatabase: .private("iCloud.com.941apps.Reps")
)
let healthCacheConfiguration = ModelConfiguration(
    "Reps-healthcache",
    schema: localSchema,
    isStoredInMemoryOnly: false,
    cloudKitDatabase: .none
)

Tus datos de entrenamiento

Viven en tu base de datos privada de iCloud y se sincronizan de dispositivo a dispositivo a través de Apple. Reps no tiene sistema de cuentas ni servidor que almacene entrenamientos. Yo no puedo leer tus números de sentadilla.

Métricas de salud

La frecuencia cardíaca y las calorías leídas de Salud permanecen en un segundo almacén: en el dispositivo, excluido de los respaldos, nunca sincronizado. Vincula un entrenamiento de Salud a un día bloqueado y solo se sincroniza el vínculo. Las mediciones se quedan en el teléfono.

Planificación con IA

Opcional. Si la usas, la solicitud del plan (tu perfil y tu historial reciente) va al proveedor que elegiste: el servicio gestionado o tu propia clave de API. El motor que expande y valida cada plan se ejecuta en el teléfono. Si prescindes de la IA, nada llega a ningún proveedor de IA.

Queda constancia.

17 idiomas en el lanzamiento
23 herramientas MCP
42 levantamientos en el corpus

Reps es gratis en el App Store. La construí para mi propio entrenamiento y es el registro que abro todos los días; si quieres lo mismo, ahí está. Si construyes para agentes, la ruta de escritura es la parte que vale la pena robar. (Las cifras son del día del lanzamiento.)