【问题标题】:UILocalNotification is supposed to repeat every weekday, but fires on weekends as wellUILocalNotification 应该在每个工作日重复,但也会在周末触发
【发布时间】:2012-03-24 20:08:18
【问题描述】:

我有一个 UILocalNotification 应该每天触发一次,从周一到周五,但不是在周末。我认为将通知的 repeatInterval 属性设置为 NSWeekdayCalendarUnit 可以完成此操作。对我来说可悲的是,我的通知仍然在周末触发。谁能建议为什么?这是我的代码:

UILocalNotification *localNotification = [[UILocalNotification alloc] init];

localNotification.alertAction = @"View";
localNotification.alertBody = NSLocalizedString(@"ALERT_MESSAGE", nil);
localNotification.soundName = UILocalNotificationDefaultSoundName;

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM-dd-yyyy HH:mm"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"America/Toronto"]];

// Notification fire times are set by creating a notification whose fire date 
// is an arbitrary weekday at the correct time, and having it repeat every weekday
NSDate *fireDate = [dateFormatter dateFromString:@"01-04-2012 11:00"]; 

localNotification.fireDate = fireDate;
localNotification.repeatInterval = NSWeekdayCalendarUnit;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
            break;

[localNotification release];

【问题讨论】:

    标签: ios ios5 uilocalnotification


    【解决方案1】:

    iOS 中的工作日仅表示一周中的一天。与周末相比,它没有“工作周”的含义。

    文档说得更清楚一点,建议您使用 1-7 作为单位:

    NSWeekdayCalendarUnit

    指定工作日单位。

    对应的值为 kCFCalendarUnitSecond。等于 kCFCalendarUnitWeekday。工作日单位是数字 1 到 N(对于公历 N=7,1 是星期日)。

    来源:http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSCalendar_Class/Reference/NSCalendar.html

    为了正确设置周一到周五的通知,这里有一些框架代码。你必须执行 5 次,所以最好将它封装在一个为 fireDate 提供参数的方法中。我已经向你展示了如何在星期一做到这一点。

    UILocalNotification *notification = [[[UILocalNotification alloc] init] autorelease];
    
    // Set this to an NSDate that is for the time you want, on Monday
    notification.fireDate = fireDate;            
    
    // Repeat every week
    notification.repeatInterval = NSWeekCalendarUnit;
    

    【讨论】:

    • 谢谢,很高兴了解这一点。完成我想要设置每周重复一次的 5 个不同通知的唯一方法是什么?
    • 是的。我用一些你可以遵循的框架代码更新了我的答案。
    • 非常感谢!虽然实现它会有点痛苦,因为我有 10 种不同的可能的每日通知。
    • 不客气。你肯定会想花一些时间来制作一些可重用的方法来创建这些通知。我在一个项目上做了同样的事情,保持代码 DRY 是值得的。
    • 感谢您的回答。 swift中的等价物是什么?我看到NSWeekCalendarUnit 已被弃用,必须使用CalendarUnitWeekOfMonth 或CalendarUnitWeekOfYear,但这些似乎不适合这个用例。
    【解决方案2】:

    您必须为本地通知单独设置日期,并将本地通知 repeatInterval 设置为 NSWeekCalendar Unit。作为

                [self notificationWithItem:tempDict Date:[self SetDateForAlarmWithWeekday:2 :tempDict] andRepeatInterval:NSWeekCalendarUnit];
                [self notificationWithItem:tempDict Date:[self SetDateForAlarmWithWeekday:3 :tempDict]andRepeatInterval:NSWeekCalendarUnit];
                [self notificationWithItem:tempDict Date:[self SetDateForAlarmWithWeekday:4 :tempDict] andRepeatInterval:NSWeekCalendarUnit];
                [self notificationWithItem:tempDict Date:[self SetDateForAlarmWithWeekday:5 :tempDict] andRepeatInterval:NSWeekCalendarUnit];
                [self notificationWithItem:tempDict Date:[self SetDateForAlarmWithWeekday:6 :tempDict] andRepeatInterval:NSWeekCalendarUnit];
    

    在这里,我创建了 setDateForAlarmWithWeekday 方法,该方法返回要在本地通知的 fireDate 属性中设置的日期,以及设置本地通知的 notificationWithItem。

    -(void) notificationWithItem:(NSDictionary*)tmpdict Date:(NSDate *)date andRepeatInterval:(NSCalendarUnit)CalUnit
    {
        UILocalNotification *localNotification =[[UILocalNotification alloc]init];
    
        if (localNotification==nil) {
            return;
        }
    
        localNotification.fireDate=date;
        localNotification.timeZone=[NSTimeZone defaultTimeZone];
        localNotification.repeatCalendar=[NSCalendar currentCalendar];
        localNotification.alertBody=[NSString stringWithFormat:@"%@",[tmpdict objectForKey:@"Reminder"]];
    
        NSDictionary *snoozeDic=[tmpdict objectForKey:@"Snooze"];
        if ([[snoozeDic valueForKey:@"Switch"]intValue]==1) {
            localNotification.alertAction=@"Snooze";
        }else
        {
            localNotification.hasAction=NO;
        }
    
        localNotification.repeatInterval=CalUnit;
        localNotification.soundName=[NSString stringWithFormat:@"%@.caf",[tmpdict objectForKey:@"Tone"]];
        localNotification.userInfo=[NSDictionary dictionaryWithObject:tmpdict forKey:@"AlarmInfo"];
        localNotification.applicationIconBadgeNumber=1;
    
        [[UIApplication sharedApplication]scheduleLocalNotification:localNotification];
    
    }
    
    
    -(NSDate*)SetDateForAlarmWithWeekday:(int)WeekDay:(NSDictionary*)dics
    {
        NSLog(@"set date for alarm called");
        NSCalendar *calendar=[NSCalendar currentCalendar];
        [calendar setTimeZone:[NSTimeZone defaultTimeZone]];
    
        unsigned currentFlag=NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit|NSWeekdayCalendarUnit;
    
        NSDateComponents *comp=[calendar components:currentFlag fromDate:[NSDate date]];
    
        NSArray *array=[[dics objectForKey:@"Time"] componentsSeparatedByString:@" "];
        NSInteger hour=[[[[array objectAtIndex:0] componentsSeparatedByString:@":"] objectAtIndex:0] intValue];
        NSInteger min=[[[[array objectAtIndex:0] componentsSeparatedByString:@":"] objectAtIndex:1] intValue];
    
        if ([[array objectAtIndex:1] isEqualToString:@"PM"]) {
            hour=hour+12;
        }
        else
        {
            if (hour==12) {
                hour=0;
            }
        }
    
        comp.hour=hour;
        comp.minute=min;
        comp.second=0;
    
        NSLog(@"set date for alarm (%i:%i:%i)",comp.hour,comp.minute,comp.second);
        NSLog(@"weekday :%i ",WeekDay);
        NSLog(@"comp weekday %i",comp.weekday);
        int diff=(WeekDay-comp.weekday);
        NSLog(@"difference :%i",diff);
    
        int multiplier;
        if (WeekDay==0) {
         multiplier=0;
        }else
        {
         multiplier=diff>0?diff:(diff==0?diff:diff+7);
        }
    
        NSLog(@"multiplier :%i",multiplier);
    
        return [[calendar dateFromComponents:comp]dateByAddingTimeInterval:multiplier*secondsInOneDay];
    }
    

    我希望这会对你有所帮助。

    【讨论】:

    • 能否分享一下 SetDateForAlarmWithWeekday 方法
    【解决方案3】:

    我也搜索过。下面的代码对我有用。将工作日值 1 传递到 7 星期日到星期六,通知正文与您要触发的操作并指定您的日期,然后通知将在该特定日期出现。 周末调用此函数两次,值为 7,周六和周日分别为 1。

    希望对您有所帮助。

    - (void) weekEndNotificationOnWeekday: (int)weekday :(UILocalNotification *)notification : (NSDate*) alramDate
    {
        NSCalendar *calendar = [NSCalendar currentCalendar];
    
        NSDateComponents *componentsForFireDate = [calendar components:(NSYearCalendarUnit | NSWeekCalendarUnit |  NSHourCalendarUnit | NSMinuteCalendarUnit| NSSecondCalendarUnit | NSWeekdayCalendarUnit) fromDate: alramDate];
        [componentsForFireDate setWeekday: weekday] ; //for fixing Sunday
        //    [componentsForFireDate setHour: 20] ; //for fixing 8PM hour
        //    [componentsForFireDate setMinute:0] ;
        //    [componentsForFireDate setSecond:0] ;
        notification.repeatInterval = NSWeekCalendarUnit;
        notification.fireDate=[calendar dateFromComponents:componentsForFireDate];
        [[UIApplication sharedApplication] scheduleLocalNotification:notification];
    
    }
    

    【讨论】:

    • 我的 nextfireDate 是 nil .. 任何建议
    【解决方案4】:

    类似但在 Swift 中。

    请记住,WeekDay 从 1 = Sunday 开始,一直到 7。请参阅 Apple Docs:https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSDateComponents_Class/

    func scheduleLocalNotification(date:NSDate, weekDay:Int){
    
            guard let calendar =  NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian),
        let groupName = dateFormatter?.stringFromDate(date) else { return }
    
            calendar.timeZone = NSTimeZone.defaultTimeZone()
    
            let dateComponents = NSDateComponents()
            dateComponents.calendar = calendar
            dateComponents.hour = calendar.component(.Hour, fromDate: date)
            dateComponents.minute = calendar.component(.Minute, fromDate: date)
            dateComponents.weekOfYear = calendar.component(.WeekOfYear, fromDate: date)
            dateComponents.weekday = weekDay
    
            let localNotificaion = UILocalNotification()
            localNotificaion.fireDate = calendar.dateFromComponents(dateComponents)
            localNotificaion.alertBody = "Hey!"
            localNotificaion.timeZone = NSTimeZone.defaultTimeZone()
            localNotificaion.userInfo = ["Time": groupName]
            localNotificaion.repeatInterval = .WeekOfYear
            UIApplication.sharedApplication().scheduleLocalNotification(localNotificaion)
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-14
      相关资源
      最近更新 更多