2013-02-17 6 views
5

Moja aplikacja tworzy obiekt (PFUSER) dla każdego użytkownika i obiekt (PF) dla każdego zdarzenia, w którym uczestniczy. Działa to dobrze. wtedy mam dwa pliki powiązane z tym wydarzeniem. zapisuję pierwszy plik w PFFile, a następnie przypisuję go do zdarzenia pfobject. kiedy używam bloków i robię to w tle, w jaki sposób można się upewnić, że kontrola nadal działa tak samo dla drugiego pliku?na iOS przy użyciu analizy składni, jak zapisać dwa PFFile do PFObject w tle

Jestem nowicjuszem w blokach, więc może byłoby dla mnie bardziej zrozumiałe, dlaczego nie działa z wywołaniami zwrotnymi, ale wygląda na to, że blok uruchamia zapis w innym wątku, a bieżący jest porzucany przed wykonaniem kolejnych kroków.

Oczywiście chciałbym zrobić oba te słowa jako "zapisz w końcu", aby umożliwić korzystanie z trybu offline.

wszelkie wskazówki/przykłady, które możesz wskazać mi jako bardzo docenione.

dziękuję!

Odpowiedz

11

saveEventually nie obsługuje jeszcze PFFiles; potrzebuje więcej inteligentnych narzędzi do obsługi ponownego przesyłania między restartami. Jednak jedną z dostępnych sztuczek jest to, że PFObject wie, jak uratować swoje dzieci, w tym PFFiles. Można po prostu powiedzieć:

PFUser *user = PFUser.currentUser; 
user[@"icon"] = [PFFile fileWithData:iconData]; 
user[@"iconThumb"] = [PFFile fileWithData:iconThumbData]; 
[user saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) { 
    // user will automatically save its files & only call this once the 
    // entire operation succeeds. 
}]; 
+0

Dzięki za ten pomysł. Uratowanie ostatecznie było miłe, ponieważ w efekcie wydawało się, że moja aplikacja może to wywołać, nawet jeśli nie jest połączona. Obecnie właśnie robię "saveInBackground" dla każdego z dwóch plików. To wygląda lepiej po tym, jak po każdym zapisaniu pliku robię obecnie PFQuery, aby uzyskać obiekt, z którym chcę skojarzyć plik i go zaktualizować - robi to raz wygląda znacznie lepiej (i oznacza, że ​​mogę przestać martwić się dołączaniem plików do poprawny obiekt!). dzięki. – hangzhouharry

1

nie jestem 100% tego, co masz na myśli, bo nie pisać żadnych kodów, ale bym sobie wyobrazić, jeśli chcesz skojarzyć wiele PFFile do PFObject to wszystko trzeba zrobić:

PFObject *object = [PFQuery getObjectOfClass:@"MyFile" objectId:id]; 
[object addObject:profilePicture forKey:@"Photo"]; 
[object addObject:coverPicture forKey:@"PhotoCover"]; 
[object saveEventually]; 

Od Parse's documentation wydaje się saveEventually robi to, co chcesz:

Saves this object to the server at some unspecified time in the future, even if Parse is currently inaccessible. Use this when you may not have a solid network connection, and don’t need to know when the save completes. If there is some problem with the object such that it can’t be saved, it will be silently discarded. If the save completes successfully while the object is still in memory, then callback will be called.

+0

to nie będzie działać, otrzymasz ten błąd: nie można saveEventually PFObject w odniesieniu do nowych, niezapisanych PFFile –

1

Jak obecnie ani saveEvetually ani zapisywania do lokalnego magazynu danych są obsługiwane, poniżej jest kategorią PFObject używam przynajmniej zaoszczędzić nieaktywny, co można zapisać lub powrocie błąd:

- (void) dr_saveWithCompletionHandler: (void(^)(NSError* error)) completionBlock { 

__block BOOL canSaveEventually = YES; 

[[self allKeys] enumerateObjectsUsingBlock:^(NSString* key, NSUInteger idx, BOOL *stop) { 
    id object = self[key]; 

    if ([object isKindOfClass:[PFFile class]]) { 
     PFFile* file = (PFFile*) object; 

     if (!file.url || file.isDirty) { 
      canSaveEventually = NO; 
     } 
    } 
}]; 

void (^localCompletionHandler) (BOOL, NSError*) = ^(BOOL succeeded, NSError *error) { 

    if (succeeded) { 
     if (completionBlock) completionBlock(nil); 

    } else { 
     if (completionBlock) completionBlock(error); 
    } 
}; 

if (canSaveEventually) { 
    [self saveEventually:localCompletionHandler]; 
} else { 
    [self saveInBackgroundWithBlock:localCompletionHandler]; 
} 

}