我在我的应用中使用推送通知服务。当应用程序在后台时,我能够在通知屏幕上看到通知(当我们从iOS设备的顶部向下滑动时显示的屏幕)。但是如果应用程序在前台是委托方法
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
被调用但通知屏幕中不显示通知。
我想在通知屏幕上显示通知,无论应用是在后台还是前台。我厌倦了寻找解决方案。非常感谢任何帮助。
答案 0 :(得分:141)
要在应用程序位于前台时显示横幅消息,请使用以下方法。
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
...
}
答案 1 :(得分:52)
以下代码适用于您:
- (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];
}
}
答案 2 :(得分:38)
对于任何可能感兴趣的人,我最终创建了一个自定义视图,它看起来像顶部的系统推送横幅,但添加了一个关闭按钮(小蓝色X)和一个用于点击消息以进行自定义操作的选项。它还支持在用户有时间读取/解除旧通知之前到达多个通知的情况(没有限制可以堆积多少...)
用法基本上是在线:
[AGPushNoteView showWithNotificationMessage:@"John Doe sent you a message!"];
在iOS7上看起来像这样(iOS6具有iOS6的外观和感觉......)
答案 3 :(得分:31)
目标C
对于iOS 10
,我们需要在willPresentNotification
中为展示通知横幅整合foreground
方法。
如果app处于前台模式(活动)
- (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);
}
答案 4 :(得分:21)
如果应用程序在前台运行,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)
}
答案 5 :(得分:12)
如果应用程序在前台运行,iOS将不会显示通知横幅/警报。这是设计的。您必须编写一些代码来处理应用程序在前台接收通知时的情况。您应该以最合适的方式显示通知(例如,将徽章编号添加到UITabBar
图标,模拟通知中心横幅等)。
答案 6 :(得分:9)
您可以创建自己的模仿横幅提醒的通知。
一种方法是创建一个看起来像横幅的自定义uiview,可以设置动画并响应触摸。考虑到这一点,您可以使用更多功能创建更好的横幅。
或者你可以找一个为你做的api,并将它们作为podfiles添加到你的项目中。
以下是我使用的一对夫妇:
答案 7 :(得分:8)
以下是app处于活动状态(前台或打开)时接收推送通知的代码。 UNUserNotificationCenter documentation
@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
答案 8 :(得分:7)
根据apple documentation,是的,您可以在应用运行时显示通知
答案 9 :(得分:6)
对于Swift 5
1)使用
确认AppDelegate的委托。UNUserNotificationCenterDelegate
2)
UNUserNotificationCenter.current().delegate = self
中的didFinishLaunch
3)在
AppDelegate
中实现以下方法。
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
print("Push notification received in foreground.")
completionHandler([.alert, .sound, .badge])
}
就是这样!
答案 10 :(得分:3)
Xcode 10 Swift 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])
}
第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)
}
答案 11 :(得分:2)
将该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])
}
答案 12 :(得分:2)
在你的app委托中使用以下代码
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])
}
}
答案 13 :(得分:1)
用于快速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
}
}
答案 14 :(得分:1)
为此的最佳方法是使用UNUserNotificationCenterDelegate
在AppDelegate
中添加extension AppDelegate: UNUserNotificationCenterDelegate
该扩展程序告诉应用程序在使用中能够获得通知
并实现此方法
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(.alert)
}
仅当应用程序在前景中时,才会在委托上调用此方法。
最后的实现:
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler(.alert)
}
}
要调用此方法,必须在didFinishLaunchingWithOptions
的AppDelegate中设置委托,然后添加此行
UNUserNotificationCenter.current().delegate = self
您可以修改
completionHandler(.alert)
与
completionHandler([.alert, .badge, .sound]))
答案 15 :(得分:0)
如上所述,您应该使用UserNotification.framework
来实现此目的。但是出于我的目的,我必须在应用程序中显示它并且想要iOS 11
样式,所以我创建了一个小帮助视图,可能对某人有用。
答案 16 :(得分:-2)
如果您的应用程序处于前台状态,则表示您当前正在使用相同的应用程序。因此,通常无需在顶部显示通知。
但是,如果你想在这种情况下显示通知,你必须创建自定义警报视图或自定义视图,如Toast或其他东西,以向用户显示您已收到通知。
如果您的应用中有此类功能,您还可以在顶部显示徽章。
答案 17 :(得分:-2)
正如@Danial Martine所说,iOS不会显示通知横幅/警告。这是设计的。但如果真的必须这样做,那么有一种方法。我也是这样做的。
下载解析框工作 2.Import #import <Parse/Parse.h>
3.将以下代码添加到didReceiveRemoteNotification方法
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[PFPush handlePush:userInfo];
}
PFPush会注意如何处理远程通知。如果App位于前台,则会显示警告,否则会在顶部显示通知。