Los botones no estaban rotos: el hilo principal estaba ocupado
118 pruebas en verde, una corrida limpia en el simulador, y botones muertos en un teléfono real. El bug era un servicio @MainActor haciendo trabajo síncrono entre awaits.
118 pruebas en verde, una corrida limpia en el simulador, y botones muertos en un teléfono real. El bug era un servicio @MainActor haciendo trabajo síncrono entre awaits.
@MainActor elimina las condiciones de carrera de datos, no las de intercalado. Un token de generación, una protección contra fallos obsoletos, y una prueba de carrera determinista sin sleeps.
Cada rama catch era código muerto en las pruebas. Una costura de fallas de 15 líneas resolvió eso, y luego una sola suite de pruebas sin anotar tumbó todo el runner.
Cinco fragmentos de ~700 líneas, instrucciones que también piden qué está bien hecho, y el paso de verificación que separó los errores reales de los plausibles.
Adoptar un linter en código que nunca tuvo uno, un hook de pre-commit sin depender de ningún framework, y tres cosas que hizo el runner de macOS que la documentación no mencionaba.
La API de compra es la parte fácil. Las costuras entre StoreKit 2, el aislamiento de Swift 6, y la observación de SwiftUI son donde se fue el tiempo.
Un mini-reproductor en línea cuando la reproducción de MusicKit queda muda en el simulador: un protocolo de dos métodos, un indicador que es una mentira honesta, y un bug dejado adentro a propósito.
Cinco pruebas que reportaban un simple «Crash»: un helper prolijo dejó que el ModelContainer se liberara mientras el store conservaba su contexto. Un contexto es algo prestado.
El verificador de aislamiento basado en regiones me dice que reporte un bug, y el Task no estructurado, pasado de moda, resulta ser la herramienta correcta.
Al construir el flujo de agregar a la biblioteca se descubrió que las copias de biblioteca y de catálogo de un mismo álbum en MusicKit son objetos sin relación entre sí, en lo que respecta a sus IDs.
Página 3 de 4