如何在iOS(ObjC)中安排每日本地推送通知?

时间:2015-10-23 11:50:33

标签: ios objective-c push-notification uilocalnotification schedule

无法以正确的方式安排每日本地PushNotification。 我想在上午9点只显示一个每日本地PushNotification,并计算今天的计算任务。

我的代码只在didFinishLaunchingWithOptions执行一次,如:

- (void)scheduleLocalNotification
{
    self.localNotification = [UILocalNotification new];

    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components:unitFlags fromDate:[NSDate date]];
    components.hour = 9;
    components.minute = 0;
    components.second = 0;
    NSDate *fireTime = [calendar dateFromComponents:components];

    _localNotification.fireDate = fireTime;
    _localNotification.alertBody = [NSString stringWithFormat:@"Hi, <username>. You have %ld tasks for today", (long)_todayTasks];
    _localNotification.repeatInterval = NSCalendarUnitDay;
    _localNotification.soundName = @"alarm.wav";
    _localNotification.timeZone = [NSTimeZone localTimeZone];

    [[UIApplication sharedApplication] scheduleLocalNotification:_localNotification];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"HH:mm"];
    NotificationManagerLog(@"schedule local notification at %@", [dateFormatter stringFromDate:fireTime]);
}

我觉得我错过了一些东西,因为它确实在9点触发,但_todayTasks中的数据错误,也可以随机触发其他_todayTasks值并重复几次随机时间的时间。

3 个答案:

答案 0 :(得分:1)

一步一步:

  1. 注册通知:

    - (void)prepareLocalNotification
        {
        if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
            UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert categories:nil];
            [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        } else  {
            UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
            [[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
        }
    }
    
  2. 如果用户允许本地通知(例如每天下午3点),则创建通知:

    - (void)createDailyBasisNotification
    {
        [[UIApplication sharedApplication] cancelAllLocalNotifications];
        UILocalNotification *next3pm = [self notificationForTime:15 withMessage:<NotificationMessage3PM> soundName:UILocalNotificationDefaultSoundName];
    
        [[UIApplication sharedApplication] scheduleLocalNotification:next3pm];
    }
    
    - (UILocalNotification *)notificationForTime:(NSInteger)time withMessage:(NSString *)message soundName:(NSString *)soundName
    {
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.alertBody = message;
        localNotification.repeatInterval = NSDayCalendarUnit;
        localNotification.timeZone = [NSTimeZone localTimeZone];
        localNotification.soundName = soundName;
    
        NSDate *date = [NSDate date];
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *dateComponents = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:date];
    
        [dateComponents setHour:time];
    
        NSDate *next = [calendar dateFromComponents:dateComponents];
        if ([next timeIntervalSinceNow] < 0) {
            next = [next dateByAddingTimeInterval:60*60*24];
        }
        localNotification.fireDate = next;
    
        return  localNotification;
    }
    
  3. 另请不要忘记致电[[UIApplication sharedApplication] cancelAllLocalNotifications]; - 这会清除所有通知,您将删除所有random次通知

答案 1 :(得分:1)

无法看到您定义_todayTasks的位置。 一般来说,触发通知的代码应该有效。就像你说的那样,确实如此。

也许_todayTasks尚未初始化(启动时)?你在使用NSUserDefaults吗?

另一个问题可能是您没有清除多次启动时安排的旧通知,因此数据错误了?

您可以尝试使用NSLog打印数据并先查看内部信息。

我在调用“applicationWillResignActive”方法时安排通知。 此外,当应用程序再次启动时,我会清除所有其他通知(“applicationDidBecomeActive”)(不幸的是在swift中):

// Clear all Notifications
let notifications = UIApplication.sharedApplication().scheduledLocalNotifications!
if notifications.count > 0 {
    print("reset Notifications.")
    UIApplication.sharedApplication().cancelAllLocalNotifications()
}

答案 2 :(得分:0)

NSString *strCurrentDate = [dateformat stringFromDate:[NSDate date]];

if ([strCurrentDate isEqualToString:[AppData getAppData].strLastDate]) 
{
  [[AppData getAppData] setIsDoneLN:YES];
}
else
{
  [[AppData getAppData] setIsDoneLN:NO];

 }

if (![AppData getAppData].isDoneLN) {

[self callLN];

}

-(void)callLN
{

// your notification code here


NSDateFormatter *dateformat;
if (!dateformat) 
{
   dateformat = [[NSDateFormatter alloc] init];
}
[dateformat setDateFormat:@"yyyy-MM-dd"];
[[AppData getAppData] setStrLastDate:[dateformat stringFromDate:[NSDate date]]];

}

//NOTE:[AppData getAppData] is a singleton class that return NSUserDefaults value. you can use normal NSUserDefaults to save and retrive the values instead of using [AppData getAppData].