Construir un prompt de calificación que estaba seguro de que no se renderizaría en el simulador
Deep Cut Atlas necesitaba un prompt de calificación de App Store en algún punto, y la regla obvia es: pedirlo después de un logro genuino, no al abrir la app. Elegí “tres álbumes agregados con éxito” como señal, suficiente para significar que la app realmente cumplió su función al menos una vez, y no tanto como para que el pedido se sienta insistente.
La lógica de activación en sí no tiene nada de particular: un contador en SettingsStore, incrementado en cada adición exitosa a través de las tres pestañas que pueden dispararlo (Discover, History, y las sugerencias “More from artist” de Playlist), una verificación de umbral, y una bandera por versión de la app para que se dispare una sola vez hasta el siguiente cambio de versión. El @Environment(\.requestReview) nativo de SwiftUI se encarga de la hoja del sistema en sí, no hace falta construir ninguna interfaz para esto, basta con llamarlo en el momento indicado.
Antes de empezar, asumí que tendría que simular toda la verificación: SKStoreReviewController y su wrapper de SwiftUI son conocidos por ser poco confiables para activarse incluso en un dispositivo real, limitados por el propio límite anual por app de Apple, y había leído más de una vez que no hace absolutamente nada en el simulador. Esperaba verificar la lógica de activación con pruebas unitarias y simplemente confiar en la única línea que llama a requestReview().
Se renderizó de todos modos. Tres adiciones reales a través de la interfaz del simulador, y apareció la hoja real de calificación del sistema, al primer intento, sin necesitar ningún entitlement especial ni bandera de depuración. No era lo que esperaba al empezar, y cambió la forma de verificar el resto de la función, en vez de confiar ciegamente en la llamada, pude capturar la hoja real, confirmar que no había un nuevo aviso al reabrir la app ni con una cuarta adición, y tratar todo el flujo como algo realmente comprobado en vez de “probablemente esté bien.”
La prueba en dispositivo real que siguió fue en gran parte una formalidad a esa altura: capacidad de respuesta al tocar los botones de agregar, sin cuelgues, mismo comportamiento que en el simulador. El hallazgo interesante acá no fue la función en sí, sino que una creencia recibida sobre cómo se comporta esta API en las herramientas de desarrollo resultó ser falsa, y habría publicado con una verificación más débil de no haberlo probado directamente.
Lecturas relacionadas
Las capturas de pantalla de la App Store que nadie actualizó en dos semanas
Dos carpetas que parecen intercambiables y no lo son, un caché JSON que sobrevive la reinstalación, y tres rondas de 'parece terminado' que no lo estaban.
Un rechazo de App Store, una trampa de MusicKit, y un trabajo que creí haber perdido
Autorización no es lo mismo que suscripción, un tipo de error que no existe, y una solución ya terminada escondida en git stash mientras yo la reconstruía a partir de notas.
Lanzar Deep Cut Atlas: qué se rompió durante mi primer envío a la App Store
Un consumible que debía ser no consumible, un ID de producto que nunca se puede reutilizar, un archivo que en silencio no se reconstruyó, y un cambio de nombre con una mecha de dos semanas.