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.