首页 文章

UNNotification本地通知用户点击不会在后台iOS 11中的应用程序时触发委托

提问于
浏览
0

我有一个应用程序,通过UNNotification本地通知每隔x分钟提醒用户 . 如果用户没有响应,则iOS锁定屏幕会显示一系列要求用户响应的 Banner . 大多数情况下,当应用程序处于后台时,用户点击 Banner (点按“主页”按钮后)会触发UNNotification中心代表 . 但是, occasionally a user tap on the latest banner does NOT trigger the delegat e . 注意:这不是关于代表没有接到电话而没有用户点击的问题:我知道这不能做到 . 当用户点击 Banner 中的操作按钮时,为什么iOS不会偶尔触发应用委托?注意:我会跟踪待处理的本地通知的数量,并且永远不会超过系统限制64 .

应用代表:

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

    UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
                      completionHandler:^(BOOL granted, NSError * _Nullable error) {
                          // Enable or disable features based on authorization.
                          NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
                          if(granted == YES){
                              [storage setBool:YES forKey:@"permission granted"];
                              [storage setBool:YES forKey:@"alert permission granted"];
                              [storage setBool:YES forKey:@"sound permission granted"];
                          }else{
                              NSLog(@"No permission granted");
                              [storage setBool:NO forKey:@"permission granted"];
                          };
                      }];
}

    #pragma mark UNNotificationCenter setup

    UNNotificationAction *acceptAction = [UNNotificationAction actionWithIdentifier:@"ACCEPT_IDENTIFIER" title:NSLocalizedString(@"Continue notifications", nil) options:UNNotificationActionOptionAuthenticationRequired];
    UNNotificationAction *declineAction = [UNNotificationAction actionWithIdentifier:@"DECLINE_IDENTIFIER" title:NSLocalizedString(@"Stop notifications", nil) options:UNNotificationActionOptionAuthenticationRequired];
    UNNotificationAction *doNotDisturbAction = [UNNotificationAction actionWithIdentifier:@"DO_NOT_DISTURB_IDENTIFIER" title:NSLocalizedString(@"Start Do Not Disturb", nil) options:UNNotificationActionOptionAuthenticationRequired];
    NSArray *actions = [NSArray arrayWithObjects:acceptAction, declineAction, doNotDisturbAction, nil];
   // NSArray *intentIdentifiers = [NSArray arrayWithObjects:@"none", nil];
    UNNotificationCategory *invite = [UNNotificationCategory categoryWithIdentifier:@"com.nelsoncapes.localNotification" actions:actions intentIdentifiers: @[] options:UNNotificationCategoryOptionNone];
    NSSet *categories = [NSSet setWithObjects:invite, nil];
    [center setNotificationCategories:categories];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound)
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
                              // Enable or disable features based on authorization.
                          }];

    #pragma mark UNNotification received in background
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
    [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
        NSLog(@"notification settings were changed");
        NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
        [storage setBool:YES forKey:KEventLoggerEventNotificationSettingsChanged];
        [storage synchronize];

        if (settings.authorizationStatus != UNAuthorizationStatusAuthorized) {
            // Notifications not allowed
            NSLog(@"notification settings were changed");
            item.eventDescription = KEventLoggerEventNotificationsNotAllowed;

            // check settings for alert and sound
        }
       // UNNotificationSetting alertSetting = settings.alertSetting;
            if(settings.alertSetting == UNNotificationSettingEnabled){
                [storage setBool:YES forKey:@"alert permission granted"];
                item.eventDescription = KEventLoggerEventAlertsAreAllowed;
            }else{[storage setBool:NO forKey:@"alert permission granted"];
                item.eventDescription = KEventLoggerEventAlertsAreNotAllowed;
            }
            if (settings.soundSetting == UNNotificationSettingEnabled){
                [storage setBool:YES forKey:@"sound permission granted"];
                item.eventDescription = KEventLoggerEventSoundsAreAllowed;
            }else {[storage setBool:NO forKey:@"sound permission granted"];
                item.eventDescription = KEventLoggerEventSoundsAreNotAllowed;
            }

    }];
    NSLog(@"appdelegate - center didReceiveNotificationResponse");


    UNNotification *notification = response.notification;
    if([actionIdentifier isEqual:@"com.apple.UNNotificationDefaultActionIdentifier"] || [actionIdentifier isEqual:@"com.apple.UNNotificationDismissActionIdentifier"]){
    }else{


        BOOL accept = [actionIdentifier isEqual:@"ACCEPT_IDENTIFIER"];
        BOOL stop = [actionIdentifier isEqual:@"DECLINE_IDENTIFIER"];
        BOOL doNotDisturb = [actionIdentifier isEqual:@"DO_NOT_DISTURB_IDENTIFIER"];

        if (accept){NSLog(@"accept");
            [self handleAcceptActionWithNotification:notification];
        }
        else if (stop){NSLog(@"stop");
            [self handleDeclineActionWithNotification:notification];
        }
        else if(doNotDisturb) {NSLog(@"do not disturb");
            [self handleDoNotDisturbActionWithNotification:notification];
        };
    }

