2016-09-26 13 views
0

Я провел много исследований по этому вопросу и написал несколько альтернатив в Objective-C, но ничего не работает. Мой вопрос: возможно ли это в iOS?Ежеквартальный аварийный сигнал самовосстановления для iOS

В частности, я хочу, чтобы пользователь мог установить «часовую перезвон» в верхней части каждого часа, получать уведомление, а затем перезапустить таймер, даже если пользователь не отвечает. Я знаю, что я не могу использовать NSTimer из-за ограничений Apple на таймерах, работающих в фоновом режиме. Я пробовал UILocalNotification и таймер «сторожевого таймера» для перезапуска почасового таймера, если пользователь не отвечает на UILocalNotification. Однако мой код в appdelegate.m, который вызывает сброс почасового таймера, не выполняется, если приложение находится в фоновом режиме, пока пользователь не ответит на UILocalNotification. И таймер «сторожевого таймера» не запускается, когда приложение находится в фоновом режиме.

Пользователь может также установить «куранты» на 15 минут, 30 минут и 45 минут после часа.

Как делают такие приложения, как Sciral HabiTimer? Ниже приведены фрагменты кода.

AppDelegate.m

UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; 
    if (localNotification) { 
     // Set icon badge number to zero 
     application.applicationIconBadgeNumber = 0; 
     HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
     [controller stopTimer]; 
     [controller startTimer]; 
     NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
     NSInteger interval = [storage integerForKey:@"intervalToWatch"]; 
     [controller setLocalNotificationExpirationTime:interval]; 
    } 

    return YES; 
} 

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 
{ 
    UIApplicationState state = [application applicationState]; 
    if (state == UIApplicationStateActive) { 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Reminder" 
                 message:notification.alertBody 
                 delegate:self cancelButtonTitle:@"OK" 
               otherButtonTitles:nil]; 
     [alert show]; 
    } 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    [controller stopTimer]; 
    [controller startTimer]; 

    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
    NSString *received = @"YES"; 
    [storage setObject:received forKey:@"notificationWasReceived"]; 
    [storage synchronize]; 

    NSInteger intervalToWatch = [storage integerForKey:@"intervalToWatch"]; 
    [controller setLocalNotificationExpirationTime:intervalToWatch]; 

    // if a timer was started, stop it. 
    NSTimer *timer = controller.expirationTimer; 
    if(timer){ 
     [timer invalidate];} 

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

- (void)applicationDidEnterBackground:(UIApplication *)application { 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
    NSLog(@"application did enter background"); 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    [controller stopTimer]; 
} 

