首页 文章

当您的应用程序处于打开状态且位于前台时显示库存iOS通知 Banner ?

提问于
浏览
86

当Apple的官方iOS消息应用程序处于打开状态且位于前台时,来自其他联系人的新消息会触发库存本机iOS通知警报 Banner . 见下图 .

这在App Store的第三方应用程序中是否可行?当您的应用为 open and in the foreground 时,应用的本地和/或推送通知?

测试 my app 时,会收到通知但 no iOS alert UI is shown .

但是这种行为 is 在Apple的官方消息应用程序中看到:

Messages is open and in the foreground. Still shows a notification alert.

Local and Remote Notification Programming Guide说:

当操作系统发送本地通知或远程通知且目标应用未在前台运行时,它可以通过警报,图标标记号或声音向用户显示通知 . 如果应用程序在传递通知时在前台运行,则应用程序委托会收到本地或远程通知 .

所以是的,我们可以在前台接收通知数据 . 但我认为没办法 present the native iOS notification alert UI .

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
{
    // I know we still receive the notification `userInfo` payload in the foreground.
    // This question is about displaying the stock iOS notification alert UI.

    // Yes, one *could* use a 3rd party toast alert framework. 
    [self use3rdPartyToastAlertFrameworkFromGithub]
}

消息然后使用私有API在前台显示警报吗?

出于这个问题的目的, please do not suggest any 3rd party "toast" pop-up alerts 在github上等等 . 我只对在应用程序打开和前台使用 stock, native iOS Local或推送通知警报UI进行此操作感兴趣 .

