In my PhoneGap 1.3 offline app I'm using modified iOS local notification plugin found in official plugin GitHub page.
I need to schedule a repeating notification (weekly/monthly), or multiple single notifications fired on every 2 weeks, based on user defined setting.
The problem occurs when I'm trying to schedule those 26 notifications to be fired on every 2 weeks.
Currently I'm using this to achieve that:
for (int i = 1; i < 26; i++)
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil) {
return;
}
NSDate *date = [[NSDate date] dateByAddingTimeInterval: i * 60 * 60 * 24 * 7 * 2];
localNotif.fireDate = date;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = [NSString stringWithFormat:#"%i: %#", i, msg];
localNotif.hasAction = NO;
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 0;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}
When running this on iPhone 3G or iPod Touch 2 the UI freezes for about 3 - 5 seconds which is a big no no. Is there a way to optimize scheduling notifications?
I know that using only weekly and monthly repeating notifications would solve the problem but the client wants every 2 weeks, every 2 months, and every 3 months notifications, so I need to schedule multiple notifications.
I have tried to run the loop in new thread using [NSThread detachNewThreadSelector:...] which raises new problems (crashes every now and then).
Are iPhones released after 3G that much faster that delay/froze won't exist? I only have those 2 ancient devices to test with.
I would suggest either performing the creation in a background thread using this: (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
Or I would try to rethink the process. Perhaps instead of creating a years worth of 2 week reminders at once just create a couple and set something else up to create the rest. Or maybe even just create one and store a repeating bool with it so when it fires it also creates the next one.
Related
I'm issuing a local notification alert (iOS 5) that will repeat its reminder periodically (every minute) until the user acknowledges it by setting repeatInterval on the UILocalNotification instance added to [[UIApplication sharedApplication] scheduleLocalNotification:
The effect of setting 'repeatInterval' is that each time the notification is repeated while not acknowledging it, there's another entry in the Notification Center. e.g: After 5 minutes of not ack'ing the firing, there are 5 separate entries in the Notification Center.
Is there way to only have one entry, but sound/vibrate alert every 1 minute?
Here's how I'm creating the local notification:
UILocalNotification *localNotify = [[UILocalNotification alloc] init];
localNotify.fireDate = aFireDate;
localNotify.timeZone = [NSTimeZone defaultTimeZone];
localNotify.userInfo = userInfo;
// 3. Configure the substance of the notification: alert, icon badge number, and sound.
localNotify.alertBody = NSLocalizedString(alertTitleText, nil);
localNotify.alertAction = NSLocalizedString(alertActionText, nil);
localNotify.soundName = UILocalNotificationDefaultSoundName;
localNotify.applicationIconBadgeNumber = 1;
localNotify.repeatInterval = NSMinuteCalendarUnit;
// Schedule the local notification for delivery.
[[UIApplication sharedApplication] scheduleLocalNotification:localNotify];
Unfortunately no. As long as the user has Notification Center turned on for your app, every local notification you fire will show up as a distinct entry in Notification Center; even if they are multiple firings of the same UILocalNotification object. The UILocalNotification API gives you no control over this.
What happens when a UILocalNotofication is scheduled when a device is switched off.
Eg. I schedule a UILocalNotification at 3pm everyday. But the device is switched off from 3:00pm to 4:00pm. I guess any one of the following conditions will be true.
No notification is fired after device is restarted.
Notification is fired when the device is restarted i.e. at 4:00pm
I do not have a device and could not test it on a simulator.
Note: By switch off I mean that the device is turned off, and not sleep/stand by mode
Local Notifications will be triggered after turning your device off and on.
I wrote a tiny test app, that verifies this behaviour:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSDate *nowDate = NSDate.date;
for (int i = 1; i <= 50; i++) {
UILocalNotification *n = [[UILocalNotification alloc]init];
n.fireDate = [nowDate dateByAddingTimeInterval:60 * i ];
n.applicationIconBadgeNumber = 0;
n.alertAction = #"Open";
n.alertBody = [NSString stringWithFormat:#"ln %# %#", #(i), n.fireDate];
[[UIApplication sharedApplication] scheduleLocalNotification:n];
}
return YES;
}
When you turn off your device, the notification becomes non-existant, so when you turn your device back on, nothing is going to happen without creating that notification again.
So if you schedule an event for 3PM and your device is turned off at 2:59PM, then back on at 3:59PM, the notification will not fire because it has to be recreated.
I work for local notification and all I have built fully functional
And follows that when launches my notification
Message shows the 2 buttons
If the press on "viwe" button => it's the launches application
And if the press on "close" button of the second, he's working close
I want to, "if the user does not first and not the second
Any after 30 seconds "
=> (after 30 seconds - After the end of a voice alert "29.mp3") but I did not press if the user does not first and not the second
Any after 30 seconds
That shows a specific sound (after 30 seconds), how can I do this
and what deligate method do that functionality
-(IBAction) scheduleNotification1 {
local1 = [[UILocalNotification alloc] init];
// create date/time information
local1.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
local1.timeZone = [NSTimeZone defaultTimeZone];
// set notification details
local1.alertBody = #"2!";
local1.alertAction = #"View";
//local1.soundName = UILocalNotificationDefaultSoundName;
//local1.soundName = #"alarmsound.caf";
local1.soundName = #"29.mp3";
// set the badge on the app icon
local1.applicationIconBadgeNumber = 1;
// local1.repeatInterval =NSSecondCalendarUnit;//// NSMinuteCalendarUnit;
//local1.repeatInterval =1 ;
// Gather any custom data you need to save with the notification
NSDictionary *customInfo = [NSDictionary dictionaryWithObject:#"ABCD2" forKey:#"yourKey1"];
local1.userInfo = customInfo;
// Schedule it!
[[UIApplication sharedApplication] scheduleLocalNotification:local1];
//[local1 release];
}
I think you will have to schedule a second notification 30 seconds after the first one, and cancel it if the user presses the view button. You can't have a timer built in to the system notification alert.
I am building an application where i show the bus stops on the map and the user current location as well.I want to implement the notification that when the user is say x meters from one bus stop ,there should be a notification like alert,sound .So that he can prepare for his stop.There may be many stops on the map and i want to do it for everystop.
Please help me how to implement that.Whether it would be LocalNotification,Then how to use this in this way..........
Thanks in advance
Do all your distance calculations in didUpdateToLocation.
You can send local notifications in iOS 4, using UILocalNotification class.
Here is some sample code:
UILocalNotification *noti = [[UILocalNotification alloc] init];
noti.fireDate = someDate;
noti.alertBody = someText;
noti.alertAction = nil;
noti.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:noti];
[noti release];
Make sure the date is as close as possible as [NSDate date], so it will appear right away.
I'm trying to clear my app's "unread" badge with a UILocalNotification. Logically you would think this would be done by setting applicationIconBadgeNumber of a UILocalNotification instance to 0. But it doesn't work, and the docs for applicationIconBadgeNumber say "The default value is 0, which means "no change.”"
So is there really no way to clear a badge with local notifications once it's been set?
Update: Some simple code:
-(void)applicationDidFinishLaunching
{
// Set the appication icon badge to 1 in 10 minutes, using a local notification so it works in the background:
// This works fine.
UILocalNotification *episodeNotification = [[UILocalNotification alloc] init];
episodeNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:(60 * 10)];
episodeNotification.timeZone = [NSTimeZone defaultTimeZone];
episodeNotification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:episodeNotification];
[episodeNotification release];
// Clear the application icon badge in 20 minutes, again using a local notifcation so it works in the background:
// This doesn't work. According to the docs for local notification it's not supposed to
// because (applicationIconBadgeNumber = 0) means "Do not change the badge"
// I'm looking for an alternative if it exists.
UILocalNotification *clearEpisodeNotification = [[UILocalNotification alloc] init];
clearEpisodeNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:(60 * 20)];
clearEpisodeNotification.timeZone = [NSTimeZone defaultTimeZone];
clearEpisodeNotification.applicationIconBadgeNumber = 0;
[[UIApplication sharedApplication] scheduleLocalNotification:clearEpisodeNotification];
[clearEpisodeNotification release];
}
I had the same problem. When setting the badge from a local notification, setting it to 0 is the default for 'no change', while doing it straight from the application would clear it. Setting it to a negative number through a local notification solved the problem.
try:
clearEpisodeNotification.applicationIconBadgeNumber = -1;
Yes, it is possible to clear the badge from the app itself.
I use the code below in one of my apps, and it works as expected (i.e. clears the badge):
//clear app badge
[UIApplication sharedApplication].applicationIconBadgeNumber=0;