0

Невозможно запланировать ежедневное местное PushNotification. Я хочу показать только одну ежедневную локальную PushNotification в 9:00 с подсчитанными задачами на сегодняшний день.Как планировать ежедневное локальное push-уведомление в iOS (ObjC)?

Мой код выполняется только один раз в 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:00, но с неправильными данными в _todayTasks, он также может быть случайным образом срабатывает с другими _todayTasks и повторяется несколько раз в произвольное время.

ответ

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. Создать уведомление, если пользователь разрешить местным Notifications (пример 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; 
    } 
    

Также не подделывать t, чтобы позвонить [[UIApplication sharedApplication] cancelAllLocalNotifications]; - это очистит все уведомления, и вы удалите все random Уведомления

+0

Это, кажется, работает, спасибо. –

1

Невозможно определить, где вы определяете _todayTasks. Ваш код для запуска уведомления в целом должен работать. И, как вы сказали, это так.

Возможно, _todayTasks еще не был инициализирован (при запуске)? Вы используете NSUserDefaults?

Еще одна проблема может заключаться в том, что вы не очистили старые уведомления, которые были запланированы несколькими запусками, и поэтому данные неверны?

Вы можете попробовать NSLog для печати данных и сначала посмотреть, что внутри.

Я планирую свое уведомление при вызове метода «applicationWillResignActive». также очистить все другие уведомления, когда приложение снова запускает («applicationDidBecomeActive»), как это (к сожалению, в скор):

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

Отмеченный ответ @Kirill принят, потому что он более полный. Спасибо за помощь тоже :-) –

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].