3

I'm trying to have a conditioned firedate time for my local notifications, however when I tried these two ways it didn't fail but it still didn't work. So, I was wondering if I'm able to do such a thing?

Note: startTime and endTime are times from date pickers.

-(void) TEST {

NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];

NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:[NSDate date]];
components.hour   = 3;
components.minute = (components.minute + 1) % 60;
components.second = 57;

NSDate *fire = [calendar dateFromComponents:components];
UILocalNotification *notif = [[UILocalNotification alloc]  init] ;
if (notif == nil)
    return;

if (fire < startTime.date) {


notif.fireDate =fire ;
    notif.repeatInterval= NSMinuteCalendarUnit ;
    notif.alertBody = [NSString stringWithFormat: @"You are missed!"] ;
    [[UIApplication sharedApplication] scheduleLocalNotification:notif] ;


    }

if (fire > endTime.date) {


    notif.fireDate =fire ;
    notif.repeatInterval= NSMinuteCalendarUnit ;
    notif.alertBody = [NSString stringWithFormat: @"You are missed!"] ;
    [[UIApplication sharedApplication] scheduleLocalNotification:notif] ;


}}

OR

-(void) TEST {

NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];

NSDateComponents *components = [calendar components:NSHourCalendarUnit fromDate:[NSDate date]];
components.hour   = 3;
components.minute = (components.minute + 1) % 60;
components.second = 57;

NSDate *fire = [calendar dateFromComponents:components];
UILocalNotification *notif = [[UILocalNotification alloc]  init] ;
if (notif == nil)
    return;

if (fire > startTime.date & fire < endTime.date) {

    [[UIApplication sharedApplication] cancelAllLocalNotifications] ;
}

else {
    notif.fireDate =fire ;
    notif.repeatInterval= NSMinuteCalendarUnit ;
    notif.alertBody = [NSString stringWithFormat: @"You are missed!"] ;
    [[UIApplication sharedApplication] scheduleLocalNotification:notif] ;


}}

Thanks

If not, what would be the easiest way to make such a condition?

user1949873
  • 460
  • 7
  • 17
  • Did you log the fire date? If you use the minute from the component you need to load the minute when getting the component from the calendar + date (NSMinuteCalendarUnit). – Wain May 05 '13 at 06:13
  • Yes I did log it and it never goes inside the if condition – user1949873 May 05 '13 at 11:38
  • Try `if ([fire timeIntervalSinceDate:startTime.date] >= 0) // fire is before start`. –  May 07 '13 at 09:58
  • @relikd Thanks, but still not working! :/ – user1949873 May 07 '13 at 23:49
  • @Bonnie **none of your answer worked** and I guess there is no solutions for such a thing as I couldn't find anyway to perform notifications cancellation on a specific time while in the background. **However, you deserve the 100 points for your hard work. Thank you.** – user1949873 May 13 '13 at 02:58
  • thanks mate, pleasure .but if you ever find something do post it here. – Bonnie May 13 '13 at 05:48

2 Answers2

0

use the NSDate Compare: method instead of if(fire > startTime.date)

if([fire compare: startTime.date] == NSOrderedDescending) // if start is later in time than end
{
    // do something
}

From the class reference:

If:
The receiver and anotherDate are exactly equal to each other, NSOrderedSame.
The receiver is later in time than anotherDate, NSOrderedDescending.
The receiver is earlier in time than anotherDate, NSOrderedAscending.

so for your condition

if (fire > startTime.date & fire < endTime.date) {

    [[UIApplication sharedApplication] cancelAllLocalNotifications] ;
}

you can use

if([fire compare: startTime.date] == NSOrderedDescending && [fire compare: endTime.date]== NSOrderedAescending)
{
   [[UIApplication sharedApplication] cancelAllLocalNotifications] ;
}

this will cancel the all local notifications if fire is between the selected start and end date

else {
// Fire the notifications
}

also have a look at the link this is similar to what you need link

Community
  • 1
  • 1
Bonnie
  • 4,943
  • 30
  • 34
  • unfortunately, notification is still firing and it didn't cancel!! I heard you can't have constrains on `UILocalNotification` is it true? – user1949873 May 07 '13 at 22:19
  • please tell what exactly you need to do, and what is not working, my assuption: startTime and EndTime is the time between which u notifications will not be triggered.? right.?? acording to this code if the fireDate is between the start and end time, the Notification will not be created, so no possibility of it triggering. Do you want to want to just cancel all notifications already created that fall in the DoNotDisturb time frame.?? or u just dont want the user to allow creating new UILocalnotication between the DoNotDisturb time frame – Bonnie May 08 '13 at 05:56
  • Your assumptions are right. I want to cancel the notifications between startTime and endTime. So, will this code be able to cancelAllLocalNotifications in the background when it was already scheduled? Because I tried it and it didn't work! – user1949873 May 08 '13 at 07:26
  • Here is the scenario, I have a local notification that is scheduled for a repeat interval every hour. I want when the user choose startTime and endTime these notifications will stop automatically during the night and reschedule again without the need to open the app. How can I do that? Is it possible with this code? – user1949873 May 08 '13 at 07:30
  • there is no straght way of doin that but, have a look at this http://stackoverflow.com/questions/15773544/activate-local-notification-based-on-time-in-the-background exatcly what you need – Bonnie May 08 '13 at 08:18
  • That was actually my question but when I tried I couldn't get it to work because I have 24 hourly interval repeated notification and he is asking me to make it daily repeat interval. If there isn't a straight way then how do you do it? Considering I need to fire a notification every 5 minute. – user1949873 May 08 '13 at 13:40
