ユーザーが受信したプッシュ通知メッセージをクリックしたときに特定のView Controllerを開きたいのですが、プッシュ通知メッセージを受信してメッセージをクリックすると、アプリケーションのみが開きますが、特定のView Controllerにリダイレクトされません。
私のコードは
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if (applicationIsActive) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Bildirim"
message:[NSString stringWithFormat:@"%@ ",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]
delegate:self cancelButtonTitle:@"Ok"
otherButtonTitles:nil];
[alertView show];
UIViewController *vc = self.window.rootViewController;
PushBildirimlerim *pvc = [vc.storyboard instantiateViewControllerWithIdentifier:@"PushBildirimlerim "];
[vc presentViewController:pvc animated:YES completion:nil];
}
}
私の質問は、iOSプッシュ通知に関連しています。
if (applicationIsActive)
状態に問題がある可能性があります。
-didReceiveRemoteNotification
にブレークポイントを設定し、異なるシナリオで実行されるかどうかを確認し、if-条件内に収まるかどうかを確認します。
(ある程度は無関係だがチェックする価値がある)この質問:
バックグラウンドでのdidReceiveRemoteNotification
-didReceiveRemoteNotification
は、アプリが(initially)閉じられ、プッシュ通知をクリックしてアプリを開くと実行されません。
このメソッドは、アプリケーションがフォアグラウンドにあるときにプッシュ通知を受信したとき、またはアプリケーションがバックグラウンドからフォアグラウンドに移行したときに実行されます。
Appleリファレンス: https://developer.Apple.com/documentation/uikit/uiapplicationdelegate
アプリが実行中で、リモート通知を受信した場合、アプリはこのメソッドを呼び出して通知を処理します。このメソッドの実装では、通知を使用して適切な一連のアクションを実行する必要があります。
...
プッシュ通知の到着時にアプリが実行されていない場合、メソッドはアプリを起動し、起動オプション辞書に適切な情報を提供します。アプリは、そのプッシュ通知を処理するためにこのメソッドを呼び出しません。代わりに、application:willFinishLaunchingWithOptions:またはapplication:didFinishLaunchingWithOptions:メソッドは、プッシュ通知ペイロードデータを取得し、適切に応答する必要があります。
だから...アプリが実行されていないときにプッシュ通知が受信され、ユーザーがプッシュ通知をクリックすると、アプリが起動してnow...プッシュ通知の内容は、launchOptions
パラメーターの-didFinishLaunchingWithOptions:
メソッドで利用できます。
言い換えると... -didReceiveRemoteNotification
は今回は実行されず、これも実行する必要があります。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//...
NSDictionary *userInfo = [launchOptions valueForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];
NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];
if(apsInfo) {
//there is some pending Push notification, so do something
//in your case, show the desired viewController in this if block
}
//...
}
ローカルおよびリモート通知の処理に関するAppleのドキュメント も読んでください
識別子名に余分なスペースがあります。削除して試してください:
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
PushBildirimlerim* pvc = [mainstoryboard instantiateViewControllerWithIdentifier:@"PushBildirimlerim"];
[self.window.rootViewController presentViewController:pvc animated:YES completion:NULL];
私は同じ問題を抱えていました。アプリが中断/終了し、プッシュ通知が届くと、アプリは開いているだけで、その通知に対応する特定の画面にリダイレクトされず、ソリューションは、
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
このメソッドのパラメーターlaunchOptions
は、特定の画面にリダイレクトするためにメソッドを呼び出す必要があることを確認することで、通知があるかどうかを通知します
コードは以下の通りです...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//your common or any code will be here at last add the below code..
NSMutableDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification)
{
//this notification dictionary is same as your JSON payload whatever you gets from Push notification you can consider it as a userInfo dic in last parameter of method -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
NSLog(@"%@",notification);
[self showOfferNotification:notification];
}
return YES;
}
次に、メソッドshowOfferNotification:notificationで、次のような対応する画面にユーザーをリダイレクトできます。
//** added code for notification
-(void)showOfferNotification:(NSMutableDictionary *)offerNotificationDic{
//This whole is my coding stuff.. your code will come here..
NSDictionary *segueDictionary = [offerNotificationDic valueForKey:@"aps"];
NSString *segueMsg=[[NSString alloc]initWithFormat:@"%@",[segueDictionary valueForKey:@"alert"]];
NSString *segueID=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"id"]];
NSString *segueDate=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"date"]];
NSString *segueTime=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"time"]];
NSLog(@"Show Offer Notification method : segueMsg %@ segueDate %@ segueTime %@ segueID %@",segueMsg,segueDate,segueTime,segueID);
if ([segueID isEqualToString:@"13"]){
NSString *advertisingUrl=[[NSString alloc]initWithFormat:@"%@",[offerNotificationDic valueForKey:@"advertisingUrl"]];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:segueMsg forKey:@"notificationMsg"];
[defaults setObject:segueDate forKey:@"notifcationdate"];
[defaults setObject:segueTime forKey:@"notifcationtime"];
[defaults setObject:advertisingUrl forKey:@"advertisingUrl"];
[defaults synchronize];
navigationController = (UINavigationController *)self.window.rootViewController;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main_iPhone" bundle: nil];
FLHGAddNotificationViewController *controller = (FLHGAddNotificationViewController*)[mainStoryboard instantiateViewControllerWithIdentifier: @"offerViewController"];
[navigationController pushViewController:controller animated:YES];
}
}
In Swift 4
上記のケースを達成する必要がある場合は、2つのケースを処理する必要があります
ここでは、複数の種類の通知がある場合、カテゴリ(プッシュ通知のペイロードの組み込みパラメーターで通知の種類を識別する)を使用しています。 1種類の通知しかない場合は、カテゴリを確認する必要はありません。
したがって、最初のケースを処理するためのコードは、AppDelegate Fileの次のとおりです。
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
let title = response.notification.request.content.title
//Method- 1 -- By using NotificationCenter if you want to take action on Push notification on particular View Controllers
switch response.notification.request.content.categoryIdentifier
{
case "Second":
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SecondTypeNotification"), object: title, userInfo: userInfo)
break
case "Third":
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ThirdTypeNotification"), object: title, userInfo: userInfo)
break
default:
break
}
///Method -2 --- Check the view controller at the top and then Push to the required View Controller
if let currentVC = UIApplication.topViewController() {
if let currentVC = UIApplication.topViewController() {
//the type of currentVC is MyViewController inside the if statement, use it as you want to
if response.notification.request.content.categoryIdentifier == "Second"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
else if response.notification.request.content.categoryIdentifier == "Third"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
}
}
completionHandler() }
方法1の場合-その後、viewDidLoadで次のようにデフォルトのView Controllerにオブザーバーを追加する必要があります
NotificationCenter.default.addObserver(self,selector: #selector(SecondTypeNotification),
name: NSNotification.Name(rawValue: "SecondTypeNotification"),
object: nil)
NotificationCenter.default.addObserver(self,selector:#selector(ThirdTypeNotification),
name: NSNotification.Name(rawValue: "ThirdTypeNotification"),
object: nil)
方法1の場合-また、オブザーバーで使用されるのと同じ名前で実行されるアクションを追加するための通知オブザーバー関数を2つ追加する必要があります。
// Action to be taken if Push notification is opened and observer is called while app is in background or active
@objc func SecondTypeNotification(notification: NSNotification){
DispatchQueue.main.async
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
@objc func ThirdTypeNotification(notification: NSNotification){
DispatchQueue.main.async
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
self.navigationController?.pushViewController(vc, animated: true)
}
}
そのため、アプリがフォアグラウンドまたはバックグラウンドにあるときに通知が開かれるたびに、上記が実行され、ペイロードのカテゴリに従ってそれぞれのView Controllerに移動します。
2番目のケース
アプリが非アクティブの場合、プッシュ通知が開かれたときに呼び出される最初の関数は
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
return true
}
そのため、プッシュ通知を開くかアプリのアイコンをクリックしてアプリを起動するかどうかをこの関数でチェックする必要があります。このために、規定が用意されています。必要なコードを追加すると、関数は次のようになります。
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
// Register the notification categories.
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
/// Check if the app is launched by opening Push notification
if launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] != nil {
// Do your task here
let dic = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? NSDictionary
let dic2 = dic?.value(forKey: "aps") as? NSDictionary
let alert = dic2?.value(forKey: "alert") as? NSDictionary
let category = dic2?.value(forKey: "category") as? String
// We can add one more key name 'click_action' in payload while sending Push notification and check category for indentifying the Push notification type. 'category' is one of the seven built in key of payload for identifying type of notification and take actions accordingly
// Method - 1
if category == "Second"
{
/// Set the flag true for is app open from Notification and on root view controller check the flag condition to take action accordingly
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
}
else if category == "Third"
{
AppConstants.sharedInstance.userDefaults.set(true, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
// Method 2: Check top view controller and Push to required view controller
if let currentVC = UIApplication.topViewController() {
if category == "Second"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
else if category == "Third"
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
currentVC.navigationController?.pushViewController(vc, animated: true)
}
}
}
return true
}
For Method 1-
After this, check these flags value in the default view controller in viewdidLoad as follows
if AppConstants.sharedInstance.userDefaults.bool(forKey: AppConstants.sharedInstance.kisFromNotificationSecond) == true
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: SecondViewController = storyboard.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(vc, animated: true)
AppConstants.sharedInstance.userDefaults.set(false, forKey: AppConstants.sharedInstance.kisFromNotificationSecond)
}
if AppConstants.sharedInstance.userDefaults.bool(forKey: AppConstants.sharedInstance.kisFromNotificationThird) == true
{
//Land on SecondViewController
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: ThirdViewController = storyboard.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
self.navigationController?.pushViewController(vc, animated: true)
AppConstants.sharedInstance.userDefaults.set(false, forKey: AppConstants.sharedInstance.kisFromNotificationThird)
}
これにより、プッシュ通知が開かれたときに特定のView Controllerを開くという目標が達成されます。
このブログを読むことができます ユーザーが受信したプッシュ通知をタップしたときに特定のView Controllerを開く方法? .