UILocalNotification triggered but not scheduled - ios

Hi people I have a problem with my app, where I want to add some basic LocalNotifications, which repeat themselves every week. I want to do this in a method called "scheduleLocalNotificationForItem:", which is called when the doneBarButtonItem is pressed. This all seems to be working so far, because when I log all the scheduled notifications every scheduled notification shows up. But when I use the app, the scheduled notifications get triggered and show up but there are some additional notifications, which I haven't set myself and I can't determinate where they come from, which appear too.
So here's my code:
- (int)scheduleNotifitactionsForItem:(AlarmItem *)item
{
NSArray *reorderdRepeat = [NSArray arrayWithArray:[self transformArray:item.repeat]];
int missedDays = 0;
int scheduledAlarms = 0;
for (int i = 0; i < item.repeat.count; i++) {
if ([[reorderdRepeat objectAtIndex:i] boolValue] == true) {//Problem determinating true values at end of array
NSInteger integerOfDay = i + 1;//reorderRepeat should contain seven items, icrement i bevore adding it to integerOfDay
NSDate *lastAlarmTime = [self getFireDateForDayOfWeek:integerOfDay withTime:item.time];
NSArray *allAlramTimesForDay = [self getFireDatesForTime:lastAlarmTime andCycle:item.cycles];
for (int i = 0; i < allAlramTimesForDay.count; i++) {
NSDate *alarmTime = [allAlramTimesForDay objectAtIndex:i];
UIApplication *application = [UIApplication sharedApplication];
UILocalNotification *notification = [UILocalNotification new];
NSDictionary *userInfo = #{#"index":[NSString stringWithFormat:#"%d",item.notification]};
notification.repeatInterval = NSCalendarUnitWeekday;
notification.alertBody = item.title;
notification.userInfo = userInfo;
notification.fireDate = alarmTime;
notification.soundName = item.sound;
[application scheduleLocalNotification:notification];
scheduledAlarms += 1;
}
} else {
missedDays += 1;
}
}
return scheduledAlarms;
}
Help is appreciated ;)

Your repeatInterval should be NSCalendarUnitWeekOfYear (or old NSWeekCalendarUnit). NSCalendarUnitWeekday (NSWeekdayCalendarUnit) will repeat everyday.

Related

How do I make UILocalNotification method keep running

I am trying to build a calendar style app that reminds people when certain events are happening the day before they happen.
I am using UILocalNotifications for this.
I have to restart my app if I want the notification to appear.
How can I have this code continuously run regardless if the app is still running or is closed, and display the notification on time?
I was wondering if I had to put this into the applicationDidEnterBackground method to make it work?
Currently my code looks like this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMMM dd, yyyy"];
NSString* path = [[NSBundle mainBundle] pathForResource:#"example"
ofType:#"txt"];
NSString* content = [NSString stringWithContentsOfFile:path
encoding:NSUTF8StringEncoding
error:NULL];
NSArray* allLinedStrings = [content componentsSeparatedByCharactersInSet:
[NSCharacterSet newlineCharacterSet]];
NSDate *tomorrow = [today dateByAddingTimeInterval:60*60*24*1];
NSString *tomorrowString = [dateFormatter stringFromDate:tomorrow];
for (int i = 0; i < allLinedStrings.count; i++) {
NSString* strsInOneLine = [allLinedStrings objectAtIndex:i];
NSArray* singleStrs = [strsInOneLine componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#";"]];
NSString *date = [singleStrs objectAtIndex:0];
if ([date isEqualToString:tomorrowString]) {
for (int j = 1; j < singleStrs.count; j+=2) {
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.fireDate = [NSDate dateWithTimeInterval:60*60*-24 sinceDate:tomorrow];
notification.alertBody = [singleStrs objectAtIndex:j+1];
notification.alertTitle = [singleStrs objectAtIndex:j];
notification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication]scheduleLocalNotification:notification];
}
}
}
// Override point for customization after application launch.
return YES;
}
Your app code does not need to be running for your local notification to be displayed. Once your app has called scheduleLocalNotification:, the notification will display whether or not you app is running.
If you app is in the foreground, you will also want to implement application:didReceiveLocalNotification:. If you want your app to respond to being opened by the user interacting with the notification, you will want to implement application:handleActionWithIdentifier:forLocalNotification:completionHandler:
As to the question of where to put the code that schedules the notification, it should go anywhere in your app that knows the event to be scheduled. It only needs to be called once per notification. It can be scheduled far in advance.

