220

我在我的应用程序中使用推送通知服务。当应用程序在后台时,我可以在通知屏幕上看到通知(当我们从 iOS 设备顶部向下滑动时显示的屏幕)。但是如果应用程序在前台,委托方法

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

正在被调用,但通知屏幕中未显示通知。

我想在通知屏幕上显示通知,无论应用程序是在后台还是前台。我厌倦了寻找解决方案。任何帮助是极大的赞赏。

4

18 回答 18

238

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

iOS 10,斯威夫特 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,斯威夫特 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
      ...
   }
于 2016-11-23T04:44:08.153 回答
60

下面的代码将为您工作:

- (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];          
    }    
}
于 2013-02-14T10:50:22.750 回答
41

目标 C

在此处输入图像描述

因为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);
}
于 2017-01-28T07:52:38.900 回答
37

对于任何可能感兴趣的人,我最终创建了一个自定义视图,该视图看起来像顶部的系统推送横幅,但添加了一个关闭按钮(蓝色小 X)和一个用于点击消息以进行自定义操作的选项。它还支持在用户有时间阅读/关闭旧通知之前到达多个通知的情况(不限制可以堆积多少......)

链接到 GitHub:AGPushNote

用法基本是在线的:

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

它在 iOS7 上看起来像这样(iOS6 具有 iOS6 的外观......)

在此处输入图像描述

于 2014-04-29T12:54:44.033 回答
27

如果应用程序在前台运行,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];
    }
    

迅速:

if application.applicationState == .active {
    var localNotification = UILocalNotification()
    localNotification.userInfo = userInfo
    localNotification.soundName = UILocalNotificationDefaultSoundName
    localNotification.alertBody = message
    localNotification.fireDate = Date()
    UIApplication.shared.scheduleLocalNotification(localNotification)
}
于 2013-02-15T03:56:57.023 回答
21

Xcode 10 斯威夫特 4.2

当您的应用程序处于前台时显示推送通知 -

第 1 步:在 AppDelegate 类中添加委托 UNUserNotificationCenterDelegate。

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

第 2 步:设置 UNUserNotificationCenter 委托

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

第 3 步:此步骤将允许您的应用程序显示推送通知,即使您的应用程序在前台也是如此

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

    }

第四步:这一步是可选的。检查您的应用程序是否在前台,如果它在前台,则显示 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)
    }
于 2019-06-21T04:54:42.277 回答
18

对于斯威夫特 5

1) 向 AppDelegate 确认委托UNUserNotificationCenterDelegate

2)UNUserNotificationCenter.current().delegate = selfdidFinishLaunch

3) 实现下面的方法AppDelegate

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

就是这样!

于 2020-05-12T06:36:44.800 回答
15

如果应用程序在前台运行,iOS 将不会显示通知横幅/警报。这是设计使然。您必须编写一些代码来处理您的应用程序在前台接收通知的情况。您应该以最合适的方式显示通知(例如,将徽章编号添加到UITabBar图标、模拟通知中心横幅等)。

于 2013-02-14T10:06:11.387 回答
9

您可以创建自己的模仿横幅警报的通知。

一种方法是创建一个看起来像横幅的自定义 uiview,并且可以动画和响应触摸。考虑到这一点,您可以创建具有更多功能的更好的横幅。

或者你可以寻找一个 api 为你做这件事,并将它们作为 podfiles 添加到你的项目中。

这是我用过的一对:

https://github.com/terryworona/TWMessageBarManager

https://github.com/toursprung/TSMessages

于 2014-03-28T14:51:18.377 回答
8

这是当应用程序处于活动状态(前台或打开)时接收推送通知的代码。 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

于 2016-12-27T09:12:49.477 回答
4

将 completionHandler 行添加到委托方法为我解决了同样的问题:

//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])
} 
于 2017-03-07T20:31:16.590 回答
3

