アプリがフォアグラウンドiOSのときにプッシュ通知を受け取る


189

アプリでプッシュ通知サービスを使用しています。アプリがバックグラウンドで動作している場合、通知画面(iOSデバイスの上部から下にスワイプすると表示される画面)に通知が表示されます。しかし、アプリケーションがフォアグラウンドにある場合、デリゲートメソッド

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

が呼び出されていますが、通知画面に通知が表示されません。

アプリがバックグラウンドかフォアグラウンドかに関係なく、通知画面に通知を表示したい。解決策を探して疲れています。どんな助けでも大歓迎です。


35
アップルは言うあなたのアプリがフォアグラウンドで実行されている間、あなたは、ローカルまたはリモートの通知を受信した場合は、アプリケーション固有の方法でユーザーに情報を渡すための責任があります。
Lauri Lehmijoki 2016年

2
いくつかの最新(10月「16)リンゴのリンク:ここではそこそこに
azmeuk

1
iOS 9.3以前のプッシュ通知のフォアグラウンドサポートはありませんか?
Anurag Sharma

@Lauri Lehmijokiリンク?公式ウェブサイトでは見つかりませんでした
Vyachaslav Gerchicov '10 / 07/18

1
私はイオンで同じ問題に直面しています...
Sayed Mohd Ali、

回答:


204

アプリがフォアグラウンドにあるときにバナーメッセージを表示するには、次のメソッドを使用します。

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
      ...
   }

このメソッドが呼び出されるのはいつですか?
Uma Madhavi 2016

私のアプリのバックグラウンドまたはフォアグラウンドのときに上から通知を表示するのに苦労していることをご案内ください。2週間以上、プッシュ通知を使用しています。サーバーからメッセージを受信できます。
Uma Madhavi

@UmaMadhaviプッシュ通知を受信できますか?
チェンサム16

21
通知センターのデリゲートをアプリのデリゲートとして設定することを忘れないでください。 UNUserNotificationsCenter.current().delegate = selfアプリケーションでdidFinishLaunchingWithOptions
Achintya Ashok

2
まだ苦労している人のために、センターの前に 's'があるUNUserNotificationsCenterではなく、そのUNUserNotificationCenter
Raj

58

以下のコードはあなたのために働くでしょう:

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

これは機能します。それが何をするかについてのもう少しの情報。アプリケーションがフォアグラウンドにある場合、ネイティブUIアラートボックスが表示され、その中に通知テキストが表示されます(title太字のテキストは少し大きく、そのmessage下のテキストは小さくなります。閉じるための[OK]ボタンは下部にあります)。0に設定されているapplicationIconBadgeNumberオプションは、Springboardのアプリアイコンの上に表示される数を非表示にすることです(たとえば、メールアプリの未読メッセージの数を示します)。この例では、そのオプションが必要かどうかはわかりません。
jwinn

これはUNnotificationとUILocalNotificationの両方で機能しますか?
user6631314

38

興味のある方のために、システムプッシュバナーのようなカスタムビューを作成しましたが、閉じるボタン(小さな青いX)とカスタムアクションのメッセージをタップするオプションを追加しました。また、ユーザーが古い通知を読んだり閉じたりする時間がなくなる前に複数の通知が届いた場合もサポートします(いくつまで積み重ねることができるかについての制限はありません...)

GitHubへのリンク:AGPushNote

使い方は基本的にオンラインです:

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

そして、iOS7ではこれのように見えます(iOS6にはiOS6のルックアンドフィールがあります...)

ここに画像の説明を入力してください



これは便利です。
夜之星辰

36

目的C

ここに画像の説明を入力してください

以下のためにiOS 10私たちは、統合する必要がwillPresentNotificationでshow通知バナーのための方法を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);
}

1
コードをコピーして、UNUserNotificationCenterDelegateプロトコルを使用することを忘れないでください。
Nik Kov 2017

この通知の代わりにアラートを表示したい場合はどうすればよいですか?
Mihir Oza 2017

@MihirOza UIAlertControllerが必要ですか?
Ashwini Chougale 2017

わかっていますが、アプリがアクティブなときに通知ポップアップを表示したくありません。アプリでアラートのみを表示したい。
Mihir Oza

24

アプリケーションがフォアグラウンドで実行されている場合、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)
}

86
これは役に立たないと思います。ローカル通知とリモート通知は同じように扱われるため、このローカル通知が発生すると、アプリが実行されている場合、バッジ/バナーまたはサウンドは表示/再生されません。
RPM

3
また、iOS通知センターにもエントリが残されます
Ab'initio

3
ただし、プッシュ通知が来てもローカル通知を起動しません。代わりに、@ Rick77のような同様の動作(アラートまたはトースターの表示)を起動します。オペレーティングシステムが処理するように求めている何かのために、もう一度オペレーティングシステムを経由する必要はないと思います。
ファビオ・オリベイラ

3
ローカルとリモートが同じ方法で処理されるため、このソリューションは機能します。アプリがフォアグラウンドにある場合、リモート通知が来たときに位置通知を作成しても何も表示されません。アラートまたはカスタムアラートの使用が解決策です
Hammer、

18
これは実際には機能しません。UILocalNotificationドキュメントから:If the app is foremost and visible when the system delivers the notification, the app delegate’s application:didReceiveLocalNotification: is called to process the notification. Use the information in the provided UILocalNotification object to decide what action to take. The system does not display any alerts, badge the app’s icon, or play any sounds when the app is already frontmost.
Chris Morse

15

アプリケーションがフォアグラウンドで実行されている場合、iOSは通知バナー/アラートを表示しません。これは仕様によるものです。アプリがフォアグラウンドにあるときに通知を受信する状況に対処するために、コードを記述する必要があります。通知は最も適切な方法で表示する必要があります(たとえば、バッジ番号をUITabBarアイコンに追加する、通知センターのバナーをシミュレートするなど)。