- (void)applicationWillEnterForeground:(UIApplication *)application { 
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application { 
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    [controller startTimer]; 
} 

- (void)applicationWillTerminate:(UIApplication *)application { 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
} 

@end 

HourlyChimeTableViewController:

-(void)setLocalNotificationExpirationTime:(NSInteger)intervalToWatch{ 
    NSDate *today = [[NSDate alloc] init]; 
    NSLog(@"Today: %@", today); 
    NSCalendar *calendar = [NSCalendar currentCalendar]; 
    NSDateComponents *components= [calendar components:(NSCalendarUnitMinute) | (NSCalendarUnitSecond) fromDate: today]; 
    NSInteger minute = [components minute]; 
    NSInteger second = [components second]; 
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; 

    switch(intervalToWatch){ 
     case 0:{ 
      NSInteger difference; 
      //minute =13; 
      // NSInteger difference = 10; 
      [offsetComponents setHour:0]; 
      [offsetComponents setMinute:0]; 
      if(minute >= 0 && minute < 15){ 
       difference = 900 - minute*60 - second;//seconds left to quarter past 
       NSLog(@"Minute: %ld Second: %ld", (long)minute, (long)second); 
      }else{ 
       if(minute >= 15 && minute < 30){ 
        difference = 1800 - minute*60 - second;// seconds to half past 
        NSLog(@"Minute: %ld Second: %ld", (long)minute, (long)second); 
       }else{ 
        if (minute >= 30 && minute < 45){// seconds to quarter to 
         difference = 2700 - minute*60 - second; 
        }else{// seconds to the hour 
         difference = 3600 - minute*60 - second; 
         NSLog(@"Minute: %ld Second: %ld", (long)minute, (long)second); 
        } 
       } 
      } 
     // difference = 60; 
      [offsetComponents setSecond:difference]; 
      NSDate *fireDate = [calendar dateByAddingComponents:offsetComponents 
                  toDate:today options:0]; 
      self.expirationInterval = difference + 5; 
      UILocalNotification *notification = [self startLocalNotification:fireDate]; 
      self.localNotification = notification; 

      [self startNotificationTimer:self.expirationInterval]; 
      break; 

-(UILocalNotification *)startLocalNotification:(NSDate *)fireDate{ 
    // [[UIApplication sharedApplication] cancelAllLocalNotifications]; 
    UILocalNotification *notification = [[UILocalNotification alloc]init]; 
    notification.fireDate = fireDate; 
    NSLog(@"firedate %@", fireDate); 
    notification.alertBody [email protected]"Timer Expired!"; 
    notification.alertTitle = @"TimeChime Alert"; 
    notification.timeZone = [NSTimeZone defaultTimeZone]; 
    notification.soundName = UILocalNotificationDefaultSoundName; 

    self.notificationWasReceived = @"NO"; 
    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
    [storage setObject:self.notificationWasReceived forKey:@"notificationWasReceived"]; 
    [storage synchronize]; 
    // notification.repeatInterval = NSCalendarUnitMinute; 

    [[UIApplication sharedApplication]scheduleLocalNotification:notification]; 
    return notification; 

} 

-(void)startNotificationTimer:(NSInteger)seconds{ 
    NSTimer *notificationTimer = [NSTimer scheduledTimerWithTimeInterval:seconds target:self selector:@selector(notificationTimerDidExpire:) userInfo:nil repeats:YES]; 
    self.expirationTimer = notificationTimer; 
    NSLog(@"started notification timer for %ld", (long)seconds); 
} 

-(void)notificationTimerDidExpire:(NSTimer *)notification{ 
    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
    self.notificationWasReceived = [storage objectForKey:@"notificationWasReceived"]; 
    NSLog(@"notification timer expired and notificationWasReceived =%@", self.notificationWasReceived); 
    if(self.localNotification) 
    { 
     [[UIApplication sharedApplication]cancelLocalNotification:self.localNotification]; 

     NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
     NSInteger intervalToWatch = [storage integerForKey:@"intervalToWatch"]; 

     // and reschedule the notification. 
     [self setLocalNotificationExpirationTime:intervalToWatch]; 
    } 
} 

Я решил проблему путем планирования несколько повторяющихся уведомлений. Вот код (также добавляет пользовательские действия для iOS8). Обратите внимание, что iOS10 имеет совершенно иной способ планирования локальных уведомлений):

// 
// AppDelegate.m 
// Hourly Chime2 
// 
// Created by Nelson Capes on 9/20/16. 
// Copyright © 2016 Nelson Capes. All rights reserved. 
// 

#import "AppDelegate.h" 
#import <AVFoundation/AVFoundation.h> 
#import "HourlyChimeTableViewController.h" 
@interface AppDelegate() 

@end 

@implementation AppDelegate 


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    // Override point for customization after application launch. 

    NSError *sessionError = nil; 
    NSError *activationError = nil; 
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&sessionError]; 
    [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 

    // ask the user to allow local notifications 
    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){ 

     [application registerUserNotificationSettings:[UIUserNotificationSettings 
                 settingsForTypes:UIUserNotificationTypeAlert categories:nil]]; 
    } 
    UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; 
    if (localNotification) { 
     // Set icon badge number to zero 
     application.applicationIconBadgeNumber = 0; 
     HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
     [controller stopTimer]; 
     [controller startTimer]; 
     [[UIApplication sharedApplication]cancelLocalNotification:localNotification]; 
     NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
     NSInteger intervalToWatch = [storage integerForKey:@"intervalToWatch"]; 
     NSMutableArray *array = [storage objectForKey:@"timerArray"]; 

     // BOOL YES means to schedule a set of local notifications; NO means don't schedule. 
     [controller setLocalNotificationExpirationTime:intervalToWatch : NO]; 



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

    } 
    // define a notification action 
    UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc]init]; 
    acceptAction.identifier [email protected]"ACCEPT_IDENTIFIER"; 
    acceptAction.title = @"Continue"; 
    acceptAction.activationMode = UIUserNotificationActivationModeBackground; 
    acceptAction.destructive = NO; 
    acceptAction.authenticationRequired = NO; 

    UIMutableUserNotificationAction *declineAction = [[UIMutableUserNotificationAction alloc]init]; 
    declineAction.identifier [email protected]"DECLINE_IDENTIFIER"; 
    declineAction.title = @"Stop"; 
    declineAction.activationMode = UIUserNotificationActivationModeBackground; 
    declineAction.destructive = NO; 
    declineAction.authenticationRequired = NO; 

    UIMutableUserNotificationCategory *inviteCategory = [[UIMutableUserNotificationCategory alloc]init]; 
    inviteCategory.identifier = @"INVITE_CATEGORY"; 
    [inviteCategory setActions:@[acceptAction, declineAction] forContext:UIUserNotificationActionContextDefault]; 

    NSSet *categories = [NSSet setWithObjects:inviteCategory, nil]; 
    if([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){ 
     UIUserNotificationSettings *settings = [UIUserNotificationSettings 
               settingsForTypes:UIUserNotificationTypeAlert categories:categories]; 
     [[UIApplication sharedApplication]registerUserNotificationSettings:settings]; 
    } 

    return YES; 
} 

