views:

51

answers:

1

Hi there,

I have a transformable attribute on one of my entities, called reminder. It's a UILocalNotification.

Now, since I want to schedule it when it's added, and cancel it when removed, I would like to override the accessors to handle the scheduling and cancelling in there.

How would that look?

Thanks!

+1  A: 

Are you actually persisting the UILocalNotification or are you using it as a transient property?

I wouldn't store it, rather UILocalNotification as a userInfo as a property. You can at a key/value pair to that dictionary with information about the owning entity. For instance:

You create a value for the key notificationID in the userInfo dictionary and set a attribute notificationID on your Core Data entity to the same value. That way, you just have to store an int or NSString in your store (which is preferable to transformable).

When you want to fetch your UILocalNotification again you can make an accessor on your Entity Class, something like:

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

Of course you can make an accessor for your notification in much the same way if you actually need access to the notification object.

Hope it helps.

UPDATE

So since you have a property you call reminder on you Entity (I'm guessing that it is a BOOL) it will look something like this:

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

In fact you don't really have to store the "reminder" attribute at all, you can just check if the notificationID attribute is nil or not. That was the idea from my suggestion before.

I haven't checked the code above but I do something similar in two of my projects.

Remember you can get into trouble if you create more than 64 local notifications, since you are only allowed to make that many per app. So you might want to track how many you have before creating any new ones.

Thomas Børlum
Thanks Thomas. Though I like your method, you didn't really answer my question. The accessors are also missing the KVO stuff that Core Data uses.
Christoph
Ah, but I think it actually does answer you question. The KVO stuff is implicitly handled by the line `self.notificationID = @"some ID". I've updated my answer to reflect what you need to do as I understand your question. And if it doesn't help you +1 one for effort would be appreciated :).
Thomas Børlum
Well, actually it's not a BOOL but the UILocalNotification. :)
Christoph
Yes, ok but you would encapsulate the notification which there would be no reason to expose to the rest of your application. But I would really stay away from transformables, unless you really need to, which is not the case here. Good luck.
Thomas Børlum