0

what i, will try do do is, when the sleep Time starts,call a method eg: goingToSleep:, you can use dispatch_later or performSelector:withObject:afterDelay: for that,

in goingToSleep:

NSArray* localNotifications = [[UIApplication sharedApplication] 
                                              scheduledLocalNotifications];
for (UILocalNotification *notification in localNotifications)
{
    if([fire compare: startTime.date] == NSOrderedDescending &&
       [fire compare: endTime.date]== NSOrderedAescending)
    {

This is the important part

  • get all the properties of the notification
  • create a NSDictionary of those properties
  • Add the NSDictionary to an array
  • and save that array into a plist.(Save Array to Plist)

  • and then Cancel that notification using

    [[UIApplication sharedApplication] cancelLocalNotification:notification];
    }
    

}

then after SleepTime is over , again call a method eg: wakingUp:

then in wakingUp:

  • read the array of NSDictionary we saved.
  • again Create UILocalnotifications using those same Properties.

this way, no UILocalNotifications will trigger during sleep time. one issue can be executing those methods, if the Application is not memory.

EDIT To have long Running Appicaions.

Community
  • 1
  • 1
Bonnie
  • 4,943
  • 30
  • 34
  • Thank you very much the code have worked partially. I tried the delay property and it worked while the app is running. However, I'm still trying to understand the Plist, NSDictionary and the arrays so I can make it work on the background. I have 2 questions: do you have any links to tutorial explains your answer? Or can you point me to elaborated answers? – user1949873 May 11 '13 at 10:00
  • What do you mean by "one issue can be executing those methods, if the Application is not memory"? What is a memory application? – user1949873 May 11 '13 at 10:01
  • Unfortunately, performSelctor:withObject:afterDelay won't work in background after the first 10 minutes :/ – user1949873 May 11 '13 at 16:22
  • exactly..dats wat i meant when i said "one issue can be executing those methods, if the Application is not memory". ie the application is closed by the os. find a way to keep it running, i have posted a [link](http://stackoverflow.com/questions/16354759/nstimer-stops-in-the-background-after-some-time/16354843#16354843), have a look at my other answer – Bonnie May 13 '13 at 05:42
  • Why have you answered twice? You shouldn't be doing this you should have update your original answer. – Popeye May 13 '13 at 12:39
  • I know that bro, but you should look at the question. my first answer was only related to the conditions that were not working as required. and my second answer was for the bounty "If not, what would be the easiest way to make such a condition?". i had to post two answer's because, a person visiting the question later on would not understand. And its not necessary to always update the previous answer "specially if both are completely different and correct". otherwise Stack Overflow wouldn't give the provision to add two answer's. – Bonnie May 13 '13 at 12:47
  • To be honest mate all it looks like is you've answer the question twice and that's it. There isn't anything to say why. Maybe you should include the reason why in your answer. Just my opinion, up to you if you do include it. It's not very common for users to answer twice they generally just update there original answer and make it clear that it is an edit and the reason for the edit. – Popeye May 13 '13 at 13:00
  • if you would have read the question and both the answer's properly you would have had a different opinion, leave it mate, move on. – Bonnie May 13 '13 at 13:04
  • I have just re-read the question and both answers and I see no reason at all now why this needs two answers from you this could definitely have been one answer. If anything I am going to question how this answer (not the first one) actually answers the question. If something was included in the reason for the bounty then that should be included somewhere as no one knows the reason for this. I am now considering a downvote because of both of the reasons stated in comments. – Popeye May 13 '13 at 13:09
  • hahaha. I just saw your profile, r u crazzy man. even when i said leave it and move on, ur still stuck at me posting two answer's, and now down voting it for the reason of posting two ans rather than the quality of the answer's itself and ur about me is funny naming people in ur profile.haha.. u seriously need medication mate, i now understand wat's wrong with you, ur downvote doesnt affect me at all,it'l just confuse others. Go out there and do something constructive mate, rather than complaining like a baby. This will be my last comment, i don't have anymore time to waste on people like you. – Bonnie May 14 '13 at 06:49