10 回答

  • 74

    如果您的部署目标> = iOS10,请使用UNUserNotification,如下所示 -

    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                    willPresent notification: UNNotification,
                                    withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
        {
            // Change this to your preferred presentation option
            completionHandler([.alert, .sound])
        }
    
  • 10

    要在应用程序位于前台时显示 Banner 消息,请使用以下方法 .

    iOS 10, Swift 3

    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.alert, .badge, .sound])
    }
    
  • 105

    EDIT:

    iOS 10中现在可以进行前景警报! Please see this answer .

    For iOS 9 and below:

    当您的应用程序处于打开状态且位于前台时,似乎无法显示库存iOS通知警报 . Messages.app必须使用私有API .

    当应用程序已经位于最前端时,系统不会显示任何警报,标记应用程序的图标或播放任何声音 . - UILocalNotification文档

    仍将调用 UIApplicationDelegate 方法,允许您的应用响应本地或远程通知:

    application:didReceiveLocalNotification:
    application:didReceiveRemoteNotification:
    

    但是,库存原生iOS通知警报 Banner UI将 not be shown ,因为它在Apple的Messages.app中,它必须使用私有API .

    您可以做的最好的事情是滚动自己的警报 Banner 或使用现有框架:

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
    {    
        // Use a 3rd party toast alert framework to display a banner 
        [self toastAlertFromGithub]
    }
    

    我在这里为这种行为打开了一个雷达: rdar://22313177

  • 14

    您可以自己处理通知并显示自定义警报 . Viber,Whatsapp和BisPhone等应用程序都使用这种方法 .

    第三方自定义警报的一个示例是CRToast .

    尝试在应用程序位于前台时安排本地通知,您将看到没有显示库存iOS警报:

    if (application.applicationState == UIApplicationStateActive ) {
         UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.userInfo = userInfo;
        localNotification.soundName = UILocalNotificationDefaultSoundName;
        localNotification.alertBody = message;
        localNotification.fireDate = [NSDate date];
        [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    }
    
  • 9

    iOS 10 添加了UNUserNotificationCenterDelegate协议,用于在您的应用处于前台时处理通知 .

    UNUserNotificationCenterDelegate协议定义了接收通知和处理操作的方法 . 当您的应用程序位于前台时,到达的通知将传递到您的委托对象,而不是使用系统界面自动显示 .

    迅速:

    optional func userNotificationCenter(_ center: UNUserNotificationCenter, 
                         willPresent notification: UNNotification, 
          withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
    

    Objective-C的:

    - (void)userNotificationCenter:(UNUserNotificationCenter *)center 
           willPresentNotification:(UNNotification *)notification 
             withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;
    

    UNNotificationPresentationOptions标志允许您指定 UNNotificationPresentationOptionAlert 以使用通知提供的文本显示警报 .

    这是关键,因为它允许您显示警报 while your app is open and in the foreground ,这是iOS 10的新功能 .

    示例代码:

    func userNotificationCenter(_ center: UNUserNotificationCenter,
           willPresent notification: UNNotification, 
           withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 
    {
        completionHandler(.alert)
    }
    
  • 5
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.body = body;
    content.userInfo = userInfo;
    content.sound = [UNNotificationSound defaultSound];
    [content setValue:@(YES) forKeyPath:@"shouldAlwaysAlertWhileAppIsForeground"];
    
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"Notif" content:content trigger:nil];
    [[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        DLog(@"Error:%@", error);
    }];
    

    当应用程序处于活动状态时,我可以显示推送通知 iOS 10.

    • 来自服务器的推送通知应为 silent .

    • 从服务器接收远程通知时,您发送本地通知并设置 keyPath: shouldAlwaysAlertWhileAppIsForeground = True 的值

  • 4

    Swift 3 version

    这会在应用程序位于前台时显示警报 .

    if #available(iOS 10.0, *)
    {
        // need to setup the global notification delegate somewhere when your app starts
        //
        UNUserNotificationCenter.current().delegate = applicationDelegate
    
        // to show a message
        //
        let content = UNMutableNotificationContent()
        content.body = "MESSAGE"
    
        let request = UNNotificationRequest(identifier: "fred", content: content, trigger: nil)
        UNUserNotificationCenter.current().add(request)
        {
           error in // called when message has been sent
    
           debugPrint("Error: \(error)")
        }
    }
    

    ApplicationDelegate的 UNUserNotificationCenterDelegate 实现

    @available(iOS 10.0, *)
    public func userNotificationCenter(_ center : UNUserNotificationCenter, willPresent notification : UNNotification, withCompletionHandler completionHandler : @escaping (UNNotificationPresentationOptions) -> Void)
    {
        completionHandler([.alert]) // only-always show the alert
    }
    
  • 12

    要在应用程序打开时显示通知,我们需要手动处理它 . 所以我在下面做的是收到通知后处理通知 .

    在AppDelegate.m中添加以下所有内容

    • 处理通知请求

    • 创建视图,添加AppIcon,通知消息并将其显示为动画

    • 添加触摸识别器,如果触摸则移除或在5秒内移除动画 .

    如果这是一个好的解决方案,请告诉我 . 对我来说工作得很好但不确定这是否正确 .

    - (void)application:(UIApplication *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    
    
    NSString *notifMessage = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];
    
    //Define notifView as UIView in the header file
    [_notifView removeFromSuperview]; //If already existing
    
    _notifView = [[UIView alloc] initWithFrame:CGRectMake(0, -70, self.window.frame.size.width, 80)];
    [_notifView setBackgroundColor:[UIColor blackColor]];
    
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,15,30,30)];
    imageView.image = [UIImage imageNamed:@"AppLogo.png"];
    
    UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 15, self.window.frame.size.width - 100 , 30)];
    myLabel.font = [UIFont fontWithName:@"Helvetica" size:10.0];
    myLabel.text = notifMessage;
    
    [myLabel setTextColor:[UIColor whiteColor]];
    [myLabel setNumberOfLines:0];
    
    [_notifView setAlpha:0.95];
    
    //The Icon
    [_notifView addSubview:imageView];
    
    //The Text
    [_notifView addSubview:myLabel];
    
    //The View
    [self.window addSubview:_notifView];
    
    UITapGestureRecognizer *tapToDismissNotif = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                        action:@selector(dismissNotifFromScreen)];
    tapToDismissNotif.numberOfTapsRequired = 1;
    tapToDismissNotif.numberOfTouchesRequired = 1;
    
    [_notifView addGestureRecognizer:tapToDismissNotif];
    
    
    [UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{
    
        [_notifView setFrame:CGRectMake(0, 0, self.window.frame.size.width, 60)];
    
    } completion:^(BOOL finished) {
    
    
    }];
    
    
    //Remove from top view after 5 seconds
    [self performSelector:@selector(dismissNotifFromScreen) withObject:nil afterDelay:5.0];
    
    
    return;
    
    
    }
    
    //If the user touches the view or to remove from view after 5 seconds
    - (void)dismissNotifFromScreen{
    
    [UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{
    
        [_notifView setFrame:CGRectMake(0, -70, self.window.frame.size.width, 60)];
    
    } completion:^(BOOL finished) {
    
    
    }];
    
    
    }
    
  • 0

    要显示本地通知,这是最佳选择 . 需要更少的代码来怀疑"BRYXBanner " https://cocoapods.org/pods/BRYXBanner

    let banner = Banner(title: "title", subtitle: "subtitle", image: UIImage(named: "addContact"), backgroundColor: UIColor(red:137.0/255.0, green:172.0/255.0, blue:2.0/255.0, alpha:1.000))
        banner.dismissesOnTap = true
        banner.show(duration: 1.0)
    
  • 0

    以下是在应用程序处于前台或开放阶段iOS 10和Swift 2.3时接收推送通知的代码

    @available(iOS 10.0, *)
    func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
    {
         completionHandler([UNNotificationPresentationOptions.Alert,UNNotificationPresentationOptions.Sound,UNNotificationPresentationOptions.Badge])
    }
    

    如果您需要访问userInfo的通知使用代码: notification.request.content.userInfo

    仅当您向有效负载添加属性 content-available:1 时,才会调用方法 userNotificationCenter(_:willPresent:withCompletionHandler:) . 最终的有效载荷应该是这样的:

    {
         "aps":{
              "alert":"Testing.. (7)",
              "badge":1,"sound":"default"
         },
         "content-available":1
    }
    

相关问题