Confirmar que una escritura en la biblioteca de MusicKit realmente se aplicó, sin escanear toda la biblioteca
Esta semana encontré un pequeño vacío de confianza en Deep Cut Atlas, mientras trabajaba en algo completamente distinto. El botón “Add to Library” de la aplicación reportaba éxito en el momento en que la llamada a MusicKit no arrojaba un error. Nunca verificaba si el álbum realmente aparecía después en Apple Music.
Eso no es un error hipotético. Es simplemente una suposición sin verificar sentada en una ruta de éxito.
De dónde salió esto
Justo había terminado un spike sobre algo completamente distinto: una molestia de UX donde automatizar la aplicación en un iPhone de repuesto seguía robándole el foco a lo que fuera que estuviera haciendo en la Mac. Un callejón sin salida, en su mayor parte, pero uno bueno. Al cerrarlo me hice una pregunta al margen: ¿podría la aplicación verificar sus propias escrituras lo bastante bien como para no tener que revisar Apple Music a simple vista tan seguido durante las pruebas? Resultó que la respuesta era “no realmente, y esta es la razón.”
La trampa: volver a consultar por id no funciona
Mi primer instinto fue copiar el patrón que ya se usaba para las escrituras de listas de reproducción, que vuelven a consultar después de cada cambio. Agregar el álbum, y después buscarlo de nuevo por id, ¿verdad?
Incorrecto, y esta base de código ya había aprendido esa lección una vez. La biblioteca y el catálogo de Apple Music usan espacios de id separados para el mismo elemento. Un álbum recién agregado a la biblioteca no lleva el mismo id que tenía en el resultado de búsqueda del catálogo desde el que se agregó. Encontré exactamente la misma trampa documentada en un hilo de los Apple Developer Forums, donde un ingeniero de Frameworks confirmó que la separación es intencional y que la heurística de selección de id no es algo sobre lo que terceros deberían construir.
Entonces una verificación ingenua de “agregarlo y después buscarlo por id” nunca encontraría nada, en silencio. Peor aún, se vería correcta en una revisión de código.
La otra trampa: escanear toda la biblioteca es lento
El respaldo obvio es escanear toda la biblioteca y revisar si el álbum nuevo está ahí. Ya había medido ese costo en una pasada anterior: unos 8 segundos en un dispositivo real con una biblioteca de cinco mil álbumes. Correr eso en cada toque de “Add to Library” cambiaría un error silencioso de corrección por uno de rendimiento muy ruidoso.
Lo que realmente funcionó
La propia documentación de MusicKit sobre esto es escasa. Las respuestas de los foros eran vagas sobre por cuáles campos se puede filtrar una solicitud de biblioteca. Así que dejé de adivinar y fui directo a la fuente: el propio archivo .swiftinterface del framework, que viene incluido con cada instalación de Xcode y es básicamente la firma real de la API, sin el filtro de los posts de blog.
find / -iname "*.swiftinterface" -path "*MusicKit*"
Eso reveló algo que la documentación no explica con claridad: cada tipo de solicitud de biblioteca expone un struct de filtro real, y para álbumes incluye cadenas simples de title y artistName, filtrables directamente:
var request = MusicLibraryRequest<Album>()
request.filter(matching: \.title, contains: title)
request.filter(matching: \.artistName, contains: artistName)
Eso es una consulta dirigida del lado del servidor, no un escaneo. Confirma un álbum específico sin recorrer toda la biblioteca. Aun así hago una coincidencia exacta final contra los resultados, ya que contains es una coincidencia de subcadena, pero la parte costosa desaparece.
Demostrarlo, no solo publicarlo
Las pruebas en simulador no tocan MusicKit real en absoluto aquí, así que compilé para el iPhone de repuesto que uso para pruebas en dispositivo, ejecuté a mano el flujo real de “Add to Library,” y observé el ida y vuelta de confirmación contra los servidores de Apple, de verdad. El botón mostró “Added to your library” solo después de que la nueva búsqueda lo encontró, y el álbum desapareció limpiamente de la lista de reproducción de origen después. Esa es la diferencia entre “el código compila” y “la cosa realmente funciona,” y en una función de MusicKit las dos no son la misma afirmación.
La parte que vale la pena recordar
Cuando la documentación de terceros y las respuestas de los foros son vagas sobre las capacidades reales de un framework, la superficie real de la API normalmente ya está en el disco, en el SDK instalado. Leerla directamente fue más rápido y más preciso que buscarla.
Lecturas relacionadas
La ventana espejada mintió sobre que el teléfono estaba desbloqueado
Un arreglo de agrupación de una línea que ya estaba escrito, y tres muros entre eso y la prueba: aislamiento de actores, el alcance exclusivo a Mac de log stream, y una sesión espejada que parece desbloqueada cuando el dispositivo no lo está.
Álbumes de preestreno, y la solución que no pude verificar del todo
Los marcadores de posición 'Track N' de Apple se mostraban como si fueran datos reales. La única señal de detección que no pude confirmar se convirtió en la única señal de la que dejé de depender.
Un botón de suscripción, una API de MusicKit que nunca había usado, y una sheet que se cierra en silencio
musicSubscriptionOffer presenta la sheet nativa de Apple, y nada en la app se enteraría jamás de que se cerró. La acción correctamente codificada que igual era un callejón sin salida funcional.