用于 swift 5 解析 PushNotification 字典

    func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
            if application.applicationState == .active {
                if let aps1 = data["aps"] as? NSDictionary {
                    if let dict = aps1["alert"] as? NSDictionary {
                        if let strTitle = dict["title"] as? String , let strBody = dict["body"] as? String {
                            if let topVC = UIApplication.getTopViewController() {
                                //Apply your own logic as per requirement
                                print("strTitle ::\(strTitle) , strBody :: \(strBody)")
                            }
                        }
                    }
                }
            }
        }

获取我们在其上显示 topBanner 的 top viewController

extension UIApplication {

    class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {

        if let nav = base as? UINavigationController {
            return getTopViewController(base: nav.visibleViewController)

        } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
            return getTopViewController(base: selected)

        } else if let presented = base?.presentedViewController {
            return getTopViewController(base: presented)
        }
        return base
    }
}
于 2019-11-11T13:18:33.727 回答
2

在您的应用委托中使用以下代码

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])
    }
}
于 2017-10-23T07:41:28.083 回答
1

最好的方法是通过使用添加UNUserNotificationCenterDelegate该 扩展程序告诉应用程序能够在使用时获得通知AppDelegateextension AppDelegate: UNUserNotificationCenterDelegate

并实现这个方法

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

仅当应用程序位于Foreground时,才会在委托上调用此方法。

所以最终的实现:

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

并且要调用它,您必须在 AppDelegate 中设置委托didFinishLaunchingWithOptions添加此行

UNUserNotificationCenter.current().delegate = self

你可以修改

completionHandler(.alert) 

completionHandler([.alert, .badge, .sound]))
于 2020-04-17T14:53:05.593 回答
0

如上所述,您应该使用UserNotification.framework来实现这一点。但出于我的目的,无论如何我都必须在应用程序中显示它并且想要有iOS 11风格,所以我创建了一个小的帮助视图,也许对某人有用。

GitHub iOS 11 推送通知视图

于 2018-01-30T16:34:13.250 回答
0

100% 工作测试

首次导入

import UserNotifications

然后在类中添加委托

UNUserNotificationCenterDelegate


class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

当应用程序打开并收到通知时,以下方法负责。

将呈现

   @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
            let content = notification.request.content

           let alertVC = UIAlertController.init(title: title, message: body, preferredStyle: .alert)

            alertVC.addAction(UIAlertAction.init(title: appLan_share.Ok_txt, style: .default, handler: {
                _ in
                   //handle tap here or navigate somewhere…..                
            }))

            vc?.present(alertVC, animated: true, completion: nil)

            print("notification Data: \(content.userInfo.values)")
                completionHandler([.alert, .sound])



}

您还可以通过检查当前应用程序状态来处理应用程序状态。

此外,如果您的应用程序未运行,则以下方法负责处理推送通知

收到

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        let aps = userInfo["aps"] as? [String: Any]
        let alert = aps?["alert"] as? [String: String]

}
于 2022-01-24T09:16:05.323 回答
-2

如果您的应用程序处于前台状态,则表示您当前正在使用同一个应用程序。所以一般不需要在顶部显示通知。

但是,如果您想在这种情况下显示通知,则必须创建自定义警报视图或自定义视图,例如 Toast 或其他东西,以向用户显示您已收到通知。

如果您的应用中有此类功能,您也可以在顶部显示徽章。

于 2016-05-12T06:10:34.767 回答
-3

正如@Danial Martine 所说,iOS 不会显示通知横幅/警报。这是设计使然。但如果真的必须这样做,那么有一种方法。我也通过同样的方式实现了这一点。

1.从Parse FrameWork下载解析框架

2.进口#import <Parse/Parse.h>

3.将以下代码添加到您的 didReceiveRemoteNotification 方法

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

PFPush 会注意如何处理远程通知。如果应用程序在前台,则会显示警报,否则会在顶部显示通知。

于 2013-02-14T10:20:14.620 回答