El problema: estoy trabajando en un documento de iCloud en el dispositivo A, p. iPod Touch. Luego cambio el nombre del documento en el dispositivo B, p. mi Mac (a través del Buscador). El cambio llega a la nube y después de un dispositivo de pausa, A llega a escucharlo.iCloud: cambiar el nombre de los documentos abiertos en otro dispositivo a veces falla
Y luego:
- algunos de todo el tiempo está bien - cojo el cambio de nombre a través de un cambio
fileURL
propiedad y puedo actualizar mi interfaz en consecuencia - el documento continúa comportándose como debe - algunas veces, el archivo fileURL se devuelve como algo como:
file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95
No es sorprendente que este archivo no se guarde.
¿Alguien puede explicar lo que está pasando y cómo evitarlo?
Antecedentes
El cambio de nombre es recogido por el bien de
NSMetadataQuery
. Así que, por ejemplo, puedo cambiar el nombre de los documentos que no están abiertos y toda la funcionalidad de mi iCloud funciona bien. El problema solo parece ocurrir con los documentos abiertos.Otras funciones de iCloud funcionan bien, p. Puedo cambiar el contenido en un dispositivo, p. mi Mac, y detectar y luego actualizar mi interfaz en otro dispositivo, p. mi iPod Touch, que tiene el documento relevante de iCloud abierto.
vi por primera vez este cuando he añadido un reemplazo para
presentedItemDidMoveToURL:
a mi subclase UIDocument. La anulación detecta de forma fiable los cambios de nombre realizados en la nube, p. cambiar el nombre del documento en otro dispositivo. Entonces a veces newURL es la URL final esperada para el documento renombrado, es decir, algo sensato desde el cual puedo extraer el nuevo nombre use `lastPathComponent ', actualice mi interfaz, etc. En otras ocasiones, newURL es un documento en otro directorio con una última componente de ruta que comienza por 'purg-', por ejemplo purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95.- (void) presentedItemDidMoveToURL:(NSURL *) newURL; { [super presentedItemDidMoveToURL: newURL]; if ([(id)[self delegate] respondsToSelector:@selector(documentNameChanged:)]) { [[self delegate] documentNameChanged: self]; } }
presentedItemDidMoveToURL:
El método no parece ser la causa raíz del problema. Por ejemplo, si no anulo ese método en absoluto, sino que compruebo periódicamente el control de vista que está revisando el documento abierto, entonces a veces después de cambiar el nombrefileURL
devolverá el nuevo nombre y a veces devolverá `purg -..... '. Así que el problema parece estar relacionado con cómo se maneja el cambio de nombre.
actualización
Como al_lea señaló, la cuestión aquí estaba relacionado con accommodatePresentedItemDeletionWithCompletionHandler:
. Ampliando la respuesta de al_lea, agregué el código a continuación a mi subclase UIDocument. Esto solucionó el problema.
- (void) accommodatePresentedItemDeletionWithCompletionHandler: (void (^) (NSError *errorOrNil)) completionHandler
{
PresentedDocument* presentedDocument = [self retain];
[presentedDocument closeWithCompletionHandler: ^(BOOL success) {
NSError* error = nil;
if (!success)
{
NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not close document that is being deleted on another device",
NSLocalizedDescriptionKey, nil];
error = [NSError errorWithDomain: @"some_suitable_domain"
code: 101
userInfo: userInfo];
}
completionHandler(error); // run the passed in completion handler (required)
dispatch_async(dispatch_get_main_queue(),^
{
[[NSNotificationCenter defaultCenter] postNotificationName: NOTIFY_presentedDocumentDeletedOnAnotherDevice
object: presentedDocument
userInfo: nil];
[presentedDocument tidyUpAfterDelete]; // app specific tidy up
[presentedDocument release];
});
}];
}
Con este código en su sitio, no hay presentedItemDidMoveToURL espuria y confuso: las llamadas realizadas y, además, el objeto relevante pueden escuchar para las notificaciones de las supresiones en otros dispositivos.
Intenté que iCloud funcionara con DocumentState por alrededor de un mes; esta era la pieza que me faltaba. Antes de agregar este código, algunas veces los elementos volvían después de la eliminación, o recibía un flujo continuo de documentos en constante cambio –