用于可转换UILocalNotification的自定义核心数据访问器

时间:2010-10-17 04:50:12

标签: iphone objective-c core-data

我的一个实体上有一个可转换的属性,称为提醒。这是一个UILocalNotification。

现在,由于我想在添加时安排它,并在删除时取消它,我想覆盖访问器来处理调度和取消。

看起来怎么样?

谢谢!

2 个答案:

答案 0 :(得分:9)

您实际上是在持久化UILocalNotification,还是将其用作瞬态属性?

我不会将其存储为UILocalNotification作为userInfo作为属性。您可以在该字典的键/值对中包含有关拥有实体的信息。例如:

您可以在notificationID字典中为密钥userInfo创建一个值,并将Core Data实体上的属性notificationID设置为相同的值。这样,您只需在商店中存储intNSString(最好是可转换的)。

如果您想再次获取UILocalNotification,可以在您的实体类上创建一个访问者,例如:

- (void)createNotification
{
    static NSUInteger kDeadlineWarningPeriod = 3600;
    UILocalNotification *notification = [[UILocalNotification alloc] init];

    …

    self.notificationID = @"some generated ID";

    [notification.userInfo setValue:self.notificationID forKey:@"notificationID"];

    [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    [notification release];
}

- (void)cancelNotification
{
    // We search for the notification.
    // The entity's ID will be stored in the notification's user info.

    [[[UIApplication sharedApplication] scheduledLocalNotifications] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

    UILocalNotification *notification = (UILocalNotification *)obj;
    NSDictionary *userInfo = notification.userInfo;

    NSString *notificationID = [userInfo valueForKey:@"notificationID"];

    if ([notificationID isEqualToString:self.notificationID])
    {
        [[UIApplication sharedApplication] cancelLocalNotification:notification];
        *stop = YES;
                    self.notificationID = nil;
    }
     }];
}

当然,如果您确实需要访问通知对象,则可以以相同的方式为您的通知创建一个访问者。

希望它有所帮助。

<强>更新

所以,既然你有一个属性,你就提醒你实体(我猜这是一个BOOL)它会看起来像这样:

// .h

@property (nonatomic, assign) BOOL reminder;

// .m

- (void)setReminder:(BOOL)reminder {

   [self willAccessValueForKey@"reminder"];
   BOOL hasReminder = [[self primitiveValueForKey:@"reminder"] booleanValue];
   [self didAccessValueForKey:@"reminder"];

   if (hasReminder && !reminder) {

        [self cancelNotification];
   }
   else if (!hasReminder && reminder) {

        [self createNotification];
   }

   if (reminder != hasReminder)
   {
        [self willChangeValueForKey:@"reminder"];
        [self setPrimitiveValue:[NSNumber numberWithBool:reminder] forKey@"reminder"];
        [self didChangeValueForKey:@"reminder"];
   }
}

实际上你根本不需要存储“提醒”属性,你可以检查notificationID属性是否为零。这是我之前建议的想法。

我没有检查上面的代码,但我在两个项目中做了类似的事情。

请记住,如果您创建超过64个本地通知,则可能会遇到麻烦,因为您只能为每个应用创建多个通知。所以你可能想要在创建任何新的之前跟踪你有多少。

答案 1 :(得分:0)

如果每个对象只有一个通知,那么您可以避免存储notificationID,只需在Persistent存储中使用NSManagedObject的objectId。

您可以使用以下代码行序列化和反序列化objectId:

[[self.objectID URIRepresentation] absoluteString] 

[[self persistentStoreCoordinator] managedObjectIDForURIRepresentation:[NSURL URLWithString:[localNotif.userInfo objectForKey: kYourReminderNotificationKey]

这里是编辑的代码:

- (void)createNotification
{        

    Class cls = NSClassFromString(@"UILocalNotification");
    if (cls != nil) {

        UILocalNotification *notif = [[cls alloc] init];
        notif.fireDate = self.dateDue;
        notif.timeZone = [NSTimeZone defaultTimeZone];


       notif.alertBody = @"Alert body";        

        notif.alertAction = @"Show me";
        notif.soundName = UILocalNotificationDefaultSoundName;


        NSDictionary *userDict = [NSDictionary dictionaryWithObject:[[self.objectID URIRepresentation] absoluteString] forKey:kRemindMeNotificationDataKey];


        notif.userInfo = userDict;

        [[UIApplication sharedApplication] scheduleLocalNotification:notif];

    }


}

- (void)cancelNotification
{

    [[[UIApplication sharedApplication] scheduledLocalNotifications] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        UILocalNotification *notification = (UILocalNotification *)obj;
        NSDictionary *userInfo = notification.userInfo;

        NSString *notificationID = [userInfo valueForKey:kRemindMeNotificationDataKey];

        if ([notificationID isEqualToString:[[self.objectID URIRepresentation] absoluteString]])
        {
            [[UIApplication sharedApplication] cancelLocalNotification:notification];
            *stop = YES;
        }
    }];
}