Получать push-уведомление, когда приложение на переднем плане iOS

Я использую службу push-уведомлений в своем приложении. Когда приложение находится в фоновом режиме, я могу видеть уведомление на экране уведомлений (экран отображается, когда мы прокручиваем верхнюю часть устройства iOS). Но если приложение находится на переднем плане, метод делегата

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo

вызывается, но уведомление не отображается на экране уведомлений.

Я хочу показать уведомление на экране уведомлений независимо от того, находится ли приложение в фоновом режиме или на переднем плане. Я устал, ища решение. Любая помощь приветствуется.

Ответ 1

Если приложение запущено на переднем плане, iOS не будет показывать баннер уведомлений/оповещения. Это по дизайну. Но мы можем достичь этого, используя UILocalNotification следующим образом

  • Проверьте, находится ли приложение в активном состоянии при приеме удаленного устройства уведомление. Если в активном состоянии запускается UILocalNotification.

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

SWIFT:

if application.applicationState == .active {
    var localNotification = UILocalNotification()
    localNotification.userInfo = userInfo
    localNotification.soundName = UILocalNotificationDefaultSoundName
    localNotification.alertBody = message
    localNotification.fireDate = Date()
    UIApplication.shared.scheduleLocalNotification(localNotification)
}

Ответ 2

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

iOS 10, Swift 3/4:

// This method will be called when app received push notifications in foreground
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) 
{
    completionHandler([.alert, .badge, .sound])
}

iOS 10, Swift 2.3:

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

Вы также должны зарегистрировать своего делегата приложения в качестве делегата для центра уведомлений:

import UserNotifications

// snip!

class AppDelegate : UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

// snip!

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

      // set the delegate in didFinishLaunchingWithOptions
      UNUserNotificationCenter.current().delegate = self
      ...
   }

Ответ 3

Ниже приведен код для вас:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo  {
    application.applicationIconBadgeNumber = 0;             
    //self.textView.text = [userInfo description];
    // We can determine whether an application is launched as a result of the user tapping the action
    // button or whether the notification was delivered to the already-running application by examining
    // the application state.

    if (application.applicationState == UIApplicationStateActive) {                
        // Nothing to do if applicationState is Inactive, the iOS already displayed an alert view.                
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Did receive a Remote Notification" message:[NSString stringWithFormat:@"Your App name received this notification while it was running:\n%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];          
    }    
}

Ответ 4

Для кого-то может быть интересно, я закончил создание пользовательского представления, которое выглядит как баннер системы, расположенный сверху, но добавляет кнопку закрытия (маленький синий X) и возможность использовать сообщение для пользовательских действий. Он также поддерживает случай более одного уведомления, полученного до того, как пользователь успел прочитать/отменить старые (без ограничений, сколько может накапливаться...)

Ссылка на GitHub: AGPushNote

Использование в основном включено:

[AGPushNoteView showWithNotificationMessage:@"John Doe sent you a message!"];

И это похоже на iOS7 (iOS6 имеет внешний вид iOS6...)

enter image description here

Ответ 5

Цель С

enter image description here

Для iOS 10 нам нужно интегрировать метод willPresentNotification для показа баннера уведомления на foreground.

Если приложение в режиме переднего плана (активно)

- (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    NSLog( @"Here handle push notification in foreground" ); 
    //For notification Banner - when app in foreground

    completionHandler(UNNotificationPresentationOptionAlert);

    // Print Notification info
    NSLog(@"Userinfo %@",notification.request.content.userInfo);
}

Ответ 6

Если приложение запущено на переднем плане, iOS не будет показывать баннер уведомлений/оповещения. Это по дизайну. Вы должны написать код, чтобы иметь дело с ситуацией, когда ваше приложение получает уведомление, когда оно находится на переднем плане. Вы должны показать уведомление наиболее подходящим способом (например, добавив номер значка к значку UITabBar, имитируя баннер Notification Center и т.д.).

Ответ 7

Вы можете создать свое собственное уведомление, которое имитирует предупреждение баннера.

Один из способов - создать пользовательский uiview, который выглядит как баннер и может анимировать и реагировать на прикосновения. Имея это в виду, вы можете создавать еще лучшие баннеры с еще большей функциональностью.

Или вы можете найти api, который сделает это за вас, и добавить их в качестве подкачки в ваш проект.

