I am working on time based reminder App. in which the user enter his reminder and time for the reminder. The problem is that how to continuously comparing the current time with the user defined time. Any sample code will greatly help. because i am stuck on this point.
Comparing the current time vs. the user defined one is not the right design pattern.
UIKit offers the NSLocalNotification object that is a more high-level abstraction for your task.
Below is a snip of code that create and schedule a local notification at the choosen time:
UILocalNotification *aNotification = [[UILocalNotification alloc] init];
aNotification.fireDate = [NSDate date];
aNotification.timeZone = [NSTimeZone defaultTimeZone];
aNotification.alertBody = #"Notification triggered";
aNotification.alertAction = #"Details";
/* if you wish to pass additional parameters and arguments, you can fill an info dictionary and set it as userInfo property */
//NSDictionary *infoDict = //fill it with a reference to an istance of NSDictionary;
//aNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:aNotification];
[aNotification release];
Also, be sure to setup your AppDelegate to respond to local notifications, both at startup and during the normal runtime of the app (if you want to be notified even the application is in foreground):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *aNotification = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];
if (aNotification) {
//if we're here, than we have a local notification. Add the code to display it to the user
}
//...
//your applicationDidFinishLaunchingWithOptions code goes here
//...
[self.window makeKeyAndVisible];
return YES;
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
//if we're here, than we have a local notification. Add the code to display it to the user
}
More details at the Apple Developer Documentation.
Why not use NSLocalNotification which you can set for a specified time, much like a calendar event. Alternatively you can add calendar events to the users calendar with EKEventKit
Tutorial for local notifications.
Tutorial for event kit.
Related
I am creating a local UILocalNotification and displaying it to the user as a banner. Is it possible to set it up so that when the user taps it and returns to the app, the app will receive some kind of data on the specific kind of notification it was? I want to open a specific view controller in the app. I think the best way would be to essentially send a URL to the app, or is there a way to get access to the UILocalNotification so that I can test which kind is was and do the right action?
To get data from the local NSUserNotification that is passed to an iOS app, all that you need to do is implement the following method: - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification.
The problem is, this is called both when a local notification is posted when the app is in the background (i.e. when the user taps on the notification and then returns to the app), and also if the app is in the foreground at the time when the local notification fires (it is on a timer, after all). So how should one figure out if the notification was fired when the app was in the background or foreground? It's pretty simple. Here's my code:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
} else {
// App was running in the foreground. Perhaps
// show a UIAlertView to ask them what they want to do?
}
}
At this point you can handle the notification based on notification.userInfo, which holds a NSDictionary.
ust implement the NSUserNotificationCenterDelegate and define this method:
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
Example:
This is what I did in a "notifier" application.
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
NSRunAlertPanel([notification title], [notification informativeText], #"Ok", nil, nil);
}
- (void) userNotificationCenter:(NSUserNotificationCenter *)center didDeliverNotification:(NSUserNotification *)notification
{
notifications=nil;
[tableView reloadData];
[center removeDeliveredNotification: notification];
}
When the notification is activated (click by the user) I just inform the user with a panel (I could use a hud window).In this case I immediately remove the delivered notification, but this is not what happens usually.The notification could stay there some time and be removed after 1/2 hours (it depends on the application that you are developing).
1 - Define some class in your project to implement NSUserNoficationCenterDelegate protocol (documented here)
#interface someObject : NSObject <NSUserNotificationCenterDelegate>
{
- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification;
}
2 - Set an instance of the object defined #1 as the delegate of default notification center.
[[NSUserNotificationCenter defaultNotificationCenter] setDelegate: someObject];
Now you will get called on didActivateNotification any time the user taps/clicks on the notification. You will have the original notification you created. So any information that you need should be available to you.
If you want/need special information (other than notification title, message, etc) you will probably need to set additional application specific information in your notification before you schedule it to be sent. For example:
NSUserNotification* notification = [[NSUserNotification alloc] init];
NSDictionary* specialInformation = [NSDictionary dictionaryWithObjectsAndKeys: #"specialValue", #"specialKey", nil];
[notification setUserInfo:specialInformation];
I have studied some of the following questions, that are::
1.) How to set alarm for selected days in iphone?
2.) iPhone alarm using repeated local notifications
3.) How to set the alarm in iPhone and save in local notification?
but they all are using local notifications. I am facing problem with local notification as I have to use three buttons on an Alarm View which are: Snooze, Ignore and Okay. I have to perform custom actions on each button click.
Please help me with this stuff.
Suggestions accepted.
Thanks in advance.
Kuldeep.
In you app delegate...
- (void) presentWidget: (NSString*)theDisplayedText {
BOOL widgetIspresent = [WidgetVC widgetIsCurrentlyPresented];
if (!widgetIspresent) {
WidgetVC *widgetVC = [[WidgetVC alloc] initWithNibName:#"WidgetVC" userInfoString:theDisplayedText bundle:nil];
widgetVC.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
widgetVC.userInfoStr = theDisplayedText;
[mainScreenManager presentViewController:widgetVC animated:YES completion:nil];
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif) {
NSLog(#"Recieved Notification didFinishLaunchingWithOptions %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
//here we have to handle whatever notification was pressed - that might also be an old aready passed one
//this all is checked when the widget opens - it will show if the notification is OK or too old
[self presentWidget: theDisplaytext ];
} else {
//so we started the app normally, not via local notification
[self presentWidget];
}
return YES;
}
// Handle the notificaton when the app is running
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)localNotif {
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification didReceiveLocalNotification %#",localNotif);
NSString *theDisplaytext = [localNotif.userInfo valueForKey:#"someKey"];
[self presentWidget: theDisplaytext];
}
You need a way to start the UIViewController for the widget, I just created a mainScreenManager helper.
So on the widgetVC you have your "Snooze" and "OK" while the "Ignore" is just the ignoring of the notification itself.
Hope this gets you on an usable track...
ps I ported my app from Android to iPhone, that's why I used the name "widgetVC" for this screen. On Android it is implemented as a widget. Hope no iPhone lover feels offended :-)
I'm trying to change the badge of the application I'm developing. When closed, unfortunately I was only notified a message without changing the badge.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge];
NSDictionary* userInfo = [launchOptions valueForKey:#"UIApplicationLaunchOptionsRemoteNotificationKey"];
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSInteger badge = [[apsInfo objectForKey:#"badge"] integerValue];
if( [apsInfo objectForKey:#"alert"] != NULL)
{
application.applicationIconBadgeNumber = badge;
}
But that does not change anything. I have not found any solution around. What method is invoked on arrival of a push notification and the application is closed? I also added:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
#if !TARGET_IPHONE_SIMULATOR
NSLog(#"remote notification: %#",[userInfo description]);
NSDictionary *apsInfo = [userInfo objectForKey:#"aps"];
NSString *alert = [apsInfo objectForKey:#"alert"];
NSLog(#"Received Push Alert: %#", alert);
NSString *badge = [apsInfo objectForKey:#"badge"];
NSLog(#"Received Push Badge: %#", badge);
application.applicationIconBadgeNumber = [[apsInfo objectForKey:#"badge"] integerValue];
#endif
}
But nothing...
Can you help me?
The badge icon number is governed by the badge property in the payload received as push message. The app itself has no role to play in what number shows up till the app becomes active. Setting the 'badge' property to any integer value (Note : it should not be string and should NOT be enclosed within "") does what is needed. The OS on receiving the notification looks for the value for 'badge' and immediately sets it on the app badge icon. All this happens when app is not active. To make sure it increments or decrements based on what happens in the app, the app should send message to server with the updated badge number.
In the active state, it is app's responsibility to handle the remote notification and change the badge icon.
Note : 'badge' property is enclosed in the 'aps' dictionary received within the payload. My payload looks like :
aps = {
alert = "Push notification!";
badge = 9;
sound = default;
}
You should define better what you want to do because it is not clear to me if wether you are talking about remote or local notifications, or what exactly you want to get and what are you getting.
Anyway, regarding remote notifications (APNS), take into account that you should set the badge as part of the payload if you want it to be set with the app closed. Your app does not get invoked unless the user manually opens the app (from the NotificationCenter or the dock).
On the other hand, when you are running the app, you will receive the call to
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
in your AppDelegate, and then you can set the badge by using
application.applicationIconBadgeNumber = badge;
Look at this, maybe it is a settings problem!:
application Icon Badge Number in ios5
Try also to give applicationIconBadgeNumber an int value, not NSInteger.
OK. Now my report about strange things.
I got it! It works good for now.
Problem was:
i created my App with push notification everything was ok with simple integer (1,8,99) but then i noticed that my integer 35.06 in the PHP variable $price did not recognize it at all even (int)$price unsuccessful . I thought the number is too long (but actually 4 digits is very popular). I decided to use
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
but as it was mentioned it does not work at all when the App is not started. No chance. It will never update the badge. I spent a lot of time thinking about what could be wrong and suddenly something came on my mind.
in the payload i just did this
'badge' => $price*100
an of course it worked good for me =)
I dont know what is the problem , why didn't work (int)$price (it is actually integer) but it is ok now.
My badge shows now something like this 3.506 and of course you can move the dot on step and you have your 35.06
Hope it could help you.
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 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.