---
name: build-errors-swift
description: >
  Resolución de errores de compilación Swift: swiftc, Swift Package Manager,
  Xcode build y Swift 6 concurrency. Incluye errores de signing, provisioning,
  módulos y linker.
  Cargar cuando un build Swift/iOS falle o haya errores de compilación.
version: "1.0.0"
herramientasPermitidas: [Read, Bash, Grep]
exclusiones:
  - "No cargar para bugs de lógica de la app iOS/macOS en runtime (crashes en EXC_BAD_ACCESS, lógica de negocio incorrecta) cuando `xcodebuild` compila — si el archive se genera pero la app crashea, no es un error de compilación."
  - "No cargar para fallos de XCTest cuando el build compila (assertions fallidas, snapshot tests que difieren) — es un error de lógica de tests, no de build."
  - "No cargar para diseñar la arquitectura Swift/iOS desde cero (MVVM, TCA, SwiftUI vs UIKit) — si la pregunta es qué patrón usar, cargar `swift-patrones` o `swift-experto`."
  - "No cargar para problemas de distribución de App Store o TestFlight que no son errores de compilación (metadatos, capturas de pantalla, review guidelines) — esos son problemas de distribución, no de build."
evolvable: true  # default para skill estandar
---
# Build Errors Swift — Diagnóstico y Solución

## Cuándo NO cargar

- El build compila pero la app crashea en runtime (EXC_BAD_ACCESS, lógica incorrecta) — no es un error de build; analizar con el crash log y Xcode debugger.
- XCTest compila pero las assertions fallan — es un error de lógica de tests.
- La pregunta es qué arquitectura usar en SwiftUI — para diseño cargar `swift-patrones`.

## Cuándo cargar

- `xcodebuild` o `swift build` falla con errores del compilador
- Errores de Swift 6 concurrency (`Sendable`, actor isolation)
- Errores de SPM (resolución de dependencias, version conflicts)
- Errores de Xcode (signing, provisioning profile, bitcode)
- `module not found` o errores de importación
- Errores de linker en proyectos Swift/ObjC mixtos

---

## Errores del Compilador Swift

### `value of type X has no member Y`

**Causa**: propiedad o método no existe en el tipo, typo en el nombre, o falta import.

```swift
// MAL
import Foundation
let url = URL(string: "https://ejemplo.com")
let host = url.hostname  // error: URL no tiene 'hostname'

// BIEN — verificar nombre correcto en documentación
let host = url?.host          // propiedad correcta en URL
let hostStr = url?.host()     // en versiones modernas es funcion

// MAL — acceder a miembro de Optional sin desenvolver
var texto: String? = "hola"
let longitud = texto.count    // error: Optional<String> no tiene 'count'

// BIEN
let longitud = texto?.count ?? 0
```

### `cannot convert value of type X to expected argument type Y`

**Causa**: tipo incorrecto pasado a una función o inicializador.

```swift
// MAL
func configurar(timeout: TimeInterval) { }
configurar(timeout: 30)     // error: Int no convierte a TimeInterval implícitamente

// BIEN — conversión explícita o usar el tipo correcto desde el inicio
configurar(timeout: TimeInterval(30))
configurar(timeout: 30.0)    // Double literal -> TimeInterval (alias de Double)

// MAL — String vs Data
URLSession.shared.uploadTask(with: request, from: "datos")  // error: String no es Data

// BIEN
let datos = "datos".data(using: .utf8)!
URLSession.shared.uploadTask(with: request, from: datos)
```

### `expression is ambiguous without more context`

**Causa**: inferencia de tipos falla por sobrecarga de funciones o literales ambiguos.

```swift
// MAL
let resultado = [1, 2, 3].map { $0 * 2 }  // puede ser ambiguo en contextos complejos

// BIEN — anotar el tipo explícitamente
let resultado: [Int] = [1, 2, 3].map { $0 * 2 }

// MAL en SwiftUI
Text(valor)  // error si 'valor' puede ser Int o String

// BIEN
Text(String(valor))
Text("\(valor)")
```

---

## Swift 6 Concurrency — Errores de Sendable y Actor Isolation

### `sending non-Sendable value across actor boundary`

**Causa**: se pasa un tipo no-Sendable a un contexto de actor o tarea async.

```swift
// MAL — clase mutable sin Sendable
class ConfiguracionMutable {
    var tema: String = "oscuro"
}

// En Swift 6 esto falla:
Task {
    let config = ConfiguracionMutable()
    await procesador.configurar(config)  // error: no es Sendable
}

// BIEN — opción 1: usar struct (implícitamente Sendable si todos los campos lo son)
struct Configuracion: Sendable {
    let tema: String
}

// BIEN — opción 2: marcar como @unchecked Sendable con sincronización manual
final class ConfiguracionSincronizada: @unchecked Sendable {
    private let lock = NSLock()
    private var _tema: String = "oscuro"
    var tema: String {
        get { lock.withLock { _tema } }
        set { lock.withLock { _tema = newValue } }
    }
}
```

### `actor-isolated property can not be referenced from a non-isolated context`

**Causa**: acceder a propiedad de un actor sin `await`.

```swift
// MAL
actor GestorCache {
    var elementos: [String: Any] = [:]
}

let gestor = GestorCache()
print(gestor.elementos)  // error: requiere await

// BIEN — acceder desde contexto async
Task {
    let elems = await gestor.elementos
    print(elems)
}

// BIEN — si el acceso es frecuente, exponer una función nonisolated
extension GestorCache {
    nonisolated var descripcion: String { "GestorCache" }
}
```

---

## Swift Package Manager — Errores de Dependencias

### `the package at X has no remote at Y`

**Causa**: URL del repositorio incorrecta o privada sin credenciales.

