在iOS上使用Parse,如何在后台保存两个PFFiles到PFObject

时间:2013-02-17 14:45:26

标签: objective-c-blocks parse-platform

我的应用为每个用户创建一个对象(PFUSER),为他们参与的每个事件创建一个(PF)对象。这很好用。然后我有两个与该事件相关的文件。我将第一个文件保存到PFFile,然后将其关联到事件pfobject。当我使用块并在后台执行此操作时,如何确保控件继续对第二个文件执行相同操作?

我是阻止的新手,所以也许我会更清楚为什么它不使用回调,但似乎该块在另一个线程中运行保存,并且在下一步采取之前放弃当前的一个。

当然,我希望将这两者作为“最终保存”以允许离线使用。

您可以指出我非常感谢的任何指导/示例。

谢谢!

3 个答案:

答案 0 :(得分:11)

saveEventually尚不支持PFFiles;它需要更多的智能来处理重启之间的恢复上传。然而,一个已经可用的技巧是PFObject知道如何保存它的子节点,包括PFFiles。你可以说:

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

答案 1 :(得分:1)

我不是100%你的意思,因为你没有发布任何代码,但我想如果你想将多个PFFile关联到PFObject,这就是你要做的全部:

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

Parse's documentation看来,saveEventually似乎符合您的要求:

  

在此处未指定的时间将此对象保存到服务器   未来,即使Parse目前无法访问。尽可能使用它   没有扎实的网络连接,也不需要知道什么时候了   保存完成。如果对象存在某些问题   无法保存,它会被默默地丢弃。如果保存完成   当对象仍然在内存中时成功,然后回调将   被称为。

答案 2 :(得分:1)

由于目前既不保存也不保存到本地数据存储,下面是一个PFObject类,我用来至少保存离线可以保存或返回错误:

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

}