Вот пара, которую я использовал:

https://github.com/terryworona/TWMessageBarManager

https://github.com/toursprung/TSMessages

Ответ 8

Вот код для получения Push Notification, когда приложение находится в активном состоянии (передним или открытым). Документация UNUserNotificationCenter

@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

Ответ 9

Согласно документации Apple, да, вы можете отображать уведомления во время работы приложения enter image description here

Ответ 10

Добавление этой строки завершенияHandler для метода делегирования решает ту же проблему для меня:

//Called when a notification is delivered to a foreground app.
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

completionHandler([.alert, .badge, .sound])
} 

Ответ 11

В своем делете приложения используйте следующий код

import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
 var currentToken: String?
 var window: UIWindow?
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        application.registerForRemoteNotifications()
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in

            // Enable or disable features based on authorization.
            if granted == true
            {
                print("Allow")
                UIApplication.shared.registerForRemoteNotifications()
            }
            else
            {
                print("Don't Allow")
            }
        }
        UNUserNotificationCenter.current().delegate = self

        return true
    }
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
        let tokenParts = deviceToken.map { data -> String in
            return String(format: "%02.2hhx", data)
        }
        let token = tokenParts.joined()
        currentToken = token  //get device token to delegate variable

    }
 public class var shared: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
         completionHandler([.alert, .badge, .sound])
    }
}

Ответ 12

Как упоминалось выше, вы должны использовать UserNotification.framework для достижения этой цели. Но для моих целей я все равно должен показать это в приложении и хотел иметь стиль iOS 11, поэтому я создал небольшое вспомогательное представление, может быть, кому-то будет полезно.

GitHub iOS 11 Просмотр push-уведомлений.

Ответ 13

Xcode 10 Swift 4.2

Чтобы показать Push-уведомление, когда ваше приложение находится на переднем плане -

Шаг 1: добавьте делегат UNUserNotificationCenterDelegate в классе AppDelegate.

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

Шаг 2: Установите делегата UNUserNotificationCenter

let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.delegate = self

Шаг 3. Этот шаг позволит вашему приложению отображать push-уведомления, даже когда ваше приложение находится на переднем плане

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

    }

Шаг 4: Этот шаг не является обязательным. Проверьте, находится ли ваше приложение на переднем плане, и если оно на переднем плане, то покажите Local PushNotification.

func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) {

        let state : UIApplicationState = application.applicationState
        if (state == .inactive || state == .background) {
            // go to screen relevant to Notification content
            print("background")
        } else {
            // App is in UIApplicationStateActive (running in foreground)
            print("foreground")
            showLocalNotification()
        }
    }

Функция локального оповещения -

fileprivate func showLocalNotification() {

        //creating the notification content
        let content = UNMutableNotificationContent()

        //adding title, subtitle, body and badge
        content.title = "App Update"
        //content.subtitle = "local notification"
        content.body = "New version of app update is available."
        //content.badge = 1
        content.sound = UNNotificationSound.default()

        //getting the notification trigger
        //it will be called after 5 seconds
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)

        //getting the notification request
        let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger)

        //adding the notification to notification center
        notificationCenter.add(request, withCompletionHandler: nil)
    }

Ответ 14

Как сказал @Danial Martine, iOS не будет показывать баннер уведомлений/оповещения. Это по дизайну. Но если это действительно так, то есть один путь. Я также добился этого тем же.

1.Загрузить работу синтаксического анализа из Parse FrameWork

2.Import #import <Parse/Parse.h>

3. Добавьте следующий код к вашему методу didReceiveRemoteNotification

 - (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [PFPush handlePush:userInfo];
}

PFPush позаботится о том, как обрабатывать удаленное уведомление. Если приложение находится на переднем плане, это показывает предупреждение, иначе оно отображает уведомление вверху.

Ответ 15

Если ваше приложение находится в состоянии переднего плана, это означает, что вы в настоящее время используете одно и то же приложение. Поэтому нет необходимости показывать уведомление сверху.

Но если вы хотите показать уведомление, в этом случае вам нужно создать свой пользовательский вид оповещения или пользовательский вид, например, Toast или что-то еще, чтобы показать пользователю, что у вас есть уведомление.

Вы также можете показать значок сверху, если у вас есть такая функция в вашем приложении.