如何使用 CKModifyRecordsOperation.perRecordProgressBlock 更新进度

Posted

技术标签:

【中文标题】如何使用 CKModifyRecordsOperation.perRecordProgressBlock 更新进度【英文标题】:How to update progress with CKModifyRecordsOperation.perRecordProgressBlock 【发布时间】:2015-04-06 14:31:41 【问题描述】:

这与最近的一个线程Update progress with MRProgress 有关。由于之前的线程(感谢 Edwin!),我将我的 cloudkit 查询从便捷 API 转换为 CKOOperations。因此,在使用 CKModifyRecordsOperation 保存记录时,我可以通过登录 perRecordProgressBlock 来查看记录的进度,非常棒。但是,我正在尝试将此进度发送回视图控制器,但我无法弄清楚如何做到这一点。我为我的所有 CloudKit 方法创建了一个类 - CKManager。我遇到的另一个问题是我不确定何时更新 VC 中的进度指示器(使用 MRProgress 框架)。我是在 CKManager 中的保存操作调用之前、期间还是之后调用它?是否应该递归调用直到进度== 1.0?这是我到目前为止的代码......除了更新/动画进度指示器(它出现并显示 0%,然后在保存操作完成后消失)之外,一切都很好。另外,我在我的 CKManager 类中使用了一个属性(双进度),我知道这是不正确的,但我不知道该怎么做。而且我认为我在下面的 CKManager 类中为此声明/定义的回调方法也不正确。任何指导表示赞赏!

CKManager.h

@property (nonatomic, readonly) double progress;
- (void)recordProgressWithCompletionHandler:(void (^)(double progress))completionHandler;

CKManager.m

    @property (nonatomic, readwrite) double progress;
    - (void)recordProgressWithCompletionHandler:(void (^)(double))completionHandler 

    completionHandler(self.progress);


- (void)saveRecord:(NSArray *)records withCompletionHandler:(void (^)(NSArray *, NSError *))completionHandler 

    NSLog(@"INFO: Entered saveRecord...");
    CKModifyRecordsOperation *saveOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:records recordIDsToDelete:nil];

    saveOperation.perRecordProgressBlock = ^(CKRecord *record, double progress) 
        if (progress <= 1) 
            NSLog(@"Save progress is: %f", progress);
            self.progress = progress;
        
    ;

    saveOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError *error) 
        NSLog(@"Save operation completed!");
        completionHandler(@[record], error);
    ;

    [self.publicDatabase addOperation:saveOperation];

Viewcontroller.m - 这是从相机获取照片并调用 CKManager 类以准备记录并将其保存到 CK 以及显示 MRProgress 指示器的方法...

if (self.imageDataAddedFromCamera) 
            self.hud = [MRProgressOverlayView showOverlayAddedTo:self.myCollectionView animated:YES];
            self.hud.mode = MRProgressOverlayViewModeDeterminateCircular;
            self.hud.titleLabelText = UPLOADING_MSG;
            // prepare the CKRecord and save it
            [self.ckManager saveRecord:@[[self.ckManager createCKRecordForImage:self.imageDataAddedFromCamera]] withCompletionHandler:^(NSArray *records, NSError *error) 
                if (!error && records) 
                    NSLog(@"INFO: Size of records array returned: %lu", (unsigned long)[records count]);
                    CKRecord *record = [records lastObject];
                    self.imageDataAddedFromCamera.recordID = record.recordID.recordName;
                    NSLog(@"INFO: Record saved successfully for recordID: %@", self.imageDataAddedFromCamera.recordID);
                    [self.hud dismiss:YES];
                    [self.hud removeFromSuperview];
                    [self.imageLoadManager addCIDForNewUserImage:self.imageDataAddedFromCamera]; // update the model with the new image
                    // update number of items since array set has increased from new photo taken
                    self.numberOfItemsInSection = [self.imageLoadManager.imageDataArray count];
                    [self updateUI];
                 else 
                    NSLog(@"Error trying to save the record!");
                    NSLog(@"ERROR: Error saving record to cloud...%@", error.localizedDescription);
                    [self.hud dismiss:YES];
                    [self.hud removeFromSuperview];
                    [self alertWithTitle:YIKES_TITLE andMessage:ERROR_SAVING_PHOTO_MSG];
                
            ];
            // where does this call belong?
            [self.ckManager recordProgressWithCompletionHandler:^(double progress) 
                dispatch_async(dispatch_get_main_queue(), ^
                    NSLog(@"Updating hud display...");
                    [self.hud setProgress:progress animated:YES];
                );
            ];

【问题讨论】:

【参考方案1】:

您应该在 saveRecord 调用中包含进度处理程序,如下所示:

- (void)saveRecord:(NSArray *)records withCompletionHandler:(void (^)(NSArray *, NSError *))completionHandler recordProgressHandler:(void (^)(double))progressHandler 

    NSLog(@"INFO: Entered saveRecord...");
    CKModifyRecordsOperation *saveOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:records recordIDsToDelete:nil];

    saveOperation.perRecordProgressBlock = ^(CKRecord *record, double progress) 
        if (progress <= 1) 
            NSLog(@"Save progress is: %f", progress);
            progressHandler(progress)
        
    ;

    saveOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError *error) 
        NSLog(@"Save operation completed!");
        completionHandler(@[record], error);
    ;

    [self.publicDatabase addOperation:saveOperation];

然后你可以像这样调用那个保存记录:

        [self.ckManager saveRecord:@[[self.ckManager createCKRecordForImage:self.imageDataAddedFromCamera]] withCompletionHandler:^(NSArray *records, NSError *error) 
            if (!error && records) 
                NSLog(@"INFO: Size of records array returned: %lu", (unsigned long)[records count]);
                CKRecord *record = [records lastObject];
                self.imageDataAddedFromCamera.recordID = record.recordID.recordName;
                NSLog(@"INFO: Record saved successfully for recordID: %@", self.imageDataAddedFromCamera.recordID);
                [self.hud dismiss:YES];
                [self.hud removeFromSuperview];
                [self.imageLoadManager addCIDForNewUserImage:self.imageDataAddedFromCamera]; // update the model with the new image
                // update number of items since array set has increased from new photo taken
                self.numberOfItemsInSection = [self.imageLoadManager.imageDataArray count];
                [self updateUI];
             else 
                NSLog(@"Error trying to save the record!");
                NSLog(@"ERROR: Error saving record to cloud...%@", error.localizedDescription);
                [self.hud dismiss:YES];
                [self.hud removeFromSuperview];
                [self alertWithTitle:YIKES_TITLE andMessage:ERROR_SAVING_PHOTO_MSG];
            
        , recordProgressHandler:^(double progress) 
            dispatch_async(dispatch_get_main_queue(), ^
                NSLog(@"Updating hud display...");
                [self.hud setProgress:progress animated:YES];
            );
        ];

因此,更新进度的代码是您的 saveRecord 调用的一部分。 上面的代码未经我测试。所以我希望我没有错字

【讨论】:

谢谢!我回家后会试一试,然后告诉你效果如何。 Edwin - 效果很好!你的 saveRecord 调用中有一个逗号,但我删除了它的工作。非常感谢!

以上是关于如何使用 CKModifyRecordsOperation.perRecordProgressBlock 更新进度的主要内容,如果未能解决你的问题,请参考以下文章

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等

如何使用 Math.Net 连接矩阵。如何使用 Math.Net 调用特定的行或列?

WSARecv 如何使用 lpOverlapped?如何手动发出事件信号?