2015-10-08 4 views
5

sto ottenendo la seguente eccezione quando si tenta di estrarre dall'archivio quando si utilizza Swift:NSKeyedUnarchiver non può decodificare oggetto della classe NSKnownKeysDictionary1

terminazione app a causa di eccezione non identificata 'NSInvalidUnarchiveOperationException', la ragione: '*** - [NSKeyedUnarchiver decodeObjectForKey:]: impossibile decodificare l'oggetto della classe (NSKnownKeysDictionary1) per la chiave (NS.objects); la classe può essere definita nel codice sorgente o in una libreria non collegata '

Contesto: sto creando un'estensione "Condividi collegamenti". Nella mia app principale (scritta nell'Obiettivo C) scrivo una serie di dizionari con le informazioni sui collegamenti usando MMWormhole.

NSFetchRequest* bookmarkFetch = [NSFetchRequest fetchRequestWithEntityName:@"XX"]; 
    bookmarkFetch.propertiesToFetch = @[ 
             @"name", @"text", @"date", @"url" 
             ]; 
    bookmarkFetch.resultType = NSDictionaryResultType; 
    NSArray* bookmarks = [moc executeFetchRequest:bookmarkFetch error:NULL]; 

    [wormhole passMessageObject:bookmarks identifier:@"XXX"]; 

I valori nell'array sono NSStrings e NSDate.

Nelle viscere della MMWormhole si ottiene:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:messageObject]; 

messageObject è solo la matrice preferiti senza alcuna elaborazione intermedia.

Nel estensione ho:

let wormhole = MMWormhole(applicationGroupIdentifier: "group.XX", optionalDirectory:nil) 
    let bookmarks = wormhole.messageWithIdentifier("XXX") as? Array<Dictionary<String,AnyObject>> 

messageWithIdentifier: finisce in ultima analisi, la chiamata a questo:

id messageObject = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 

La matrice viene scritto nella cartella di gruppo applicazione in modo corretto - posso leggerlo usando un'altra estensione, una scritta nell'obiettivo C.

Questa eccezione viene visualizzata quando eseguo il simulatore. Il codice appare per funzionare correttamente quando viene eseguito su un dispositivo a 32 bit (iPhone 5 e iPad 3). Non ho un dispositivo a 64 bit per testare al momento.

Immagino di perdere uno import o un framework, ma quale/i?

+0

Qual è il formato di 'data' al viene chiamato 'NSKetedUnarchiver'? È possibile che i valori o la struttura della classe siano cambiati in codice da quando sono stati salvati per la prima volta nel filesystem? La pulizia di dati/cache derivati ​​potrebbe dirti se questo è il problema. – ColinMasters

+0

Passa semplicemente l'NSArray 'bookmarks' direttamente a NSKeyedArchiver. Ho aggiornato la mia domanda con quel codice. –

risposta

2

L'ho chiesto nei forum degli sviluppatori Apple e (per una volta) got a good answer da Apple Developer Relations. Citerò i bit importanti:

NSKnownKeysDictionary1 è un voodoo di Core Data che non capisco. ... Chiaramente qualcosa non funziona con la sua serializzazione e la deserializzazione . Avete i Core Data attivi e funzionanti su entrambe le estremità del worm ? Indipendentemente da ciò, potrebbe essere più sensato fare una copia approfondita dell'array di segnalibri (e qualsiasi altra cosa che si ottiene dai dati di Core ) in modo da inviare dizionari standard attraverso il "filo" piuttosto che roba di dati di base.

Quindi la mia soluzione è aggiungere il framework Core Data all'estensione o eseguire la copia profonda. (Ho fatto temporaneamente l'ex La soluzione corretta è probabilmente il secondo..)

+0

Basta aggiungere il framework Core Data nella tua estensione :). –

4

Questa è solo una nota a margine:

È possibile impostare nomi di classe sia per il NSKeyedArchiver & NSKeyedUnarchiver. Ho avuto questo problema senza occuparmi di CoreData. L'unarchiver non ha più trovato la mia classe.

Impostazione del className per la mia classe funziona come illustrato di seguito:

Per la archiver:

NSKeyedArchiver.setClassName("MyClass", for: MyClass.self) 
let data = NSKeyedArchiver.archivedData(withRootObject: root) 

E il unarchiver:

NSKeyedUnarchiver.setClass(MyClass.self, forClassName: "MyClass") 
let root = NSKeyedUnarchiver.unarchiveObject(with: data)