// determine whether the user will allow local notifications. 
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings;{ 

    if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)]){ // Check it's iOS 8 and above 
     NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
     UIUserNotificationSettings *grantedSettings = [[UIApplication sharedApplication] currentUserNotificationSettings]; 

     if (grantedSettings.types == UIUserNotificationTypeNone) { 
      NSLog(@"No permission granted"); 
      [storage setBool:NO forKey:@"permission granted"]; 
     } 
     else if (grantedSettings.types & UIUserNotificationTypeSound & UIUserNotificationTypeAlert){ 
      NSLog(@"Sound and alert permissions "); 
      [storage setBool:YES forKey:@"permission granted"]; 
      [storage setBool:YES forKey:@"sound permission granted"]; 
      [storage setBool:YES forKey:@"alert permission granted"]; 
     } 
     else if (grantedSettings.types & UIUserNotificationTypeAlert){ 
      NSLog(@"Alert Permission Granted"); 
      [storage setBool:YES forKey:@"permission granted"]; 
      [storage setBool:YES forKey:@"alert permission granted"]; 
      [storage setBool:NO forKey:@"sound permission granted"]; 
     } 
     [storage synchronize]; 
    } 

} 
-(void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forLocalNotification:(nonnull UILocalNotification *)notification completionHandler:(nonnull void (^)())completionHandler{ 
    if ([identifier isEqualToString:@"ACCEPT_IDENTIFIER"]){ 
     [self handleAcceptActionWithNotification:notification]; 
    }else{ 
     if ([identifier isEqualToString:@"DECLINE_IDENTIFIER"]){ 
      [self handleDeclineActionWithNotification:notification]; 
     } 
    } 
    completionHandler(); 
} 
-(void)handleAcceptActionWithNotification:notification{ 
    NSLog(@"accept action received"); 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    [controller stopTimer]; 
    [controller startTimer]; 
    [[UIApplication sharedApplication]cancelLocalNotification:notification]; 
    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
    NSInteger intervalToWatch = [storage integerForKey:@"intervalToWatch"]; 
    // BOOL YES means to schedule a set of local notifications; NO means don't schedule. 
    [controller setLocalNotificationExpirationTime:intervalToWatch : NO]; 
} 
-(void)handleDeclineActionWithNotification:notification{ 
    NSLog(@"decline Action received"); 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    [controller stopTimer]; 

} 
- (void)applicationWillResignActive:(UIApplication *)application { 
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 
} 

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification 
{ 
    UIApplicationState state = [application applicationState]; 
    if (state == UIApplicationStateActive) { 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Reminder" 
                 message:notification.alertBody 
                 delegate:self cancelButtonTitle:@"OK" 
               otherButtonTitles:nil]; 
     [alert show]; 
    } 
    // [[UIApplication sharedApplication]cancelAllLocalNotifications]; 
    NSLog(@"app delegate: notification received"); 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    [controller stopTimer]; 
    [controller startTimer]; 

    [[UIApplication sharedApplication]cancelLocalNotification:notification]; 
    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
    NSInteger intervalToWatch = [storage integerForKey:@"intervalToWatch"]; 
    // NSMutableArray *array = [storage objectForKey:@"timerArray"]; 

    // BOOL YES means to schedule a set of local notifications; NO means don't schedule. 
    [controller setLocalNotificationExpirationTime:intervalToWatch : NO]; 



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

- (void)applicationDidEnterBackground:(UIApplication *)application { 
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
    NSLog(@"application did enter background"); 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    // [controller stopTimer]; 
} 


- (void)applicationWillEnterForeground:(UIApplication *)application { 
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 
    NSLog(@"application did enter foreground"); 
} 


- (void)applicationDidBecomeActive:(UIApplication *)application { 
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.a 
    NSLog(@"app delegate: applicationDidBecomeActive"); 
    HourlyChimeTableViewController *controller = [[HourlyChimeTableViewController alloc]init]; 
    [controller startTimer]; 
    if ([[UIApplication sharedApplication] respondsToSelector:@selector(currentUserNotificationSettings)]){ // Check it's iOS 8 and above 
     UIUserNotificationSettings *grantedSettings = [[UIApplication sharedApplication] currentUserNotificationSettings]; 

     if (grantedSettings.types == UIUserNotificationTypeNone) { 
      NSLog(@"No permission granted"); 
      UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"You have not granted permission for Alerts" 
                  message:@"We can't let you know when a timer expires" 
                  delegate:self cancelButtonTitle:@"OK" 
                otherButtonTitles:nil]; 
      [alert show]; 
     } 
     else if (grantedSettings.types & UIUserNotificationTypeSound & UIUserNotificationTypeAlert){ 
      NSLog(@"Sound and alert permissions "); 
     } 
     else if (grantedSettings.types & UIUserNotificationTypeAlert){ 
      NSLog(@"Alert Permission Granted"); 
     }else{ 
      NSLog(@"No permissions "); 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"You have not granted permission for Alerts" 
                 message:@"We can't let you know when a timer expires" 
                 delegate:self cancelButtonTitle:@"OK" 
               otherButtonTitles:nil]; 
     [alert show]; 
     } 
    } 

} 
- (void)applicationWillTerminate:(UIApplication *)application { 
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 
} 


