在应用程序处于打开状态且位于前台时显示库存iOS通知横幅?

时间:2015-06-15 18:52:38

标签: ios uikit apple-push-notifications uilocalnotification toast

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

这可以在App Store的第三方应用中使用吗?当您的应用打开且处于前台时,您的应用的本地和/或推送通知?

在测试我的应用时,会收到通知但未显示iOS提醒用户界面

但在Apple的官方消息应用中可以看到 这种行为

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

Local and Remote Notification Programming Guide说:

  

当操作系统发送本地通知或远程通知且目标应用未在前台运行时,它可以通过提醒向用户显示通知,图标徽章编号或声音。

     

如果应用程序在传递通知时在前台中运行,则应用代理会收到本地或远程通知。

是的,我们可以在前台收到通知数据。但我认为无法显示本机iOS通知提醒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在前台显示警报?

出于这个问题的目的,请不要在github等上建议任何第三方“toast”弹出警报。我只对使用库存,原生iOS 本地或推送通知会在应用程序处于打开状态且位于前台时警告UI

10 个答案:

答案 0 :(得分:116)

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

  

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

夫特:

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

目标-C:

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

UNNotificationPresentationOptions标记允许您指定UNNotificationPresentationOptionAlert以使用通知提供的文本显示提醒。

这是关键,因为它允许您在应用程序处于打开状态且在前台时显示警告,这是iOS 10的新功能。

示例代码:

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

答案 1 :(得分:81)

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

iOS 10,Swift 3

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

答案 2 :(得分:14)

修改

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

适用于iOS 9及以下版本:

当您的应用处于打开状态且位于前台时,似乎无法显示iOS通知提醒。 Messages.app必须使用私有API。

  

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

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

application:didReceiveLocalNotification:
application:didReceiveRemoteNotification:

但是,库存原生iOS通知提醒横幅用户界面不会显示,就像在Apple的Messages.app中一样,它必须使用私有API。

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

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

我已在此处为此行为打开了一个雷达:rdar://22313177

答案 3 :(得分:14)

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

在AppDelegate.m

中添加以下所有内容
  1. 处理通知电话
  2. 创建视图,添加AppIcon,通知消息并将其显示为动画
  3. 添加触摸识别器,如果触摸则移除,或在5秒内通过动画移除。
  4. 如果这是一个好的解决方案,请告诉我。为我工作得很好,但我不确定这是否正确。

    - (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) {
    
    
    }];
    
    
    }
    

答案 4 :(得分:10)

以下是在应用程序处于前台或开放阶段时接收推送通知的代码,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

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

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

答案 5 :(得分:9)

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

的活动状态时,我可以显示推送通知
  1. 来自服务器的推送通知应无声

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

答案 6 :(得分:5)

您可以自行处理通知并显示自定义提醒。 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];
}

答案 7 :(得分:4)

Swift 3版本

当应用程序位于前台时显示警告。

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
}

答案 8 :(得分:1)

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

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

答案 9 :(得分: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)