objectForKey: returning null

Hi people I m working on a AlarmApp and I want to schedule some localNotifications, this works so far, but when I try to delete them my problem appears. I'm trying to list all localNotifications and loop throughout their userInfo to determinate which Notification has to be deleted. I've added a dictionary to the userInfo property of the Notification with value = index of alarm im alarmArray and key = "index" and now I'm trying to get backt that index with objectForKey: I've also tried valueForKey: but it doesn't work. When I log the dictionary it said that the dictionary contains one item: { 0 = index; } but when I try to log the valueForKey:#"index" the console gives me back a "null".
So can someone tell me what I'm doing wrong? Here's my code:
- (void)deleteNotificationForKey:(int)key
{
UIApplication *application = [UIApplication sharedApplication];
NSArray *eventArray = [application scheduledLocalNotifications];
for (int i = 0; i < eventArray.count; i++) {
UILocalNotification* notification = [eventArray objectAtIndex:i];
NSDictionary *currentUserInfo = notification.userInfo;
NSString *index = [currentUserInfo objectForKey:#"index"];
NSLog(#"%s:%#",__PRETTY_FUNCTION__,currentUserInfo);
NSLog(#"%s:%#",__PRETTY_FUNCTION__,index);
NSLog(#"%s:%d",__PRETTY_FUNCTION__,key);
if ([index intValue] == key)
{
NSLog(#"%s:%#",__PRETTY_FUNCTION__,notification);
[application cancelLocalNotification:notification];
}
}
}
It should work if you use stringWithFormat:
NSString *index = [NSString stringWithFormat:#"%#", [currentUserInfo valueForKey:#"index"]];
In this situation your dictionary object is #"index" and key is #0, if you try this, it should work
NSString *index = [currentUserInfo objectForKey:#0];
To solve this problem you need to change #0 and #"index" places when you initialize your dictionary

iOS local notification userInfo always null

I am trying to schedule a local notification with some custom data attached which I will then read when the user opens the app by clicking on the notification.
I schedule the local notification like this:
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [[NSDate date] dateByAddingTimeInterval:10];
notification.alertBody = #"Hello World!";
notification.userInfo = [[NSDictionary alloc] initWithObjectsAndKeys:
#"123123123123", #"beaconUUID",
[NSNumber numberWithInt:10], #"beaconMajor",
[NSNumber numberWithInt:20], #"beaconMinor",
nil];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
Then in the code which handles the notification I do this:
- (void)onAppDidBecomeActive:(NSNotification*)notification
{
NSLog(#"Object = %#", [notification object]);
NSDictionary* userInfo = [notification userInfo];
NSLog(#"UserInfo = %#", userInfo);
NSString* beaconUUID = [userInfo objectForKey:#"beaconUUID"];
NSLog(#"Beacon UUID = %#", beaconUUID);
}
My problem is that when I try to read the userInfo it always returns null. How do I read the userInfo dictionary from a NSNotification object?
The three NSLog calls from the above code sample print the following in the console:
2015-02-04 14:11:52.690 BeaconPlugin[17050:724150] Object = <UIConcreteLocalNotification: 0x7ff1d37199a0>{
fire date = Wednesday, February 4, 2015 at 2:11:51 PM Central European Standard Time,
time zone = (null),
repeat interval = 0,
repeat count = UILocalNotificationInfiniteRepeatCount,
next fire date = (null),
user info = {
beaconMajor = 10;
beaconMinor = 20;
beaconUUID = 123123123123;
}}
2015-02-04 14:11:52.691 BeaconPlugin[17050:724150] UserInfo = (null)
2015-02-04 14:11:52.691 BeaconPlugin[17050:724150] Beacon UUID = (null)
Which does show that the dictionary values are part of the user info. Anybody got any ideas what I am doing wrong?
You scheduled a UILocalNotification but you are retrieving your user info from a NSNotification, this two is not the same.
you should do this:
UILocalNotification *localNotif = [notification object];
NSDictionary *userInfo = [localNotif userInfo];
NSString* beaconUUID = [userInfo objectForKey:#"beaconUUID"];
Its worked for when i receive from didReceiveLocalNotification protocol
in AppDelegate.m file
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState state = [application applicationState];
NSLog(#"Object = %#", notification);
NSDictionary* userInfo = [notification userInfo];
NSLog(#"UserInfo = %#", userInfo);
NSString* beaconUUID = [[notification userInfo] objectForKey:#"beaconUUID"];
NSLog(#"Beacon UUID = %#", beaconUUID);
}
see below output console
2015-02-04 19:11:12.937 SampleNO[6676:907] Object = <UIConcreteLocalNotification: 0x769e780>{fire date = Wednesday, February 4, 2015, 7:11:09 PM India Standard Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = (null), user info = {
beaconMajor = 10;
beaconMinor = 20;
beaconUUID = 123123123123;
}}
2015-02-04 19:11:14.621 SampleNO[6676:907] UserInfo = {
beaconMajor = 10;
beaconMinor = 20;
beaconUUID = 123123123123;
}
2015-02-04 19:11:18.086 SampleNO[6676:907] Beacon UUID = 123123123123

Trying to create UILocalNotification repeating every weekday

I'm trying to create a repeating local notification using Xamarin.IOS. I want to have different alert body message each day, for example "It's monday", "It's tuesday" and so on.
The problem I have is that the only the first notification is working. After I've read the documentation and a few tutorials the correct way to create a repeating notification is to loop through each day and create a total of seven notifications that has the RepeatInterval property set to NSCalendarUnit.Weekday.
My code is a bit messy at the moment...
for (int i = 0; i <= 6; i++) {
NSDateComponents components = gregCalendar.Components (NSCalendarUnit.Day | NSCalendarUnit.Year | NSCalendarUnit.Month, DateTime.Now.AddDays(i).ToNSDate());
components.Day = DateTime.Now.AddDays(i).Day;
components.Month = DateTime.Now.AddDays(i).Month;
components.Year = DateTime.Now.AddDays(i).Year;
NSDate referenceDate = gregCalendar.DateFromComponents (components);
NSDateComponents componentsForFireDate = gregCalendar.Components (NSCalendarUnit.Year | NSCalendarUnit.Hour | NSCalendarUnit.Minute, referenceDate);
componentsForFireDate.Year = components.Year;
componentsForFireDate.Month = components.Month;
componentsForFireDate.Day = components.Day;
componentsForFireDate.Hour = 8;
componentsForFireDate.Minute = 0;
var dayOfWeek = (int)DateTime.Now.AddDays (i).DayOfWeek + 1;
if (dayOfWeek == 8)
dayOfWeek = 1;
componentsForFireDate.Weekday = dayOfWeek;
NSDate fireDateOfNotification = gregCalendar.DateFromComponents (componentsForFireDate);
UILocalNotification localNotification = new UILocalNotification ();
localNotification.FireDate = fireDateOfNotification;
localNotification.TimeZone = NSTimeZone.LocalTimeZone;
localNotification.AlertBody = dayOfWeek;
localNotification.AlertAction = "daily";
localNotification.RepeatCalendar = NSCalendar.CurrentCalendar;
localNotification.RepeatInterval = NSCalendarUnit.Weekday;
localNotification.ApplicationIconBadgeNumber = 1;
UIApplication.SharedApplication.ScheduleLocalNotification (localNotification);
}
My question is, how can I create a local notification that should repeat every day but with different alert body message depending on the weekday?
Add this code into you for loop
switch(i)
{
case 0: //mon
localNotification.alertbody = #"Monday....you message";
break;
case 1 //tue
localNotification.alertbody = #"Tuesday....you message";
break;
case 2://wed
localNotification.alertbody = #"Wednesday....you message";
break;
...
...
}

Local Notification Ever Changing Text

I am working on getting local notifications to fire at a time every day (set by the user). I have done this in the past, but just where it was one static message that would get shown every day. I would like for it to take the text for the local notification from a plist file I have made with each row being a quote. Is there a way to fire local notifications, but have it change the text every day?
I have right now:
- (IBAction)scheduleNotification {
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil) {
UILocalNotification *notif = [[cls alloc] init];
notif.fireDate = [datePicker date];
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = #"Today's 5 Minutes With God Study Is Now Available";
notif.alertAction = #"Ok";
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = 1;
NSInteger index = [scheduleControl selectedSegmentIndex];
switch (index) {
case 0:
notif.repeatInterval = NSDayCalendarUnit;
break;
case 1:
notif.repeatInterval = 0;
break;
}
NSDictionary *userDict = [NSDictionary dictionaryWithObject:#"Today's Quote!"
forKey:kRemindMeNotificationDataKey];
notif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
[self.notifications addObject:notif];
[notif release];
}
}
So, how would I get the alertBody to show a different message each day?
You have to create a new notification every time, for every new message.

Resources