简体   繁体   English

iOS 7中使用iCloud通知的核心数据

[英]Core Data with iCloud Notifications in iOS 7

I have added iCloud support to my app. 我已经为我的应用添加了iCloud支持。 when the user update his data I got a notification NSPersistentStoreDidImportUbiquitousContentChangesNotification 当用户更新他的数据时,我收到了通知NSPersistentStoreDidImportUbiquitousContentChangesNotification

That's great 那很棒

However, I have these problems 但是,我有这些问题

  1. I can't find a will version of this notification that I can use to show loader for example that the database will be updated 我找不到这个通知的will版本,我可以用它来显示加载器,例如数据库将被更新
  2. Since I can't find a will version, then I used the same notification to display a loader to tell the user that the database is being updated ... The problem in this notification is that it can be called several time if the content changed in iCloud is relatively large which lead me to display several loading indicator ! 由于我找不到will版本,所以我使用相同的通知显示加载器告诉用户数据库正在更新...此通知中的问题是,如果内容发生更改,可以多次调用它在iCloud中比较大,这导致我显示几个加载指示器!
  3. Is there a way that I can use to trigger the update through iCloud manually? 有没有办法可以手动触发iCloud更新?

.


I added iCloud support to Core data by doing this: 我通过这样做添加了对Core数据的iCloud支持:

in NSManagedObjectContext 在NSManagedObjectContext中

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

in NSPersistentStoreCoordinator 在NSPersistentStoreCoordinator中

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

and In NSPersistentStoreDidImportUbiquitousContentChangesNotification notification method 并在NSPersistentStoreDidImportUbiquitousContentChangesNotification通知方法中

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

I can't find a will version of this notification that I can use to show loader for example that the database will be updated 我找不到这个通知的遗嘱版本,我可以用它来显示加载器,例如数据库将被更新

Yeah, that's because there isn't one. 是的,那是因为没有一个。 When new changes come in, the iCloud daemon saves them and then tells you what it has done. 当新的更改进入时,iCloud守护程序会保存它们, 然后告诉您它做了什么。

Since I can't find a will version, then I used the same notification to display a loader to tell the user that the database is being updated ... The problem in this notification is that it can be called several time if the content changed in iCloud is relatively large which lead me to display several loading indicator ! 由于我找不到遗嘱版本,所以我使用相同的通知显示加载器告诉用户数据库正在更新...此通知中的问题是,如果内容发生更改,可以多次调用它在iCloud中比较大,这导致我显示几个加载指示器!

Yes! 是! I had this same issue. 我有同样的问题。 These notifications can be very frequent, so you don't want to notify the user every time one comes in. What I did was arrange to delay the notification until iCloud had quieted down for at least 1 second. 这些通知可能非常频繁,因此您不希望每次进入时都通知用户。我所做的是安排延迟通知,直到iCloud安静至少1秒钟。 You can do this using an NSTimer . 您可以使用NSTimer执行此操作。 First declare it as a property: 首先将其声明为属性:

@property (readwrite, retain) NSTimer *iCloudUpdateTimer;

Then when you get the "did import" notification, do something like this: 然后,当您收到“导入”通知时,请执行以下操作:

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....

What this does: Creates the timer if it doesn't exist. 这样做:如果计时器不存在,则创建它。 If it does exist, it delays the fire date for one second. 如果确实存在,则会将开火日期延迟一秒钟。 When iCloud sends a lot of notifications, the timer keeps getting pushed out into the future. 当iCloud发送大量通知时,计时器将继续被推出。 The timer will finally fire one second after iCloud calms down. 在iCloud平静下来后,计时器将最终点火一秒钟。

Then when the timer fires, do something like: 然后当计时器触发时,执行以下操作:

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

    // Then notify the user
}

You may need to use dispatch_async to make sure that all timer access happens on the same queue. 您可能需要使用dispatch_async来确保所有计时器访问都发生在同一队列中。

(As an aside, even if there were a "will import" notification, it would probably be posted just as often as the current "did import" notification, so it wouldn't help you very much.) (顺便说一句,即使有“将导入”通知,它可能会像当前的“导入”通知一样频繁发布,所以它对你没有多大帮助。)

Is there a way that I can use to trigger the update through iCloud manually? 有没有办法可以手动触发iCloud更新?

No, you have absolutely no control over that. 不,你绝对无法控制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM