Cancel Local Notification by passing notification id(of type UserData)

Brent,

  The short answer is that we’re given a userdata type which doesn’t seem like it wants to persist to a text format when we try.  We can keep a table that will be cleared up when the app closes, but then we have no data related to its id when the app is started.

Any scheduling app will have multiple notifications and needs the ability to cancel and recreate specific ones.  If a user makes a notification and then later decides to change the time at which it fires having the ID would be very helpful as it could be tied to that specific event, and only cancel that single notification, to recreate the new one, or cancel ONE specific notification we no longer want to send to the user.

But if we have say hundreds or more events, it means that we now have to persist all data associated with those events, use the cancel to destroy them all, and then iterate over our local copies of them and recreate all the ones we really wanted to keep.

For the time being I’ve written my own lib to encapsulate all this management and logic, but would prefer that corona provide a more easily used type that can easily be persisted in string based storage.

Thanks for responding,

Chris

I am also having this identical problem.  i have an app of mine that needs to schedule a bunch of alerts but some actions could cause 1 or 2 of the alerts to change times…  

but they have already been scheduled.    

now according to the Corona Docs on this page:  http://docs.coronalabs.com/api/library/system/scheduleNotification.html

is says " Returns a reference id that can be used to cancel the notification."  however using Corona Labs own example on the same page.  

notificationId = system.scheduleNotification( utcTime, options )

which is find but if you add a simple print statement after it you will get an error

notificationId = system.scheduleNotification( utcTime, options ) print("notificationId is: ",notificationId )

this print statement says it cant print a NIL.    but if you watch your logs in xCode, its actually a userdata object.

If i can’t print the value and i cant store the value in the database that it returns…  THEN how can this statement be true?

" Returns a reference id that can be used to cancel the notification."  _ ~Corona _

Have you considered base64 encoding the userdata and saving that?  When you base64 decode it, you should end up with the object again.

There is a base64 encode/decode pair in the “mime” library or tons of b64enc type functions as lua string recipes that you could google

I can try that but in order to encode it do i not need the variable :  notificationId to be something other then Nil? right now all that i get back from corona says that variable is a NIL. so how can i manipulate it at all?

Ok i have tried to base64 encode the results and still get an error.

 Jul 15 09:57:08 Learning-Gems-iPad3 1306-MyEvents[5114] <Warning>: Runtime error

    bad argument #1 to ‘b64’ (string expected, got userdata)

    stack traceback:

Any additional help from Corona would be appreciated here.  again, according to your documentation we should be getting a return from the system.scheduleNotification API that we can store and be able to use it later to cancel the notification we are creating.  

The Lua userdata that is returned by the system.schedueNotification() API is a C/C++ pointer (ie: a memory address).  You should *never* save it.  The reason is because when you restart your app, that memory address will become invalid (aka: a wild pointer) and will cause a crash if you attempt to use it.  The reason Corona returns it as userdata/memory-address is because iOS does not actually provide an ID for local/scheduled notifications.  So, there is nothing you can use to save to file other than what you’ve put into its custom data property.  Unfortunately, Corona does not provide any means to fetch scheduled notifications on iOS.

Are you saying that if I create a local notification, say to encourage someone to revisit my App a week after installing it, the notification will appear attached to my App icon in the iOS without me having any ability to clear it? This appears to be happening right now and I need to know how to clear a previously set iOS notification, just like any other App.

if you “applicationExit” your app and then restart it, then yes, you’ll have no means of removing your previously scheduled local notifications.  All of your previous notification userdata IDs will become invalid.  We unfortunately do not have a Lua API to re-fetch new IDs for your previous scheduled local notifications, which is needed for iOS.  It’s admittedly a hole in our API design for local/scheduled notifications (push/remote notifications are okay).

I’m also pretty sure (but not 100% positive; more like 95%) that those notification userdata IDs are safe to use on Android since they’re not really pointers on that platform, but that’s an implementation specific detail on that platform that we could change in the future.  The typical rule in Lua is that “userdata” objects are really C/C++ pointers (aka: memory address) and they’re only safe to use for that 1 application instance.  They should never be saved/restored to/from file.

Any word on when this ‘hole’ will be plugged? Otherwise, using Local Notifications on iOS will do nothing but leave a number on your app forever. Seems like a hole too big to ignore.

You are in control if badges (the numbers in red circles) show up when your notification goes off. You don’t have to create a badge. You can also clear badges upon app start or resume. Many apps clear their badges this way.

See: https://docs.coronalabs.com/api/library/native/setProperty.html

Rob

With cancelling a specific notification, I save the notification ID and with cancelling I just pull it with to use with cancelNotification(). It works and I get no errors or crashes. I dont know if this it the right or good way to do it tho. It seems it only works on Android. On iOS I’m getting a nil value on cancelNotification.

On iOS, you get a “Userdata” object. This is a block of ‘C’ pointer memory. It’s only valid for that session. If the app gets flushed from memory, the Userdata is invalid. There is no way to cancel a local notification from iOS after the app closes and re-opens.

Rob

Are you saying that if I create a local notification, say to encourage someone to revisit my App a week after installing it, the notification will appear attached to my App icon in the iOS without me having any ability to clear it? This appears to be happening right now and I need to know how to clear a previously set iOS notification, just like any other App.

if you “applicationExit” your app and then restart it, then yes, you’ll have no means of removing your previously scheduled local notifications.  All of your previous notification userdata IDs will become invalid.  We unfortunately do not have a Lua API to re-fetch new IDs for your previous scheduled local notifications, which is needed for iOS.  It’s admittedly a hole in our API design for local/scheduled notifications (push/remote notifications are okay).

I’m also pretty sure (but not 100% positive; more like 95%) that those notification userdata IDs are safe to use on Android since they’re not really pointers on that platform, but that’s an implementation specific detail on that platform that we could change in the future.  The typical rule in Lua is that “userdata” objects are really C/C++ pointers (aka: memory address) and they’re only safe to use for that 1 application instance.  They should never be saved/restored to/from file.

Any word on when this ‘hole’ will be plugged? Otherwise, using Local Notifications on iOS will do nothing but leave a number on your app forever. Seems like a hole too big to ignore.

You are in control if badges (the numbers in red circles) show up when your notification goes off. You don’t have to create a badge. You can also clear badges upon app start or resume. Many apps clear their badges this way.

See: https://docs.coronalabs.com/api/library/native/setProperty.html

Rob

With cancelling a specific notification, I save the notification ID and with cancelling I just pull it with to use with cancelNotification(). It works and I get no errors or crashes. I dont know if this it the right or good way to do it tho. It seems it only works on Android. On iOS I’m getting a nil value on cancelNotification.

On iOS, you get a “Userdata” object. This is a block of ‘C’ pointer memory. It’s only valid for that session. If the app gets flushed from memory, the Userdata is invalid. There is no way to cancel a local notification from iOS after the app closes and re-opens.

Rob