显示基于 UNUserNotification iOS 的 UIAlertAction 未按预期工作
Showing a UIAlertAction based on UNUserNotification iOS not working as expected
我已经在这几个小时了,据说我的一切都按照它应该的方式运行,但是当通知在应用程序中消失时它没有调用我的 userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))
方法,什么也没有发生。
当不在应用程序中时,应用程序会按预期提供通知,但在应用程序中时什么也不会。
这是我的代码,如果你看到我做错了什么,请告诉我。
Class NotificationDelegate.h:
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>
@interface NotificationDelegate : UNUserNotificationCenter <UNUserNotificationCenterDelegate>
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler;
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler;
@end
NotificationDelegate.m:
#import "NotificationDelegate.h"
@implementation NotificationDelegate
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
[self sendMessage:[UIApplication sharedApplication] message:notification.request.content];
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
- (void) sendMessage:(UIApplication *)application message:(UNNotificationContent *)content{
UIAlertController *ac = [UIAlertController alertControllerWithTitle:content.title
message:content.body
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"Go Away!" style:UIAlertActionStyleDefault handler:nil];
[ac addAction:action];
dispatch_async(dispatch_get_main_queue(), ^{
[application.keyWindow.rootViewController presentViewController:ac animated:YES completion:nil];
});
}
//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
}
@end
AppDelegate.h:
#import <UIKit/UIKit.h>
#import "NotificationDelegate.h"
@import UserNotifications;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UNUserNotificationCenter *center;
@property (strong, nonatomic) NotificationDelegate *ncdel;
@property (strong, nonatomic) UIWindow *window;
@end
AppDelegate.m:
#import "AppDelegate.h"
@import UserNotifications;
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.center = [UNUserNotificationCenter currentNotificationCenter];
self.center.delegate = self.ncdel;
return YES;
}
ViewController.m:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.pvHelper = [[PickerViewHelperViewController alloc] init];
self.pickerView.dataSource = self.pvHelper;
self.pickerView.delegate = self.pvHelper;
self.pvHelper.answer = [NSNumber numberWithInteger:10];
}
- (void) requestPermission{
UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge;
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:options
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
NSLog(@"Something went wrong");
}
}];
}
- (void) createNotification:(NSNumber *)time{
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:@"Alarming, isn't it?" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"Listen to me my love" arguments:nil];
content.sound = [UNNotificationSound defaultSound];
content.badge = [NSNumber numberWithInteger:99];
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:[time integerValue]
repeats:NO];
//Note: Calling addNotificationRequest with the same identifier string will replace the existing notification. If you want to schedule multiple requests use a different identifier each time.
NSString *identifier = @"Alarm Triggered";
UNNotificationRequest *req = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:req withCompletionHandler:^(NSError * _Nullable error) {
if(error != nil){
NSLog(@"Something went wrong: %@", error);
}
else{
NSLog(@"I have requested the Notification be made");
}
}];
}
- (IBAction)buttonTappedSetAlarm:(id)sender {
[self requestPermission];
[self createNotification: [[self pvHelper] answer]];
}
这无关紧要,但我的单视图应用程序只有一个 10、20、30...60 秒、分钟、小时的选择器,我计算得到请求的时间.
所以就像我说的那样,请求在应用程序之外按预期工作,但是在前台的应用程序中,没有任何反应,这真的让我很困扰。
如有任何帮助,我们将不胜感激。
我知道怎么做了。
我放弃了在另一个 class 中实现 UNUserNotificationCenterDelegate
的尝试,只是在我的视图控制器中实现了它:
#import <UIKit/UIKit.h>
#import "PickerViewHelperViewController.h"
@import UserNotifications;
@interface ViewController : UIViewController <UNUserNotificationCenterDelegate>
@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
@property (strong, nonatomic) PickerViewHelperViewController *pvHelper;
// Two methods needed to implement from the UNUserNotificationCenterDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler;
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler;
@end
然后在我的 .m 文件中添加了随附代码以显示本地通知。
- (void) sendMessage:(UIApplication *)application title:(NSString *)title message:(NSString *)message{
UIAlertController *ac = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"Go Away!" style:UIAlertActionStyleDefault handler:nil];
[ac addAction:action];
dispatch_async(dispatch_get_main_queue(), ^{
[application.keyWindow.rootViewController presentViewController:ac animated:YES completion:^{
application.applicationIconBadgeNumber = 0;
}];
});
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
[self sendMessage:[UIApplication sharedApplication] title:@"local notification within App" message:notification.request.content.body];
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionBadge);
}
//Called when a notification is delivered to a background app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
[self sendMessage:[UIApplication sharedApplication]
title:@"I habe been opened from outside the App"
message:response.notification.request.content.body];
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
我上面的创建通知和请求权限的方法在代码中保持不变。
这允许在应用程序中显示本地通知,并允许在通过通知打开应用程序时显示通知。
我已经在这几个小时了,据说我的一切都按照它应该的方式运行,但是当通知在应用程序中消失时它没有调用我的 userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))
方法,什么也没有发生。
当不在应用程序中时,应用程序会按预期提供通知,但在应用程序中时什么也不会。
这是我的代码,如果你看到我做错了什么,请告诉我。
Class NotificationDelegate.h:
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>
@interface NotificationDelegate : UNUserNotificationCenter <UNUserNotificationCenterDelegate>
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler;
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler;
@end
NotificationDelegate.m:
#import "NotificationDelegate.h"
@implementation NotificationDelegate
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
[self sendMessage:[UIApplication sharedApplication] message:notification.request.content];
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
- (void) sendMessage:(UIApplication *)application message:(UNNotificationContent *)content{
UIAlertController *ac = [UIAlertController alertControllerWithTitle:content.title
message:content.body
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"Go Away!" style:UIAlertActionStyleDefault handler:nil];
[ac addAction:action];
dispatch_async(dispatch_get_main_queue(), ^{
[application.keyWindow.rootViewController presentViewController:ac animated:YES completion:nil];
});
}
//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
}
@end
AppDelegate.h:
#import <UIKit/UIKit.h>
#import "NotificationDelegate.h"
@import UserNotifications;
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UNUserNotificationCenter *center;
@property (strong, nonatomic) NotificationDelegate *ncdel;
@property (strong, nonatomic) UIWindow *window;
@end
AppDelegate.m:
#import "AppDelegate.h"
@import UserNotifications;
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.center = [UNUserNotificationCenter currentNotificationCenter];
self.center.delegate = self.ncdel;
return YES;
}
ViewController.m:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.pvHelper = [[PickerViewHelperViewController alloc] init];
self.pickerView.dataSource = self.pvHelper;
self.pickerView.delegate = self.pvHelper;
self.pvHelper.answer = [NSNumber numberWithInteger:10];
}
- (void) requestPermission{
UNAuthorizationOptions options = UNAuthorizationOptionAlert + UNAuthorizationOptionSound + UNAuthorizationOptionBadge;
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:options
completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (!granted) {
NSLog(@"Something went wrong");
}
}];
}
- (void) createNotification:(NSNumber *)time{
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:@"Alarming, isn't it?" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:@"Listen to me my love" arguments:nil];
content.sound = [UNNotificationSound defaultSound];
content.badge = [NSNumber numberWithInteger:99];
UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:[time integerValue]
repeats:NO];
//Note: Calling addNotificationRequest with the same identifier string will replace the existing notification. If you want to schedule multiple requests use a different identifier each time.
NSString *identifier = @"Alarm Triggered";
UNNotificationRequest *req = [UNNotificationRequest requestWithIdentifier:identifier content:content trigger:trigger];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:req withCompletionHandler:^(NSError * _Nullable error) {
if(error != nil){
NSLog(@"Something went wrong: %@", error);
}
else{
NSLog(@"I have requested the Notification be made");
}
}];
}
- (IBAction)buttonTappedSetAlarm:(id)sender {
[self requestPermission];
[self createNotification: [[self pvHelper] answer]];
}
这无关紧要,但我的单视图应用程序只有一个 10、20、30...60 秒、分钟、小时的选择器,我计算得到请求的时间.
所以就像我说的那样,请求在应用程序之外按预期工作,但是在前台的应用程序中,没有任何反应,这真的让我很困扰。
如有任何帮助,我们将不胜感激。
我知道怎么做了。
我放弃了在另一个 class 中实现 UNUserNotificationCenterDelegate
的尝试,只是在我的视图控制器中实现了它:
#import <UIKit/UIKit.h>
#import "PickerViewHelperViewController.h"
@import UserNotifications;
@interface ViewController : UIViewController <UNUserNotificationCenterDelegate>
@property (weak, nonatomic) IBOutlet UIPickerView *pickerView;
@property (strong, nonatomic) PickerViewHelperViewController *pvHelper;
// Two methods needed to implement from the UNUserNotificationCenterDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler;
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)())completionHandler;
@end
然后在我的 .m 文件中添加了随附代码以显示本地通知。
- (void) sendMessage:(UIApplication *)application title:(NSString *)title message:(NSString *)message{
UIAlertController *ac = [UIAlertController alertControllerWithTitle:title
message:message
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"Go Away!" style:UIAlertActionStyleDefault handler:nil];
[ac addAction:action];
dispatch_async(dispatch_get_main_queue(), ^{
[application.keyWindow.rootViewController presentViewController:ac animated:YES completion:^{
application.applicationIconBadgeNumber = 0;
}];
});
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
[self sendMessage:[UIApplication sharedApplication] title:@"local notification within App" message:notification.request.content.body];
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionBadge);
}
//Called when a notification is delivered to a background app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
[self sendMessage:[UIApplication sharedApplication]
title:@"I habe been opened from outside the App"
message:response.notification.request.content.body];
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
我上面的创建通知和请求权限的方法在代码中保持不变。
这允许在应用程序中显示本地通知,并允许在通过通知打开应用程序时显示通知。