@end 

Следующий код показывает, как планировать локальное оповещение:

-(void)setLocalNotificationExpirationTime:(NSInteger)intervalToWatch :(BOOL)option{ 

    // BOOL YES means to schedule a set of local notifications; NO means don't schedule. 

    NSDate *today = [[NSDate alloc] init]; 
    NSLog(@"Today: %@", today); 
    NSCalendar *calendar = [NSCalendar currentCalendar]; 
    NSDateComponents *components= [calendar components:(NSCalendarUnitMinute) | (NSCalendarUnitSecond) fromDate: today]; 
    NSInteger minute = [components minute]; 
    NSInteger second = [components second]; 
    NSDateComponents *offsetComponents = [[NSDateComponents alloc] init]; 

    // intervalToWatch is an NSInteger set by the UI to determine what kind of notification to set. 
    // 1 = every 15 minutes; 2 = every half hour; 3 = every hour. 
    // we calculate the seconds left until the next interval, then schedule a local notification with the seconds left. 
    switch(intervalToWatch){ 
     case 0:{// notification every 15 minutes 
      NSInteger difference; 
      [offsetComponents setHour:0]; 
      [offsetComponents setMinute:0]; 
      if(minute >= 0 && minute < 15){ 
       difference = 900 - minute*60 - second;//seconds left to quarter past 
       // NSLog(@"Minute: %ld Second: %ld", (long)minute, (long)second); 
      }else{ 
       if(minute >= 15 && minute < 30){ 
        difference = 1800 - minute*60 - second;// seconds to half past 
        // NSLog(@"Minute: %ld Second: %ld", (long)minute, (long)second); 
       }else{ 
        if (minute >= 30 && minute < 45){// seconds to quarter to 
         difference = 2700 - minute*60 - second; 
        }else{// seconds to the hour 
         difference = 3600 - minute*60 - second; 
         // NSLog(@"Minute: %ld Second: %ld", (long)minute, (long)second); 
        } 
       } 
      } 
       // schedule repeating local notifications every 15 minutes. 
       if(option == YES){ 
        [offsetComponents setSecond:difference]; 

        NSDate *fireDate = [calendar dateByAddingComponents:offsetComponents 
                   toDate:today options:0]; 

        UILocalNotification *notification = [self startLocalNotification:fireDate]; 
        self.localNotification = notification;// at the next 15 minute interval. 


        [offsetComponents setSecond:difference + 900]; 
        fireDate = [calendar dateByAddingComponents:offsetComponents 
                 toDate:today options:0]; 

        UILocalNotification *notification1 = [self startLocalNotification:fireDate];// at next 30 minutes 
        [self.timerArray addObject:notification1]; 

        [offsetComponents setSecond:difference + 1800]; 
        fireDate = [calendar dateByAddingComponents:offsetComponents 
                 toDate:today options:0]; 

        UILocalNotification *notification2 = [self startLocalNotification:fireDate];// at next 45 minutes 
        [self.timerArray addObject:notification2]; 

        [offsetComponents setSecond:difference + 2700]; 
        fireDate = [calendar dateByAddingComponents:offsetComponents 
                 toDate:today options:0]; 

        UILocalNotification *notification3 = [self startLocalNotification:fireDate];// at next hour 
        [self.timerArray addObject:notification3]; 

       } 
      } 
      break; 

     case 1:{// notification every 30 minutes at half past the hour. 
      NSInteger difference; 
      [offsetComponents setHour:0]; 
      [offsetComponents setMinute:0]; 
      if(minute >= 0 && minute < 30){ 
       difference = 1800 - minute*60 - second;// seconds to half past 
      }else{ 
       difference = 3600 - minute*60 - second;// seconds to the hour 
      } 
      if(option == YES){ 
       [offsetComponents setSecond:difference]; 

       NSDate *fireDate = [calendar dateByAddingComponents:offsetComponents 
                  toDate:today options:0]; 

       UILocalNotification *notification = [self startLocalNotification:fireDate]; 
       self.localNotification = notification;// at the next 30 minute interval. 


       [offsetComponents setSecond:difference + 1800]; 
       fireDate = [calendar dateByAddingComponents:offsetComponents 
                toDate:today options:0]; 
       UILocalNotification *notification2 = [self startLocalNotification:fireDate];// at next 45 minutes 
       [self.timerArray addObject:notification2]; 
      } 
      break; 
     } 
     case 2:{// notification every hour on the hour 
      minute = 58; 
      NSInteger difference = 3600 - minute*60 - second; 
      if(option == YES){ 
       [offsetComponents setSecond:difference]; 

       NSDate *fireDate = [calendar dateByAddingComponents:offsetComponents 
                  toDate:today options:0]; 

       UILocalNotification *notification = [self startLocalNotification:fireDate]; 
       self.localNotification = notification;// at the next 60 minute interval. 
      } 
      break; 
     } 

     } 


    } 

