Отображение знакового баннера уведомлений iOS, когда ваше приложение открыто и находится на переднем плане?

Когда приложение Apple официально опубликовано приложение iOS открыто, и на переднем плане новые сообщения от других контактов запускают запасы, собственный баннер уведомлений уведомлений iOS. См. Изображение ниже.

Возможно ли это в сторонних приложениях в App Store? Локальные и/или Push-уведомления для вашего приложения, когда ваше приложение открыто и на переднем плане?

При тестировании моего приложения уведомления получаются, но не отображается идентификатор пользователя iOS.

Но это поведение отображается в приложении официальных сообщений Apple:

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

Руководство по программированию локального и удаленного уведомлений сообщает:

Когда операционная система отправляет локальное уведомление или удаленное уведомление, а целевое приложение не работает на переднем плане, оно может передать уведомление пользователю через alert, номер значка значка или звук.

Если приложение выполняется в переднем плане при доставке уведомления, делегат приложения получает локальное или удаленное уведомление.

Итак, да, мы можем получать данные уведомления на переднем плане. Но я не вижу возможности представить пользовательский интерфейс уведомления об уведомлении iOS.

-(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 для отображения предупреждения на переднем плане?

Для целей этого вопроса , пожалуйста, не предлагайте никаких всплывающих предупреждений сторонних производителей "toast" на github или т.д. Меня интересует только это, если это можно сделать с помощью инвентарь iOS Локальный или Push Notification UI, когда ваше приложение открыто и на переднем плане.

Ответ 1

iOS 10 добавляет UNUserNotificationCenterDelegate протокол для обработки уведомлений, когда ваше приложение находится на переднем плане.

Протокол UNUserNotificationCenterDelegate определяет методы получения уведомлений и обработки действий. Когда ваше приложение находится на переднем плане, входящие уведомления доставляются в объект делегата вместо автоматического отображения с использованием системных интерфейсов.

Swift:

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 для отображения предупреждения с использованием текста, предоставленного уведомлением.

Это ключ, так как он позволяет отображать предупреждение , пока ваше приложение открыто и на переднем плане, которое является новым для iOS 10.

Пример кода:

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

Ответ 2

Для отображения сообщения баннера, когда приложение находится на переднем плане, используйте следующий метод.

iOS 10, Swift 3:

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

Ответ 3

Чтобы показывать уведомления, пока приложение открыто, мы должны обрабатывать его вручную. Итак, что я делаю ниже, нужно обработать уведомление после его получения.

Добавить все ниже в AppDelegate.m

  • Обратиться к уведомлению
  • Создайте представление, добавьте сообщение AppIcon, Уведомление и покажите его как анимацию.
  • Добавить Touch распознаватель, чтобы удалить, если он коснулся или удалился за 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) {


}];


}

Ответ 4

Вот код для получения Push Notification при приложении на переднем плане или на открытой сцене, 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

EDIT:

В iOS 10 теперь доступны предупреждения переднего плана! См. этот ответ.

Для iOS 9 и ниже:

Кажется, что невозможно показать уведомление об уведомлении iOS на складе, когда ваше приложение открыто и находится на переднем плане. Message.app должен использовать частный API.

В системе не отображаются предупреждения, значок значка приложений или воспроизведение любых звуков, когда приложение уже находится на самом переднем плане. - Документы UILocalNotification

Теперь будут вызваны методы 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

Ответ 6

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

Я могу показать push-уведомление, когда приложение активно для iOS 10.

  • Нажатое уведомление с сервера должно быть тихим.

  • При получении удаленного уведомления с сервера вы отправляете локальное уведомление и устанавливаете значение для keyPath: shouldAlwaysAlertWhileAppIsForeground = True

Ответ 7

Вы можете самостоятельно обработать уведомление и показать собственное оповещение. Такие приложения, как 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];
}

Ответ 8

версия 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
}

Ответ 9

Чтобы показать локальное уведомление, это лучший вариант. нужно меньше кода для "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)

Ответ 10

Если цель развертывания >= iOS10, используйте UNUserNotification, как показано ниже -

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