harry
harry

Reputation: 338

on iOS using Parse, how to save two PFFiles to a PFObject in background

My app creates an object (PFUSER) for each user, and an (PF) object for each event they participate in. This works fine. then i have two files associated with that event. i save the first file to a PFFile, then associate it to the event pfobject. when i use blocks and do this in the background, how can then make sure control continues to do the same for the second file?

I am new to blocks so maybe it would be clearer to me why its not working with callbacks, but it seems the block runs the save in another thread and the current one is abandoned before the next steps are taken.

Of course i'd like to do both of these as "save eventually" to allow offline use.

any guidance / examples you can point me to greatly appreciated.

thanks!

Upvotes: 5

Views: 4686

Answers (3)

As currently neither saveEvetually nor saving to the local data store are supported, below is a category of PFObject I am using to at least save offline what can be saved or returning error:

    - (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];
}

}

Upvotes: 1

Thomas Bouldin
Thomas Bouldin

Reputation: 3725

saveEventually doesn't support PFFiles yet; it needs a bit more smarts to handle resuming uploads between restarts. One trick that is already available, however, is that PFObject knows how to save its children, including PFFiles. You can just say:

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.
}];

Upvotes: 11

Enrico Susatyo
Enrico Susatyo

Reputation: 19790

I'm not 100% what you mean because you didn't post any codes, but I'd imagine if you want to associate multiple PFFile to PFObject this is all you have to do:

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

From Parse's documentation it seems like saveEventually does what you want:

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.

Upvotes: 1

Related Questions