```swift
// En Package.swift — verificar URL exacta
.package(url: "https://github.com/org/paquete.git", from: "1.0.0")

// Para paquetes privados en Xcode:
// Xcode > Preferences > Accounts > agregar cuenta GitHub/GitLab con token
```

### Conflicto de versiones entre dependencias transitivas

```swift
// Error: "package has already been required using a different source control requirement"
// Un paquete requerido con diferentes rangos de versión

// SOLUCIÓN: pinear versión exacta en Package.swift de la app
.package(url: "https://github.com/apple/swift-log.git", exact: "1.5.3")

// O usar el mínimo compatible que satisfaga a todos
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0")
```

---

## Xcode Build — Signing y Provisioning

### `Code signing is required for product type 'Application'`

```bash
# Diagnóstico rápido
xcodebuild -showBuildSettings | grep -E "CODE_SIGN|DEVELOPMENT_TEAM|PROVISIONING"

# Para CI sin cuenta de desarrollador (simulador/tests):
xcodebuild test \
  -scheme MiApp \
  -destination 'platform=iOS Simulator,name=iPhone 15' \
  CODE_SIGNING_ALLOWED=NO \
  CODE_SIGNING_REQUIRED=NO

# Para builds de producción: usar automatic signing en Xcode
# o exportar el perfil de aprovisionamiento como archivo .mobileprovision
```

### `Provisioning profile doesn't include the X entitlement`

**Causa**: la capability está en el proyecto pero no en el provisioning profile.

```
Pasos de resolución:
1. Xcode > Signing & Capabilities > verificar que la capability está listada
2. developer.apple.com > Identifiers > actualizar App ID con la capability
3. Regenerar provisioning profile en developer.apple.com
4. Xcode > Preferences > Accounts > Download Manual Profiles
```

---

## Module Not Found / Linker Errors

### `No such module 'X'`

**Causa**: framework no agregado al target, o SPM no resuelto.

```bash
# Para SPM: resolver paquetes
File > Packages > Resolve Package Versions

# Para frameworks del sistema: agregar en Xcode
# Target > Build Phases > Link Binary With Libraries > agregar el framework

# Para frameworks propios: verificar FRAMEWORK_SEARCH_PATHS en Build Settings
```

### `Undefined symbol: _X` (linker error)

**Causa**: símbolo declarado pero no implementado, o librería no linkeada.

```bash
# Diagnóstico: el error indica el archivo objeto que necesita el símbolo
# Buscar en que libreria/framework esta el simbolo:
nm -gU /path/to/Framework.framework/Framework | grep "_NombreSimbolo"

# Si es Swift <-> ObjC interop: verificar que el bridging header esta configurado
# Build Settings > Swift Compiler - General > Objective-C Bridging Header
```

---

## Gotchas / Errores comunes no obvios

- **Swift 6 strict concurrency activa en el package pero no en los targets individuales**: `swift build` falla con errores de actor isolation aunque el developer activó `SWIFT_STRICT_CONCURRENCY=complete` en el paquete raíz. Causa: en Swift Package Manager, el flag de concurrency debe declararse en cada target individualmente en `Package.swift` con `swiftSettings: [.enableExperimentalFeature("StrictConcurrency")]` — el setting del paquete padre no se propaga automáticamente. Solución: agregar el setting por target explícitamente, o usar el flag de compilación `-strict-concurrency=complete` en CI.
- **SPM resuelve el paquete correctamente en Xcode pero `swift build` en terminal falla con "no such module"**: el proyecto Xcode tiene un `DerivedData` cacheado con la versión correcta, pero en terminal el directorio de build es diferente. Causa: Xcode y `swift build` usan directorios de caché diferentes (`DerivedData` vs `.build/`). Solución: ejecutar `swift package resolve && swift build` desde el directorio del paquete, o eliminar el directorio `.build/` para forzar una resolución limpia.
- **Error de signing "No profiles for bundle identifier X"** en CI aunque el certificate y el provisioning profile están instalados: el provisioning profile está instalado para el usuario del developer pero el CI ejecuta con un usuario diferente. Causa: los profiles se instalan en `~/Library/MobileDevice/Provisioning Profiles/` del usuario actual — en CI cada ejecución puede tener un usuario diferente. Solución: copiar el provisioning profile al directorio del usuario del agente CI en el step de setup, o usar `xcodebuild -allowProvisioningUpdates` con App Store Connect credentials.
- **`Product > Clean Build Folder` resuelve el error temporalmente pero vuelve a aparecer en el siguiente build incremental**: hay un archivo generado por un script de build phase que tiene un timestamp más nuevo que los archivos fuente, forzando una recompilación con el archivo corrupto. Causa: un `Run Script Build Phase` sin `Input Files` ni `Output Files` declarados se ejecuta en cada build incremental y puede sobreescribir archivos generados con contenido incorrecto. Solución: agregar `Input Files` y `Output Files` explícitos al script de build phase para que Xcode solo lo ejecute cuando los inputs cambien.

## Checklist de Diagnóstico

- [ ] Leer el error completo en Xcode: el error secundario suele ser la causa raíz.
- [ ] `Product > Clean Build Folder` (Cmd+Shift+K) antes de reintentar.
- [ ] Para errores de Swift 6: habilitar incrementalmente con `SWIFT_STRICT_CONCURRENCY`.
- [ ] Para SPM: `File > Packages > Reset Package Caches` si hay errores de resolución.
- [ ] `xcodebuild -verbose` en terminal para diagnóstico más detallado que la UI.
- [ ] Verificar que `IPHONEOS_DEPLOYMENT_TARGET` es compatible con las APIs usadas.
- [ ] Para errores de signing en CI: verificar que los certificados no expiraron.
- [ ] `swift package diagnose-api-breaking-changes` para detectar breaking changes en SPM.