1
しかし、iOSメールアプリケーションでは、メールアプリがフォアグラウンドで動作しているときに新しい通知バナー/アラートが表示されます
Ab'initio

3
@ Ab'initioよくわかりませんが、iOSではすべてのアプリケーションが同じように作成されていません。ストックMailアプリは、パブリックSDKでは利用できない何らかのプライベートAPIを使用していると思います。または、通知コードがAppleのメールアプリIDで例外を作っている可能性があります。
ダニエル・マルティン

1
何??ハーピーレイジ攻撃を仕掛けようとしています。
Josh

@DanielMartínは、iOS 8.0でフォアグラウンド状態の通知をどのように受信するのか教えてくれます
Dilip Tiwari

9
この答えはiOS 9以下にのみ当てはまることを覚えておいてください。iOS 10以降、Appleは通知を処理する新しいAPI(UNUserNotificationCenter API)を導入しました。新しいAPIとともに、アプリケーションがフォアグラウンドにある場合に通知を表示できるようになりました。したがって、この質問の異なる回答が原因で混乱している場合は、回答の一部が古すぎてiOS 9以前の動作のみを説明しているためです。他の回答ではUNUserNotificationCenter 、 iOS 10.
tomacco

12

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:このステップはオプションです。アプリがフォアグラウンドにあるかどうかを確認し、フォアグラウンドにある場合はローカル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)
    }

1
これは、スレッドへのすべての返信を読む必要性の良い例です。以前のスレッドは、デリゲートよりも最後にこのメソッドに言及しており、最後にこの1つはあなたがする必要のある3つのステップすべてに言及しています。完全な回答をありがとうございます。
user3069232

それがあなたを助けたことを知ってよかった。ハッピーコーディング
Prashant Gaikwad

10

アップルのドキュメントによると、はい、アプリの実行中に通知を表示できますここに画像の説明を入力してください


その関数をアプリデリゲートまたは特定のクラスのどこに記述できますか?
iOS開発者

ロードされたビューでそのメソッドを記述したい場合はどうなりますか?
iOS開発者

あなたはどこでも書くことができますが、条件はUNUserNotificationCenterDelegateプロトコルに準拠する必要があります
SPatel

書き込めませんviewDidLoad
SPatel 2018年

1
AppDelegateを拡張することをお勧めしますextension AppDelegate: UNUserNotificationCenterDelegate
SPatel

9

バナーアラートを模倣した独自の通知を作成できます。

1つの方法は、バナーのように見え、タッチにアニメーション化して応答できるカスタムuiviewを作成することです。これを念頭に置いて、さらに多くの機能を備えたさらに優れたバナーを作成できます。

または、それを行うAPIを探して、それらをpodfilesとしてプロジェクトに追加できます。

ここに私が使用したカップルがあります:

https://github.com/terryworona/TWMessageBarManager

https://github.com/toursprung/TSMessages


1
このリンクで質問に答えることができますが、回答の重要な部分をここに含め、参照用のリンクを提供することをお勧めします。リンクされたページが変更されると、リンクのみの回答が無効になる可能性があります。
Robert

1
TWMessageBarManagerシングルトン設計パターンを使用しているため、appdelegate自体を介して簡単に呼び出して使用できます。リンクをありがとう。
Jay Mayu

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


ビューでこの関数をどこに書き込むのがロードされましたか?またはビューコントローラクラスで?
iOS開発者

ネストされた関数としてそれを関数で呼び出すことができる場合はどうなりますか?
iOS開発者

1
これをAppDelegateクラスに配置します。この関数を呼び出す必要はありません。
ミラノジャヤ

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

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を表示するトップ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
    }
}

guard声明はあなたの友達です:-)
ニコラMiari

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

0

上記のように、UserNotification.frameworkこれを実現するにはを使用する必要があります。しかし、私の目的のためにとにかくそれをアプリで表示する必要があり、iOS 11スタイルを持ちたいと思ったので、小さなヘルパービューを作成しました。おそらく誰かに役立つでしょう。

GitHub iOS 11プッシュ通知ビュー


0

このための最良のアプローチUNUserNotificationCenterDelegateAppDelegate、使用して追加することです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)
    }
}

これを呼び出すには、AppDelegateでデリゲートを設定し、didFinishLaunchingWithOptionsこの行を追加する必要があります

UNUserNotificationCenter.current().delegate = self

変更できます

completionHandler(.alert) 

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

0

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

それでおしまい!


-2

@Danial Martineが言ったように、iOSは通知バナー/アラートを表示しません。これは仕様によるものです。しかし、本当にそれをしなければならないなら、一つの方法があります。私も同じことでこれを達成しました。

1.解析フレームワークを解析フレームワークからダウンロードします

2.インポート #import <Parse/Parse.h>

3. didReceiveRemoteNotificationメソッドに次のコードを追加します

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

PFPushは、リモート通知の処理方法を処理します。アプリがフォアグラウンドにある場合はアラートが表示され、そうでない場合は上部に通知が表示されます。


警告?あなたはアラートビューを意味しますか?
iphondroid 2014年

1
しかし、アラートボタンアクションのコールバックを取得する方法
チャーリー

-2

アプリケーションがフォアグラウンド状態の場合は、現在同じアプリを使用していることを意味します。したがって、通常は上部に通知を表示する必要はありません。

ただし、その場合でも通知を表示したい場合は、カスタムアラートビューまたはToastなどのカスタムビューを作成して、通知を受け取ったことをユーザーに示す必要があります。

アプリにそのような機能がある場合は、上部にバッジを表示することもできます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.