Migrar un proyecto Xcode
A menos que crees un nuevo proyecto usando Tuist, en cuyo caso se te configura todo automáticamente, tendrás que definir tus proyectos de Xcode usando las primitivas de Tuist. Lo tedioso de este proceso depende de la complejidad de tus proyectos.
Como probablemente sepas, los proyectos de Xcode pueden volverse desordenados y complejos con el tiempo: grupos que no coinciden con la estructura de directorios, archivos que se comparten entre objetivos o referencias a archivos que apuntan a archivos inexistentes (por mencionar algunos). Toda esa complejidad acumulada hace que nos resulte difícil proporcionar un comando que migre los proyectos de forma fiable.
Además, la migración manual es un excelente ejercicio para limpiar y simplificar tus proyectos. No sólo lo agradecerán los desarrolladores de tu proyecto, sino también Xcode, que los procesará e indexará más rápidamente. Una vez que hayas adoptado por completo Tuist, te asegurarás de que los proyectos se definan de forma coherente y de que sigan siendo sencillos.
Con el objetivo de facilitarle esa labor, le damos algunas pautas basadas en los comentarios que hemos recibido de los usuarios.
Crear un andamiaje de proyectos#
En primer lugar, crea un andamio para tu proyecto con los siguientes archivos Tuist:
::: grupo de códigos
import ProjectDescription
let tuist = Tuist()
import ProjectDescription
let project = Project(
name: "MyApp-Tuist",
targets: [
/** Targets will go here **/
]
)
// swift-tools-version: 5.9
import PackageDescription
#if TUIST
import ProjectDescription
let packageSettings = PackageSettings(
// Customize the product types for specific package product
// Default is .staticFramework
// productTypes: ["Alamofire": .framework,]
productTypes: [:]
)
#endif
let package = Package(
name: "MyApp",
dependencies: [
// Add your own dependencies here:
// .package(url: "https://github.com/Alamofire/Alamofire", from: "5.0.0"),
// You can read more about dependencies here: https://docs.tuist.io/documentation/tuist/dependencies
]
)
:::
Project.swift es el archivo de manifiesto donde definirás tu proyecto, y
Package.swift es el archivo de manifiesto donde definirás tus dependencias. El
archivo Tuist.swift es donde puedes definir la configuración de Tuist para tu
proyecto.
Para evitar conflictos con el proyecto Xcode existente, recomendamos añadir el
sufijo -Tuist al nombre del proyecto. Puedes eliminarlo una vez que hayas
migrado completamente tu proyecto a Tuist.
Construir y probar el proyecto Tuist en CI#
Para asegurarte de que la migración de cada cambio es válida, te recomendamos que amplíes tu integración continua para construir y probar el proyecto generado por Tuist a partir de tu archivo de manifiesto:
tuist install
tuist generate
xcodebuild build {xcodebuild flags} # or tuist test
Extraiga la configuración de compilación del proyecto en .xcconfig archivos#
Extraiga la configuración de compilación del proyecto en un archivo .xcconfig
para que el proyecto sea más sencillo y fácil de migrar. Puede utilizar el
siguiente comando para extraer la configuración de compilación del proyecto en
un archivo .xcconfig:
mkdir -p xcconfigs/
tuist migration settings-to-xcconfig -p MyApp.xcodeproj -x xcconfigs/MyApp-Project.xcconfig
A continuación, actualice su archivo Project.swift para que apunte al archivo
.xcconfig que acaba de crear:
import ProjectDescription
let project = Project(
name: "MyApp",
settings: .settings(configurations: [
.debug(name: "Debug", xcconfig: "./xcconfigs/MyApp-Project.xcconfig"), // [!code ++]
.release(name: "Release", xcconfig: "./xcconfigs/MyApp-Project.xcconfig"), // [!code ++]
]),
targets: [
/** Targets will go here **/
]
)
A continuación, amplíe su canal de integración continua para ejecutar el
siguiente comando y asegurarse de que los cambios en la configuración de
compilación se realizan directamente en los archivos .xcconfigde:
tuist migration check-empty-settings -p Project.xcodeproj
Extraer dependencias de paquetes#
Extrae todas las dependencias de tu proyecto en el archivo
Tuist/Package.swift:
// swift-tools-version: 5.9
import PackageDescription
#if TUIST
import ProjectDescription
let packageSettings = PackageSettings(
// Customize the product types for specific package product
// Default is .staticFramework
// productTypes: ["Alamofire": .framework,]
productTypes: [:]
)
#endif
let package = Package(
name: "MyApp",
dependencies: [
// Add your own dependencies here:
// .package(url: "https://github.com/Alamofire/Alamofire", from: "5.0.0"),
// You can read more about dependencies here: https://docs.tuist.io/documentation/tuist/dependencies
.package(url: "https://github.com/onevcat/Kingfisher", .upToNextMajor(from: "7.12.0")) // [!code ++]
]
)
Puedes anular el tipo de producto para un paquete específico añadiéndolo al
diccionario productTypes en la estructura PackageSettings. Por defecto,
Tuist asume que todos los paquetes son frameworks estáticos.
Determinar el orden de migración#
Recomendamos migrar los objetivos del más dependiente al menos dependiente. Puede utilizar el siguiente comando para listar los objetivos de un proyecto, ordenados por el número de dependencias:
tuist migration list-targets -p Project.xcodeproj
Empiece a migrar los objetivos de la parte superior de la lista, ya que son de los que más se depende.
Migrar objetivos#
Migre los objetivos uno a uno. Recomendamos hacer un pull request por cada objetivo para asegurarse de que los cambios se revisan y prueban antes de fusionarlos.
Extraiga la configuración de compilación de destino en .xcconfig files#
Al igual que hizo con la configuración de compilación del proyecto, extraiga la
configuración de compilación del destino en un archivo .xcconfig para que el
destino sea más sencillo y fácil de migrar. Puede utilizar el siguiente comando
para extraer la configuración de compilación del destino en un archivo
.xcconfig:
tuist migration settings-to-xcconfig -p MyApp.xcodeproj -t TargetX -x xcconfigs/TargetX.xcconfig
Defina el objetivo en el archivo Project.swift#
Defina el objetivo en Project.targets:
import ProjectDescription
let project = Project(
name: "MyApp",
settings: .settings(configurations: [
.debug(name: "Debug", xcconfig: "./xcconfigs/Project.xcconfig"),
.release(name: "Release", xcconfig: "./xcconfigs/Project.xcconfig"),
]),
targets: [
.target( // [!code ++]
name: "TargetX", // [!code ++]
destinations: .iOS, // [!code ++]
product: .framework, // [!code ++] // or .staticFramework, .staticLibrary...
bundleId: "dev.tuist.targetX", // [!code ++]
sources: ["Sources/TargetX/**"], // [!code ++]
dependencies: [ // [!code ++]
/** Dependencies go here **/ // [!code ++]
/** .external(name: "Kingfisher") **/ // [!code ++]
/** .target(name: "OtherProjectTarget") **/ // [!code ++]
], // [!code ++]
settings: .settings(configurations: [ // [!code ++]
.debug(name: "Debug", xcconfig: "./xcconfigs/TargetX.xcconfig"), // [!code ++]
.debug(name: "Release", xcconfig: "./xcconfigs/TargetX.xcconfig"), // [!code ++]
]) // [!code ++]
), // [!code ++]
]
)
Si el objetivo tiene un objetivo de prueba asociado, deberá definirlo también en
el archivo Project.swift repitiendo los mismos pasos.
Validar la migración de destino#
Ejecute tuist generate seguido de xcodebuild build para asegurarse de que el
proyecto se construye, y tuist test para asegurarse de que las pruebas pasan.
Además, puede utilizar xcdiff para
comparar el proyecto Xcode generado con el existente y asegurarse de que los
cambios son correctos.
Repita#
Repita hasta que todos los objetivos estén completamente migrados. Una vez que
haya terminado, le recomendamos que actualice sus pipelines CI y CD para
construir y probar el proyecto utilizando tuist generate seguido de
xcodebuild build y tuist test.
Solución de problemas#
Errores de compilación por falta de archivos.#
Si los archivos asociados a los objetivos de tu proyecto Xcode no estuvieran todos contenidos en un directorio del sistema de archivos que representara al objetivo, podrías acabar con un proyecto que no compilara. Asegúrese de que la lista de archivos después de generar el proyecto con Tuist coincide con la lista de archivos en el proyecto de Xcode, y aprovechar la oportunidad para alinear la estructura de archivos con la estructura de destino.