Подтвердить что ты не робот

IOS UILocalNotification срабатывает один раз в день, раз в два дня и только по воскресеньям

Я пытаюсь использовать набор настроек для планирования UILocalNotification. В настройках вы можете выбрать, хотите ли вы получать уведомления ежедневно (1/день), 1 раз в 2 дня, только по воскресеньям или никогда.

Вот код, который я использовал (это все в AppDelegate.m):

    -(void)defaultsChanged:(NSNotification *)notification {

         [[UIApplication sharedApplication] cancelAllLocalNotifications];

        [[NSUserDefaults standardUserDefaults]synchronize];
        NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:@"multi_preference"];

        NSLog(@"%@", testValue);

        NSDate *today = [NSDate date];

        NSCalendar* calendar = [NSCalendar currentCalendar];
        NSDateComponents* compoNents = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:today]; // Get necessary date components

        [compoNents month];[compoNents day];

        NSDictionary *dictToday= [self getDataFromdate : [compoNents day] month:[compoNents month]];


        if ([testValue isEqualToString:@"one"]){
            UILocalNotification* localNotification = [[UILocalNotification alloc] init];
            localNotification.fireDate = [[NSDate date]dateByAddingTimeInterval:20];
            localNotification.alertAction = @"View";
            localNotification.alertBody = [dictToday objectForKey:@"saint_description"];
            localNotification.repeatInterval = NSDayCalendarUnit;
            localNotification.timeZone = [NSTimeZone defaultTimeZone];
            localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;

            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
             [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self];

             }
        if (testValue==Nil){
            UILocalNotification* localNotification = [[UILocalNotification alloc] init];
            localNotification.fireDate = [[NSDate date]dateByAddingTimeInterval:20];
            localNotification.alertAction = @"View";
            localNotification.alertBody = [dictToday objectForKey:@"saint_description"];
            localNotification.repeatInterval = NSDayCalendarUnit;
            localNotification.timeZone = [NSTimeZone defaultTimeZone];
            localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;

            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self];

        }
        if ([testValue isEqualToString:@"two"]){

            UILocalNotification* localNotification = [[UILocalNotification alloc] init];
            localNotification.fireDate = [[NSDate date]dateByAddingTimeInterval:86401];
            localNotification.alertAction = @"View";
            localNotification.alertBody = [dictToday objectForKey:@"saint_description"];
            localNotification.repeatInterval = NSDayCalendarUnit;
            localNotification.timeZone = [NSTimeZone defaultTimeZone];
            localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;

            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
             [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self];

        }

        if ([testValue isEqualToString:@"three"]){
        NSDate *today2 = [[NSDate alloc] init];
        NSCalendar *gregorian = [[NSCalendar alloc]
                                 initWithCalendarIdentifier:NSGregorianCalendar];

        // Get the weekday component of the current date
        NSDateComponents *weekdayComponents = [gregorian components:NSWeekdayCalendarUnit
                                                           fromDate:today2];

        /*
         Create a date components to represent the number of days to subtract from the current date.
         The weekday value for Sunday in the Gregorian calendar is 1, so subtract 1 from the number of days to subtract from the date in question.  (If today is Sunday, subtract 0 days.)
         */
        NSDateComponents *componentsToSubtract = [[NSDateComponents alloc] init];
        [componentsToSubtract setDay: 0 - ([weekdayComponents weekday] - 1)];

        NSDate *beginningOfWeek = [gregorian dateByAddingComponents:componentsToSubtract
                                                             toDate:today2 options:0];

        /*
         Optional step:
         beginningOfWeek now has the same hour, minute, and second as the original date (today).
         To normalize to midnight, extract the year, month, and day components and create a new date from those components.
         */
        NSDateComponents *components =
        [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit |
                               NSDayCalendarUnit) fromDate: beginningOfWeek];
        beginningOfWeek = [gregorian dateFromComponents:components];



            UILocalNotification* localNotification = [[UILocalNotification alloc] init];
            localNotification.fireDate = beginningOfWeek;
            localNotification.alertAction = @"View";
            localNotification.alertBody = [dictToday objectForKey:@"saint_description"];
            localNotification.repeatInterval = NSWeekdayCalendarUnit;
            localNotification.timeZone = [NSTimeZone defaultTimeZone];
            localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;

            [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
            [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self];

        }
    }

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(defaultsChanged:)
                                                 name:NSUserDefaultsDidChangeNotification
                                               object:nil];

    UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (locationNotification) {
        // Set icon badge number to zero
        application.applicationIconBadgeNumber = 0;
    }
return yes;
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{




    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Today Saint"
                                                    message:notification.alertBody
                                                   delegate:self cancelButtonTitle:@"OK"
                                          otherButtonTitles:nil];
    if (notification.alertBody!=Nil)
    [alert show];


     [[NSNotificationCenter defaultCenter] postNotificationName:@"reloadData" object:self];

    // Set icon badge number to zero
    application.applicationIconBadgeNumber = 0;
}

Правильно ли код для запуска уведомлений, как я уже говорил? Если нет, то в чем проблема? Спасибо!

4b9b3361

Ответ 1

Кажется, вы планируете уведомления, когда пользователь меняет настройки. Тем не менее, вы никогда не рассылаете ранее запланированные уведомления, поэтому вы периодически наблюдаете всплески уведомлений, которые будут точно соответствовать временам, когда вы неоднократно меняли настройки день или два дня назад.

Уведомления, которые вы планируете, представляют собой разные объекты, чем набор уведомлений, которые вы собираетесь изменить. К сожалению, UILocalNotifications не имеют токенов идентификатора.

Тем не менее, вы можете отключить все предыдущие уведомления всякий раз, когда вы получаете сообщение defaultsChanged: с [[UIApplication sharedApplication] cancelAllLocalNotifications]; перед переносом. Это решит вашу проблему.

Также внимательно посмотрите на это решение, которое предлагает отменить и перенести уведомления даже после запуска, чтобы избежать всплесков или дубликатов уведомлений, когда пользователь переустанавливает ваше приложение.

Ответ 2

У меня есть две идеи,

Во-первых: какое значение dictToday?

NSDictionary *dictToday= [self getDataFromdate : [compoNents day] month:[compoNents month]];
[dictToday objectForKey:@"saint_description"]

Если это значение равно нулю, ваше уведомление не появится.

Второе: проверьте свой часовой пояс и часовой пояс, который был возвращен:

[NSTimeZone defaultTimeZone]

Вы можете находиться в +3 часовом поясе и настраивать локальное предупреждение на отрицательный часовой пояс, и это никогда не произойдет.