2014-11-30 19 views
8

Mam obiekt użytkownika, który muszę przechowywać w NSUserDefaults i udostępniać z aplikacją rozszerzenia iOS 8 (Watchkit). W głównej aplikacji kontenerowej mogę kodować i dekodować obiekt bez żadnych problemów. Jednak gdy próbuję pobrać przechowywany obiekt użytkownika w rozszerzeniu, pojawia się błąd "'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class".NSInvalidUnarchiveOperationException nie może zdekodować błędu obiektu w rozszerzeniu Apple Watch

O ile widzę NSCoding został poprawnie zaimplementowany w obiekcie (i jestem w stanie zakodować i odkodować obiekt w "głównej" aplikacji).

Kod w aplikacji "Kontener" do przechowywania obiektu użytkownika.

//Store user data in NSUserDefaults 
NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.mygroup"]; 

SFUserAccount *user = [SFUserAccountManager sharedInstance].currentUser; 

NSData *userEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:user]; 
[defaults removeObjectForKey:@"SF User Acct1"]; //remove any old values 
[defaults setObject:userEncodedObject forKey:@"SF User Acct1"]; 

[defaults synchronize]; 
SFUserAccount *decodedUser = [NSKeyedUnarchiver unarchiveObjectWithData:userEncodedObject]; 

Ostatni wiersz powyżej, aby wykonać dekodowanie testu w aplikacji głównej, działa poprawnie.

Kod do pobrania z NSUserDefaults i dekodowania w docelowym rozszerzeniu znajduje się poniżej.

NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.mygroup"]; 
    NSData *archivedUser = [defaults objectForKey:@"SF User Acct1"]; 



    if (archivedUser){ 
     SFUserAccount *user = [NSKeyedUnarchiver unarchiveObjectWithData:archivedUser]; 
    } 

W kodzie rozszerzenia, dostaję " 'NSInvalidUnarchiveOperationException', przyczyna:„*** - [NSKeyedUnarchiver decodeObjectForKey:]: nie można zdekodować obiekt klasy"

sugestie co do miejsca, gdzie powinien zacząć szukać? Aplikacja kompiluje dobrze, co prowadzi mnie do przekonania, że ​​wymagane ramy zostały włączone do celu rozszerzenia.

+1

Czy plik implementacji, w którym zdefiniowano SFUserAccount, jest dodany w miejscu docelowym rozszerzenia? – msk

+1

Plik binarny jest zawarty w tarczy. Ale twoje pytanie doprowadziło mnie do dalszych badań. Okazuje się, że musiałem ustawić flagę Set Other linker na "-ObjC -all_load". Nie jestem pewien, co dokładnie robi, ale teraz działa! Wielkie dzięki za Twoją pomoc. – YogiBotics

+0

te flagi łączące są prawdopodobnie nieco przesadzone. Sprawdź, czy pliki klas należą do obu celów. – dwery

Odpowiedz

9

Aby Twoje rozszerzenie WatchKit mogło dekodować obiekty SFUserAccount, musi zrozumieć klasę SFUserAccount. Aby to umożliwić, należy go dodać do rozszerzenia WatchKit.

  1. Kliknij swoją nazwę projektu w Nawigatorze projektu, na górze lewej kolumny w Xcode. (Naciśnij Cmd-1, aby wyświetlić nawigator projektu, jeśli jest on ukryty:
  2. Kliknij, aby podświetlić nazwę rozszerzenia WatchKit po lewej stronie głównego okna, pod "Celami". (UWAGA: zaznacz swoje rozszerzenie WatchKit Rozszerzenie, nie WatchKit App.
  3. Wybierz „Budowanie Fazy” w pozycji na górze.
  4. Obok „skompilować źródła”, użyj trójkąt, aby wyświetlić sekcję, jeśli nie jest już widoczny.
  5. Kliknij "+" u dołu sekcji, aby dodać nowe źródło:
  6. Z listy wybierz plik .m dla klasy, którą chcesz dodać (w tym case, plik SFUserAccount.m).
  7. Kliknąć "Dodaj".
  8. Buduj i biegnij.
+0

Nice! Potrzebowałem tego, gdy próbowałem przekazać zdefiniowaną przez użytkownika klasę między aplikacją hosta iOS a rozszerzeniem WatchKit. –

+0

To jest właściwa odpowiedź! – OxenBoxen

Powiązane problemy