2012-06-09 9 views
5

Korzystam z narzędzia RestKit 0.10.1 z danymi podstawowymi w celu wdrożenia systemu iOS 5.0, aby utworzyć aplikację, która będzie współpracować z niestandardowym interfejsem API RESTFul. Ponieważ łączność w trybie offline jest ważna, utrzymuję pamięć podręczną danych użytkownika w lokalnej bazie danych CoreData na urządzeniu.RestKit + CoreData: Jak zapisać obiekt lokalnie, tylko po pomyślnym zapisaniu zdalnym?

Teraz RestKit jest całkiem niezły i nie było łatwo ustawić RKFetchResultsTableController, aby łatwo wyświetlać i utrwalać moje dane. Jest jednak jedno zachowanie RestKit, które nie wydaje się idealne i którego nie mogę wymyślić, jak zmienić.

Mam model o nazwie "Nagrywanie". Aby utworzyć nowe nagranie, robię, co następuje:

Recording *r = [NSEntityDescription insertNewObjectForEntityForName:@"Recording" inManagedObjectContext:[[RKObjectManager sharedManager].objectStore managedObjectContextForCurrentThread]]; 

r.name = newName; 

[[RKObjectManager sharedManager] sendObject:r toResourcePath:@"/recordings" usingBlock:^(RKObjectLoader *loader){ 
     loader.delegate = self; 
     loader.method = RKRequestMethodPOST; 
     loader.serializationMIMEType = RKMIMETypeJSON; 

     loader.serializationMapping = [RKObjectMapping serializationMappingUsingBlock:^(RKObjectMapping *serializationMapping){ 
      [serializationMapping mapAttributes:@"name", nil]; 

     }]; 

     RBMappingProvider *mappings = (RBMappingProvider *)[[RKObjectManager sharedManager] mappingProvider]; 
     loader.objectMapping = [mappings recordingObjectMapping]; 

    }]; 

ta tworzy nowy podmiot typu „Recording”, a następnie wysyła do serwera podmiotu w żądaniu POST. W przypadku sukcesu działa to świetnie.

Problem polega jednak na tym, że serwer czasami odrzuca te, które tworzą poprawnie. W takich sytuacjach stwierdzam, że istnieje już lokalna kopia obiektu w bazie danych podstawowych z identyfikatorem 0 (identyfikator jest kluczem podstawowym ustawianym przez serwer).

Jedynym sposobem na usunięcie lokalnej jednostki jest wymuszenie odświeżenia lokalnych danych z serwera.

Czy istnieje sposób na utrzymywanie obiektu lokalnie tylko wtedy, gdy serwer odpowie 2xx? Alternatywnie, czy istnieje sposób na cofnięcie zmian, jeśli serwer zareaguje cokolwiek oprócz 2xx?

Dzięki,

+0

FWIW, tworząc jednostkę z zapisu * r = [obiektu zapisu] jak podano w Dokumentach RestKit ma w ogóle nie zmieniają zachowanie. – apurva

+0

Nie masz metody zwrotnej w RK z odpowiedzią serwera? Zachowaj odwołanie do obiektu i usuń je, jeśli przesyłanie zostało odrzucone. – Mundi

+0

@mundi To jedno podejście, a może nawet bardziej pożądane. Jednak zastanawiałem się, czy możliwe było utrzymanie lokalnego stanu dopiero po zaakceptowaniu przez serwer ładunku. To spowodowałoby dużo mniej redundantnego kodu. – apurva

Odpowiedz

0

Niestety, z powodu zapisu jest NSManagedObject, nawet twoja tymczasowa instancja musi zostać włożony w kontekście zarządzanego obiektu. @ Mundi rozwiązanie utrzymania odniesienia i usunięcie go z kontekstu po błędzie jest rozwiązaniem, które bym użył. Trochę dodatkowego kodu bije pełne odświeżenie z serwera.

Aktualizacja do 0.20.x ułatwi to. Bloki udanych i niepowodzeń, które są używane podczas wysyłania żądania, bardzo ułatwiają zachowanie tego odniesienia i usunięcie go w przypadku niepowodzenia. Np

[_objectManager postObject:aMessage 
         path:@"message" 
       parameters:parameters 
        success:^(RKObjectRequestOperation * operation, RKMappingResult * mappingResult){ 
        // Success code here 
        } 
        failure:^(RKObjectRequestOperation * operation, NSError * error){ 
        [_managedObjectContext deleteObject:aMessage]; 
        [_managedObjectContext save:nil]; 
        }]; 
Powiązane problemy