我已经搜索了很多,试图找到解决这个问题的具体方法。我有一个使用以前的UILocalNotification系统发送本地通知的应用程序,这在iOS 10.3.3下仍然可以正常工作。但是,我尝试将其转换为新的UNNotification系统,因为前一个系统已被弃用。无论我是否尝试使用UNCalendarNotificationTrigger或UNTimeIntervalNotificationTrigger,代理都不会接收呼叫。这是触发viewcontroller的代码。
if (isItTime){
NSCalendar *currentCalendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
[currentCalendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *components = [currentCalendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitTimeZone fromDate:[now dateByAddingTimeInterval:30]];
// components.second = 0;
NSLog(@"trigger components: %@", components);
UNCalendarNotificationTrigger* trigger = [UNCalendarNotificationTrigger
triggerWithDateMatchingComponents:components repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"invite" content:content trigger:trigger];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error != nil) {
NSLog(@"Something went wrong: %@",error);
}
}];
[self.currentLocalNotificationRequests addObject:request];
return request;
}else{
return nil;
}
以下是委托代码(appdelegate)didFinishLaunching:
- (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.
NSLog(@"_prefix:set($class $method $line)");
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"];
};
}];
appdelegate获取通知的代码:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
NSLog(@"appdelegate - center didReceiveNotificationResponse");
NSString *actionIdentifier = response.actionIdentifier;
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];
};
}
completionHandler();
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"appdelegate willPresentNotification");
UNNotificationRequest * request = notification.request;
NSString * actionIdentifier = request.identifier;
if([actionIdentifier isEqualToString:UNNotificationDismissActionIdentifier] || [actionIdentifier isEqualToString:UNNotificationDefaultActionIdentifier]){
}else{
if([actionIdentifier isEqualToString:@"invite"]){
NSLog(@"app delegate notification received while in foreground");
}
}
completionHandler(UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound);
}
这是触发代码的NSLog:
<NSDateComponents: 0x146d51c0>
TimeZone: America/Chicago (CDT) offset -18000 (Daylight)
Calendar Year: 2017
Month: 10
Leap month: no
Day: 29
Hour: 14
Minute: 3
Second: 4
很明显系统没有调用appdelegate方法(我确实在通知时间之前将应用程序放在后台,因此应该调用didReceiveNotification方法。
如果有人可以提供帮助,我将不胜感激!
此外,viewDidLoad中的此代码:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(receiveNotificationFromAppDelegate:)
name:kAppDelegateNotification
object:nil];
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(applicationBecameActive) name:UIApplicationDidBecomeActiveNotification object:nil];
self.currentLocalNotificationRequests = [[NSMutableArray alloc]init];
/*
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(checkDndIndicator) name:UIApplicationDidBecomeActiveNotification object:nil];
*/
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.
NSLog(@"request granted");
}];
启动触发过程的代码:
-(UNNotificationRequest *)startLocalNotification:(NSDate *)fireDate :
(NSMutableDictionary *)userInfo{
NSUserDefaults *storage = [NSUserDefaults standardUserDefaults];
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center removeAllPendingNotificationRequests];
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = NSLocalizedString(@"TimeChime Alert", nil);
content.body = NSLocalizedString(@"Click to Stop or Change Timer",nil);
content.categoryIdentifier = @"com.nelsoncapes.localNotification";
答案 0 :(得分:0)
事实证明,这个问题很难解决但修复很容易。不幸的是,我没有仔细遵循第一条编码规则:RTFD。
Apple的UNNotificationRequest文档&gt;标识符状态:
&#34;如果您在安排新通知时使用相同的标识符,系统会删除先前已使用该标识符安排的通知,并将其替换为新标识。&#34;
我的代码为每个UNNotificationRequest使用相同的标识符。虽然每个请求的日历通知日期不同,但系统仅保留最新日期请求。在我的情况下,触发器将在1小时后发射,我预计它会在15分钟后发射。这就是为什么我从未在设备上看过通知以及为什么我从未在委托的didReceiveNotificationResponse方法中看到断点。
修复非常简单。只需在以下代码中提供唯一标识符即可。之后,代码可以运行。
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"invite" content:content trigger:trigger];
替换@&#34;邀请&#34;每个请求都有唯一的标识符。
答案 1 :(得分:0)
我没有收到通知,因为我没有指定传递给我的 UNCalendarNotificationTrigger 所需的日期组件。
这不起作用:
NSDateComponents *dateComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour) fromDate:[[NSDate date] dateByAddingTimeInterval:5]];
这有效:
NSDateComponents *dateComponents = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitNanosecond) fromDate:[[NSDate date] dateByAddingTimeInterval:5]];