iOS 7中使用iCloud通知的Core Data

6
我已经为我的应用程序添加了iCloud支持。当用户更新他的数据时,我会收到通知 NSPersistentStoreDidImportUbiquitousContentChangesNotification
这很好。
然而,我遇到了以下问题:
  1. 我找不到一个 will 版本的通知,可以用来显示加载器,例如数据库将要被更新。
  2. 由于我找不到 will 版本,所以我使用相同的通知来显示一个加载器,告诉用户数据库正在更新... 这个通知的问题在于,如果iCloud中的内容相对较大,则它可能会被多次调用,从而导致我显示多个加载指示器!
  3. 有没有一种方法可以手动通过iCloud触发更新?

.


我通过以下方式向Core Data添加了iCloud支持:

在NSManagedObjectContext中

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;

在 NSPersistentStoreCoordinator 中

[_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{NSPersistentStoreUbiquitousContentNameKey:@"iCloudStore"} error:nil];

在 NSPersistentStoreDidImportUbiquitousContentChangesNotification 通知方法中

(涉及 IT 技术相关内容)
- (void)persistentStoreDidImportUbiquitousContentChanges:(NSNotification *)notification
{
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    [managedObjectContext performBlock:^{
        [managedObjectContext mergeChangesFromContextDidSaveNotification:notification];

        dispatch_async(dispatch_get_main_queue(), ^{
            UIWindow *mainWindow = [[[UIApplication sharedApplication] delegate] window];
            MBProgressHUD *hud = [MBProgressHUD HUDForView:mainWindow];
            if (hud == nil) {
                hud = [[MBProgressHUD alloc] initWithWindow:mainWindow];
            }
            [mainWindow addSubview:hud];
            hud.labelText = NSLocalizedString(@"Progress updated", nil);
            [hud show:YES];
            [hud hide:YES afterDelay:1];

            // Post Notification
            [[NSNotificationCenter defaultCenter] postNotificationName:RESET_APPLICATION_NOTIFICATION object:nil];
        });
    }];
}
1个回答

5
我找不到一种合适的通知版本,可以用来展示加载器,告诉用户数据库正在更新。是的,确实没有这样的版本。当新变更出现时,iCloud 守护程序会先保存它们,然后才告诉您它所做的事情。
既然我找不到一个合适的版本,那么我就使用同一个通知来显示一个加载器,告诉用户数据库正在被更新。但是这个通知存在一个问题,如果iCloud中的内容相对较大,则该通知可能会被多次调用,导致我必须显示几个加载指示器!
没错!我也遇到过这个问题。这些通知可能非常频繁,因此您不希望每次收到通知时都通知用户。我做的是安排将通知延迟至iCloud平静了至少1秒钟。您可以使用NSTimer来实现这一点。首先将其声明为属性:
@property (readwrite, retain) NSTimer *iCloudUpdateTimer;

当您收到“did import”通知时,请执行以下操作:
if (self.iCloudUpdateTimer == nil) {
    self.iCloudUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:1.0
        target:self
        selector:@selector(notifyUser:)
        userInfo:nil
        repeats:NO];
} else {
    [self.iCloudUpdateTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:1.0];
}

// Now actually handle the notification....

功能:如果计时器不存在,则创建计时器。如果存在,则将触发时间延迟一秒钟。当iCloud发送大量通知时,计时器会不断地被推迟到未来。最终,计时器将在iCloud平静下来后的一秒钟内触发。

然后,当计时器触发时,执行以下操作:

- (void)notifyUser:(NSNotification *)notification
{
    [self.iCloudUpdateTimer invalidate];
    self.iCloudUpdateTimer = nil;

    // Then notify the user
}

您可能需要使用dispatch_async来确保所有计时器访问都在同一队列上进行。
(顺便说一下,即使有“将导入”通知,它也可能与当前的“已导入”通知一样频繁地发布,所以它对您帮助不大。)
“有没有一种方法可以手动通过iCloud触发更新?”
不,您绝对无法控制它。

谢谢!...这是我想到的第一个场景。但是我一直梦想着找到另一个官方场景...谢谢 :) - Hani Ibrahim
使用这种方法,您可以在“本地”存储中添加更改时通知用户。我说得对吗?因此,没有办法通知用户他们的数据将要被更新。在我的看法中,从用户角度来看这非常奇怪。 - MatterGoal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接