查看控制器:

-(UNNotificationRequest *)triggerNotifications: (NSString *)identifier : (NSTimeInterval) interval{
// Note: identifier must be unique or else each new request causes all others to be cancelled.
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = NSLocalizedString(@"Timer expired", nil);
content.body = NSLocalizedString(@"Touch to continue", nil);
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
BOOL sound = [storage boolForKey:@"sound permission granted"];
if(sound){
    if([self.selectedSound isEqual:NSLocalizedString(kselectedSoundKeyDoorBell, nil)]){
        content.sound = [UNNotificationSound soundNamed:@"doorbell.caf"];
    }else if ([self.selectedSound isEqual:NSLocalizedString(kselectedSoundKeySystemDefault, nil)]){
        content.sound = [UNNotificationSound defaultSound];
    }else if ([self.selectedSound isEqual:NSLocalizedString(kselectedSoundKeyElectronicChime, nil)]){
        content.sound = [UNNotificationSound soundNamed:@"electronic_chime.caf"];
    }else{
        if([self.selectedSound isEqual:NSLocalizedString(kselectedSoundKeyComputer, nil)]){
            content.sound = [UNNotificationSound soundNamed:@"Computer.caf"];
        }
    }
}
content.categoryIdentifier = @"com.nelsoncapes.localNotification";
NSDate *today = [NSDate date];
NSDate *fireDate = [today dateByAddingTimeInterval:interval];
// first extract the various components of the date
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger year = [calendar component:NSCalendarUnitYear fromDate:fireDate];
NSInteger month = [calendar component:NSCalendarUnitMonth fromDate:fireDate];
NSInteger day = [calendar component:NSCalendarUnitDay fromDate:fireDate];
NSInteger hour = [calendar component:NSCalendarUnitHour fromDate:fireDate];
NSInteger minute = [calendar component:NSCalendarUnitMinute fromDate:fireDate];
NSDateComponents *components = [[NSDateComponents alloc]init];
components.year = year;
components.month = month;
components.day = day;
components.hour = hour;
components.minute = minute;

// construct a calendarnotification trigger and add it to the system
UNCalendarNotificationTrigger *trigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:components repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier: identifier content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError *error){
    if(error){
    NSLog(@"error on trigger notification %@", error);
    }
}];
}

1 回答

  • 0

    我相信我发现了问题(它在我的代码中) . 我用相同的日期组件调用了triggerNotification两次(我只对分钟粒度感兴趣,因为我用它在第x分钟触发警报) . 第一个调用是用户按下开始按钮,第二个调用是在app delegate中调用applicationDidBecomeActive时 . 事实上,我确实在我的表中看到了重复的通知 . 我认为,但无法证明,当系统有两个UNNotificationRequests等待同一日期组件时,它只响应一个相应的警报标语 . 因此,当我点击最新的 Banner 时,代表没有被调用 . 我删除了第二个触发器,问题似乎得到解决(即,点击 Banner 中的按钮会导致对我的代理人的调用) . 注意:即使我为相同的日期组件触发了两次通知,我也确实在每个请求中提供了一个唯一标识符 .

相关问题