关于iphone:在前台iOS中获取推送通知

Get push notification while App in foreground iOS

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

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

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

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


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

iOS 10,Swift 3/4:

1
2
3
4
5
// 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:

1
2
3
4
5
6
7
8
9
@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])
}

您还必须将您的应用代表注册为通知中心的代表:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
2
3
4
5
6
7
8
9
10
11
12
13
14
- (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:
%@"
,[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];          
    }    
}


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

链接到GitHub:AGPushNote

用法基本上是在线:

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

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

enter image description here


目标C.

enter image description here

对于iOS 10,我们需要在foreground中集成willPresentNotification方法以显示通知横幅。

如果app处于前台模式(活动)

1
2
3
4
5
6
7
8
9
- (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);
}


如果应用程序在前台运行,iOS将不会显示通知横幅/警报。这是设计的。但我们可以通过如下使用UILocalNotification来实现它

  • 在接收遥控器时检查应用程序是否处于活动状态
    通知。如果处于活动状态,则触发UILocalNotification。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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];
    }

迅速:

1
2
3
4
5
6
7
8
if application.applicationState == .active {
    var localNotification = UILocalNotification()
    localNotification.userInfo = userInfo
    localNotification.soundName = UILocalNotificationDefaultSoundName
    localNotification.alertBody = message
    localNotification.fireDate = Date()
    UIApplication.shared.scheduleLocalNotification(localNotification)
}


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


您可以创建自己的模仿横幅提醒的通知。

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

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

这是我用过的一对夫妇:

https://github.com/terryworona/TWMessageBarManager

https://github.com/toursprung/TSMessages


以下是app处于活动状态(前台或打开)时接收推送通知的代码。 UNUserNotificationCenter文档

1
2
3
4
5
@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


根据Apple文档,是的,您可以在应用运行enter image description here时显示通知


Xcode 10 Swift 4.2

要在应用程序位于前台时显示推送通知 -

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

1
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

第2步:设置UNUserNotificationCenter委托

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

第3步:即使您的应用处于前台,此步骤也会允许您的应用显示推送通知

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

    }

第4步:此步骤是可选的。 检查您的应用是否位于前台,如果它位于前台,则显示Local PushNotification。

1
2
3
4
5
6
7
8
9
10
11
12
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()
        }
    }

本地通知功能 -

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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)
    }

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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])
    }
}


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

1
2
3
4
5
6
//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])
}


如上所述,您应该使用UserNotification.framework来实现此目的。 但是为了我的目的,我必须在应用程序中显示它并希望有iOS 11样式,所以我创建了一个小帮助器视图,可能对某人有用。

GitHub iOS 11推送通知视图。


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

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

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


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

1.从Parse FrameWork下载解析框架工作

2.Import #import

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

1
2
3
4
5
 - (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [PFPush handlePush:userInfo];
}

PFPush将注意如何处理远程通知。如果App位于前台,则会显示警报,否则会在顶部显示通知。