writeup

mi apple watch se emparejó bien. luego lo olvidó.

kisnner obando · septiembre de 2026 · watchos 27.2 · xcode 27 / device hub · macos 27.2 · el repo · estado: resuelto después, mira el seguimiento

actualización, 3 de octubre: resultó que se arregló actualizando el iphone a ios 27.2, no con nada en el reloj. el seguimiento tiene la evidencia y sus límites: el reloj no estaba roto. mi iphone iba atrasado. lo que sigue es la investigación tal como la escribí en su momento.

un informe de un apple watch ultra 2 que desapareció de xcode 27 y no volvió. este no está resuelto. lo que tengo es una descripción mucho más estrecha del fallo que "no conecta", construida con logs del mac y del reloj, un experimento que cambió mi teoría y un callejón sin salida con un host de emparejamiento independiente. está reportado a apple como FB24924229.

resumen

el síntoma

$ xcrun devicectl list devices
iPhone (2)   available (paired)   iPhone 15 Pro Max
iPad         available (paired)   iPad Pro 12.9-inch
             (no watch)
$ xcrun devicectl manage pair --device <watch>
The specified device was not found (1000)

device hub mostraba "no disponible por ahora — debe estar cerca". instalar desde la app watch del iphone avanzaba hasta la mitad y se atascaba. antes descarté bluetooth, wi-fi, el cable, el modo desarrollador y la propia app. la lista completa está en what-i-tried.md.

1. el emparejamiento funciona y luego el canal se cierra

remotepairingd en el mac muestra un emparejamiento completo y exitoso, seguido de un cierre:

22:21:41.314  PairSetup server done -- client authenticated
22:21:41.314  tcp-79: Pairing session of kind setupManualPairing succeeded
22:21:41.344  tcp-79: received error reading message        <-- +30 ms
22:21:41.345  tcp-79: authenticated -> invalidated
22:21:41.663  DeviceHub: Beaconing pairing session explicitly ended by client

mi primer informe llamó a ese cierre de 30 ms el bug. no lo era.

2. un control: el iphone hace lo mismo

tras restablecer ubicación y privacidad, el iphone también tuvo que volver a emparejarse, un minuto antes que el reloj, en el mismo mac:

setup exitosocanal cerradoreconexión
iphone10:54:22.173+36 ms+1,4 s verifyManualPairing → available
reloj10:55:08.951+29 msninguna

el cierre es normal: termina el setup y el dispositivo reconecta con una sesión verificada. lo que falta es la reconexión del reloj. reescribí el repo y el reporte a apple para decir eso. un borrador anterior usó la reconexión de un ipad como control, que no era un setup nuevo, así que tampoco era una comparación justa.

3. los relojes se emparejan hacia el mac

el mac encuentra un iphone buscando _remotepairing._tcp. el reloj nunca anunció eso, y yo tenía "el reloj no se anuncia" como hipótesis principal. leer un log stream en vivo durante el emparejamiento mostró que el flujo es al revés para un reloj:

22:21:16  remotepairingd: Started listening for network pairing   <-- sheet opened
22:21:41  setupManualPairing succeeded
22:21:41  DeviceHub: Beaconing pairing session explicitly ended  <-- sheet closes itself

el reloj se conecta al listener _remotepairing-pairable-host._tcp del mac, y ese listener existe solo mientras la hoja emparejar dispositivo cercano… de device hub está abierta. la hoja se cierra sola ~300–400 ms después del setup. así que probablemente el reloj no se anuncia por diseño, y apareció una teoría nueva: quizá el reloj intenta reconectar, pero ya no queda nada a lo que conectarse.

4. mantener al mac escuchando

reabrir la hoja a mano dejaba un hueco de 15 s y no volvía nada. para cerrar el hueco escribí watch-pair-keeper.sh: sigue remotepairingd y, en cuanto device hub suelta el listener, vuelve a pulsar emparejar dispositivo cercano… mediante system events, y luego reporta si el reloj verificó. antes de usarlo en vivo le pasé un log capturado para comprobar los tiempos.

22:53:00.613  setupManualPairing succeeded (watch)     closed at +305 ms
22:53:01.533  mac listening again                      gap: 615 ms
22:53:23.502  Network pairing peers updated. Total count: 1   <-- the watch is back
22:53:23.558  PairingData(startNewSession: true, kind: setupManualPairing)
22:53:23.559  DeviceHub: Presenting pairing challenge   <-- a new code
22:53:33.642  setupManualPairing succeeded (watch)     closed again at +286 ms

eso refutó mi teoría y dio una respuesta mejor. el reloj sí reconecta. pero pide un pair-setup nuevo, no un pair-verify, como si hubiera olvidado el emparejamiento que terminó 23 segundos antes. el mac guardó el emparejamiento y estaba escuchando; el reloj no usó su parte. setup, cierre, setup, cierre.

un falso positivo que vale la pena mencionar: el script marcó un verifyManualPairing a las 22:53:59. era el ipad. el script solo cuenta un verify cuando la siguiente línea autenticada lleva el prefijo del udid del reloj, y por eso no reportó éxito.

5. los logs propios del reloj

un sysdiagnose del reloj (corona + botón lateral, y luego por el iphone) mostró a remotepairingdeviced iniciando el emparejamiento con normalidad: resuelve el anuncio del mac, conecta por wi-fi, lockdownShouldDisableDevicePairing: NO, "manual pairing in progress". luego el archivo no tiene líneas de ningún proceso entre las 22:21:34.1 y las 22:21:48, así que el lado del reloj del cierre de las 22:21:41 no está. (el primer archivo que salió era el del iphone. el nombre dice iPhone-OS o Watch-OS; compruébalo antes de ponerte a analizar.)

6. un host independiente

si el lado del mac no se puede cambiar, quizá se pueda reemplazar. pymobiledevice3 11.19.1 trae remote pair-host, que anuncia un host emparejable y acepta un emparejamiento iniciado por el dispositivo. el reloj lo listó en desarrollador ▸ macs emparejados ▸ otros dispositivos, pidió el código del reloj y luego nunca abrió una conexión tcp.

al host de apple se llega por ipv6 link-local; pymobiledevice3 se enlaza a 0.0.0.0 y solo publica un registro a. así que lo envolví (pair_host_dualstack.py) para escuchar en ambas familias y anunciar también el registro aaaa. mismo resultado: ninguna conexión, por ninguna de las dos. device hub además ejecuta una sesión "beaconing" que pymobiledevice3 no tiene. si el reloj la necesita, todavía no lo sé.

dónde está

errores míos en el camino

lo que me llevo

enlaces