Pergunta

I am writing an iPhone app in which I have three countdown timers, that each set a local notification when they are started by the user (IBAction).

My question is, how can I reference to an existing local notification elsewhere in the code? I have tried referencing it directly like this which crashes:

[[UIApplication sharedApplication] cancelLocalNotification:myNotification];

And like this after scheduling the notification and adding it to the user defaults:

In my scheduling method...
[myDefaults setObject:myNotification forKey:@"myNotification"];
...

And in my cancelling method...
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
[[UIApplication sharedApplication] cancelLocalNotification:[myDefaults objectForKey:@"myNotification"]];
[myDefaults synchronize];

My app crashes with a SIGABRT error on the cancelLocalNotification line above. Can anybody tell me where I am going wrong?

Thanks in advance!

Foi útil?

Solução

Ok, I've found a working solution to my issue after thinking it through step by step. I found I was going about the whole issue entirely the wrong way!

Essentially, I found you don't need any local notifications when the app is active (i.e. in foreground). So instead of setting the local notification when the timer is started, I set the relevant notifications up when the app is about to resign.

I put these observers in my viewDidLoad;

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appWillResign) name:UIApplicationWillResignActiveNotification 
object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(appIsActive) name:UIApplicationDidBecomeActiveNotification 
object:nil];

and in my appWillResign method, I set up the notifications for any active timers. When the app is resumed, I simply cancel ALL the notifications.

[[UIApplication sharedApplication] cancelAllLocalNotifications];

In short, you shouldn't need to reference the notifications elsewhere in the code. You only set them up when they are absolutely needed: when the app is backgrounded! So you really don't need to 'store' them anywhere for later use.

Thanks for your contribution @Learner, you helped put me on the right track! :D

Outras dicas

It is difficult to predict but generally SIGABRT comes when you access an nil or released object.

So in [[UIApplication sharedApplication] cancelLocalNotification:myNotification]; `

it can be "myNotification" which is nil.

OR if [myDefaults objectForKey:@"myNotification"] returns nil.

Possible resason for that can be that NsUserDefaults stores only few data type as mentioned in following paragraph of class reference.

A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. If you want to store any other type of object, you should typically archive it to create an instance of NSData.

What i can predict is that myNotification which is being stored is of type UILocalNotification. so probably storing of data is failing.

Please debug the code further and post if above cases are not working.

The fix is to sync the NSUserDefaults. I'm assuming you just set the object and did not synchronize it. If so the object will not actually save to NSUserDefaults, rather just to the local NSUserDefaults object. What you need to do is call [defaults synchronize] after setting the object.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top