ios - 显示基于 UNUserNotification iOS 的 UIAlertAction 未按预期工作

标签 ios objective-c ios10

我已经在这里工作了几个小时,据说我的一切都按预期运行,但它没有调用我的 userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)通知 withCompletionHandler:(void (^)(UNNotificationPresentationOptions options)) 方法当通知在应用程序内关闭时,什么也没有发生。

应用程序不在应用程序中时会按预期发出通知,但在应用程序中时则不会发出任何通知。

这是我的代码,如果您发现我做错了什么,请告诉我。

类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]];
}

这无关紧要,但我的单 View 应用程序只有 10、20、30...60 秒、分钟、小时的选择器,我计算得出请求的时间。

就像我说的,请求在应用程序之外按预期工作,但是当应用程序位于前台时,什么也没有发生,这真的让我很困扰。

任何帮助将不胜感激。

最佳答案

我知道怎么做了。

我放弃了在另一个类中实现 UNUserNotificationCenterDelegate 的尝试,而是在我的 View Controller 中完成了它:

#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);
}

上面的创建通知和请求权限方法在代码中保持不变。

这允许在应用程序中显示本地通知,并且如果通过通知打开应用程序,则可以显示通知。

关于ios - 显示基于 UNUserNotification iOS 的 UIAlertAction 未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44169935/

相关文章:

ios - 在左侧对齐 UIButton 的图像和 UILabel

objective-c - 从 uisplitview 更改主视图和详细 View

ios - NSKeyedArchiver 适用于模拟器但不适用于实际设备

ios - 苹果是否正式支持离线听写?

ios - CGPath 与 UIBezierPath

ios - AWS SNS 无法使用 createPlatformEndpoint

ios - 有什么方法可以使 UISegmentedControl 中的段宽度与内容成正比?

ios - 从 iOS 日历事件同步到我们的应用程序的 2 种方式

swift - 我想更改框架的版本。[swift 4/xcode 9]

ios - iOS 10/Xcode 8 设备上的 NSLog 似乎被截断了?为什么?