Il problema: sto lavorando su un documento iCloud sul dispositivo A, ad es. Ipod touch. Quindi cambio il nome del documento sul dispositivo B, ad es. il mio Mac (tramite il Finder). Il cambiamento arriva al cloud e dopo una pausa il dispositivo A arriva a sentirlo.iCloud - la rinominazione di documenti aperti su un altro dispositivo a volte fallisce
E poi:
- una parte del tempo tutto è bene - prendo il cambiamento di nome tramite una cambiato
fileURL
proprietà e posso aggiornare il mio interfaccia di conseguenza - il documento continua a comportarsi proprio come dovrebbe - parte del tempo, il fileURL del documento viene restituito come qualcosa come:
file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95
Non sorprende che questo file non salverà.
Qualcuno può spiegare cosa sta succedendo e come aggirare?
Sfondo
Il cambio di nome è raccolto multa da da
NSMetadataQuery
. Pertanto, ad esempio, posso rinominare i documenti che non sono aperti e tutte le funzionalità di iCloud funzionano correttamente. Il problema sembra solo verificarsi con documenti aperti.Altre funzioni di iCloud funzionano correttamente, ad es. Posso modificare il contenuto su un dispositivo, ad es. il mio Mac, e rilevare e quindi aggiornare la mia interfaccia su un altro dispositivo, ad es. il mio iPod Touch, che ha il documento iCloud pertinente aperto.
Ho notato questo quando ho aggiunto un override per
presentedItemDidMoveToURL:
alla sottoclasse UIDocument. L'override recupera in modo affidabile le modifiche al nome apportate nel cloud, ad es. rinominare il documento su un altro dispositivo. Quindi a volte newURL è l'URL finale previsto per il documento rinominato, ovvero qualcosa di sensato da cui posso estrarre il nuovo nome, utilizzare 'lastPathComponent', aggiornare la mia interfaccia ecc. In altre occasioni newURL è un documento in qualche altra directory con un ultimo componente del percorso che inizia con 'purg-', es Purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95.- (void) presentedItemDidMoveToURL:(NSURL *) newURL; { [super presentedItemDidMoveToURL: newURL]; if ([(id)[self delegate] respondsToSelector:@selector(documentNameChanged:)]) { [[self delegate] documentNameChanged: self]; } }
Il metodo
presentedItemDidMoveToURL:
non sembra essere la causa principale del problema. Ad esempio, se non sovrascrivo quel metodo, ma periodicamente controlla il viewController che si occupa del documento aperto, allora a volte dopo un rinominarefileURL
restituirà il nuovo nome e a volte restituirà `purg -..... '. Quindi il problema sembra essere relativo alla modalità di gestione della rinomina.
Aggiornamento
Come al_lea ha sottolineato, il problema qui era collegato a accommodatePresentedItemDeletionWithCompletionHandler:
. Espandendo la risposta di al_lea, ho aggiunto il codice qui sotto alla mia sottoclasse UIDocument. Questo risolve il 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 questo codice in atto, non ci sono presentedItemDidMoveToURL spuria e confusa: le chiamate effettuate e, in aggiunta, l'oggetto in questione possono ascoltare per le notifiche di eliminazioni su altri dispositivi.
Ho provato a far funzionare iCloud usando solo DocumentState per circa un mese: questo era il pezzo che mi mancava. Prima di aggiungere questo codice gli articoli a volte ritornano dopo la cancellazione, oppure otterrei un flusso continuo di stati del documento che cambiano continuamente –