2013-10-31 13 views
13

Próbuję użyć pakietu ustawień, aby zaplanować UILocalNotification. W ustawieniach możesz wybrać, czy powiadomienia mają przychodzić codziennie (1/dzień), 1 co 2 dni, tylko w niedziele czy nigdy.Uruchamianie systemu iOS jest uruchamiane raz dziennie, raz na dwa dni i tylko w niedziele

Oto kod użyłem (to wszystko w 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's 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; 
} 

Czy poprawny kod do uruchomienia powiadomienia jak już zaznaczono? Jeśli nie, to w czym jest problem? Dzięki!

Odpowiedz

6

Wygląda na to, że planujesz powiadomienia, gdy tylko użytkownik zmieni preferencje. Nigdy jednak nie masz zaplanowanych powiadomień , dlatego w tym czasie obserwuje się serie powiadomień, które odpowiadają dokładnie czasom, w których wielokrotnie zmieniałeś ustawienia dzień lub dwa dni temu.

Zaplanowane powiadomienia są innymi obiektami niż zestaw powiadomień, które mają zostać zmodyfikowane. Niestety, UILocalNotifications nie ma żadnych tokenów identyfikatora.

Można jednak unschedule wszystkie wcześniejsze powiadomienia, gdy pojawi się komunikat defaultsChanged: z ty [[UIApplication sharedApplication] cancelAllLocalNotifications];przed przełożyć. To rozwiąże twój problem.

Zapoznaj się również z informacjami na stronie this solution, które sugerują anulowanie i zmianę harmonogramu powiadomień nawet po uruchomieniu, aby uniknąć wybuchów lub duplikowania powiadomień, gdy użytkownik ponownie zainstaluje aplikację.

+0

Dzięki, już korzystałem z metody cancelAllLocalNotifications, ale nie wiem dlaczego, zapomniałem wkleić ją tutaj. Chodzi o to, że teraz nie wystrzeliwują, kiedy powinny. Na przykład, jeśli używam localNotification.fireDate = [[NSDate date] dateByAddingTimeInterval: 20]; i localNotification.repeatInterval = NSDayCalendarUnit; będzie codziennie uruchamiać powiadomienia w czasie 20 sekund od teraz? –

+0

Może używasz go w niewłaściwym miejscu? "cancelAllLocalNotifications" powinno być pierwszą rzeczą, którą robisz w metodzie wklejanej. –

+0

Zaktualizowałem kod. Ale powiadomienia nie są uruchamiane, kiedy powinny. jakieś pomysły? –

2

Mam dwa pomysły,

pierwsze: co to jest wartość dictToday?

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

Jeśli ta wartość jest zerowa, powiadomienie nie zostanie wyświetlone.

drugie: Sprawdź strefę czasową i strefę czasową wrócił z:

[NSTimeZone defaultTimeZone] 

Można być na +3 strefy czasowej i ustawiania localnotification ognia na negatywnej strefy czasowej i że nigdy nie będzie zdarzyć.