-(UILocalNotification *)startLocalNotification:(NSDate *)fireDate{ 

    // [[UIApplication sharedApplication] cancelAllLocalNotifications]; 

    UILocalNotification *notification = [[UILocalNotification alloc]init]; 
    NSUserDefaults *storage = [NSUserDefaults standardUserDefaults]; 
    notification.fireDate = fireDate; 
    NSLog(@"firedate %@", fireDate); 
    notification.alertBody [email protected]"Timer Expired!"; 
    notification.alertTitle = @"TimeChime Alert"; 
    notification.timeZone = [NSTimeZone defaultTimeZone]; 
    BOOL sound = [storage boolForKey:@"sound permission granted"]; 
    if(sound){ 
     notification.soundName = UILocalNotificationDefaultSoundName;} 
    notification.repeatInterval = NSCalendarUnitHour; 
    notification.category = @"INVITE_CATEGORY"; 

    [[UIApplication sharedApplication]scheduleLocalNotification:notification]; 

    return notification; 

} 
+1

Рассчитайте свое первое время огня, как сейчас, и укажите 'repeatInterval'' NSCalendarUnitHour' – Paulw11

+0

Вы пытались установить некоторые скрытые события в календаре? – PnotNP

ответ

0

После долгих испытаний, мой ответ на мой собственный вопрос «это невозможно». Когда приложение начинает ждать локального уведомления, оно блокируется. Невозможно написать несколько многопоточных кодов (которые я никогда не делал), чтобы что-либо сделать, но дать ответ пользователю (т. Е. Ни один сторожевой таймер не будет отключен, пока приложение заблокировано, например, когда оно находится в фоновом режиме).

Я нашел, однако, способ решить свою проблему, которую я отредактировал для публикации.

+0

Примечание: я редактировал свое оригинальное сообщение, чтобы показать решение. –

Смежные вопросы