Appleの公式iOSメッセージアプリが開いてフォアグラウンドにあるとき、他の連絡先からの新しいメッセージが、ストックのネイティブiOS通知アラートバナーをトリガーします。下の画像をご覧ください。
これはApp Storeのサードパーティアプリで可能ですか?アプリがopenでフォアグラウンドにある場合のアプリのローカルおよび/またはプッシュ通知?
my appをテストすると、通知は受信されますが、iOSアラートUIは表示されません。
しかし、この動作isはAppleの公式メッセージアプリで見られます。
オペレーティングシステムがローカル通知またはリモート通知を配信し、ターゲットアプリがフォアグラウンドで実行されていないの場合、alert、アイコンバッジ番号、またはサウンド。
通知の配信時にアプリがforegroundで実行されている場合、アプリのデリゲートはローカルまたはリモートの通知を受け取ります。
そのため、フォアグラウンドで通知データを受信できます。しかし、iOSネイティブアラート通知UIを表示する方法はありません。
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
// I know we still receive the notification `userInfo` payload in the foreground.
// This question is about displaying the stock iOS notification alert UI.
// Yes, one *could* use a 3rd party toast alert framework.
[self use3rdPartyToastAlertFrameworkFromGithub]
}
次に、メッセージはプライベートAPIを使用して、フォアグラウンドでアラートを表示しますか?
この質問の目的のために、githubなどでサードパーティの「トースト」ポップアップアラートを提案しないでくださいgithubなどでこれができる場合にのみ興味がありますstock、ネイティブiOSローカルまたはプッシュ通知アラートUIを使用して、アプリケーションが開いてフォアグラウンドにある。
iOS 1は、アプリがフォアグラウンドにあるときに通知を処理するためのプロトコル UNUserNotificationCenterDelegate
を追加します。
UNUserNotificationCenterDelegate
プロトコルは、通知を受信し、アクションを処理するためのメソッドを定義します。アプリがフォアグラウンドにあるとき、到着した通知はシステムインターフェイスを使用して自動的に表示されるのではなく、デリゲートオブジェクトに配信されます。
迅速:
optional func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
Objective-C:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;
NNotificationPresentationOptions フラグを使用すると、UNNotificationPresentationOptionAlert
を指定して、通知で提供されるテキストを使用してアラートを表示できます。
これは、アラートを表示できるため重要ですアプリが開いている最前面にある間。これはiOS 10の新機能です。
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler(.alert)
}
アプリがフォアグラウンドにあるときにバナーメッセージを表示するには、次の方法を使用します。
iOS 10、Swift:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
編集:
IOS 10でフォアグラウンドアラートが可能になりました! この回答をご覧ください 。
iOS 9以下の場合:
アプリが開いてフォアグラウンドにある場合、iOSの通知通知を表示することはできないようです。 Messages.appはプライベートAPIを使用している必要があります。
システムは、アプリが既に最前面にある場合、アラートを表示したり、アプリのアイコンにバッジを付けたり、サウンドを再生したりしません。 - ILocalNotification docs
UIApplicationDelegate
メソッドは引き続き呼び出され、アプリがローカルまたはリモートの通知に応答できるようにします。
application:didReceiveLocalNotification:
application:didReceiveRemoteNotification:
ただし、ネイティブのiOS通知アラートバナーUIは、プライベートAPIを使用する必要があるAppleのMessages.appにあるように表示されません。
最善の方法は、独自のアラートバナーをロールするか、既存のフレームワークを使用することです。
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
// Use a 3rd party toast alert framework to display a banner
[self toastAlertFromGithub]
}
ここでこの動作のレーダーを開きました:rdar://22313177
アプリが開いているときに通知を表示するには、手動で処理する必要があります。したがって、以下で行うことは、受信した通知を処理することです。
以下をすべてAppDelegate.mに追加します
これが適切なソリューションかどうかを教えてください。私にとってはうまくいきましたが、これが正しい方法かどうかはわかりません。
- (void)application:(UIApplication *)applicationdidReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSString *notifMessage = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];
//Define notifView as UIView in the header file
[_notifView removeFromSuperview]; //If already existing
_notifView = [[UIView alloc] initWithFrame:CGRectMake(0, -70, self.window.frame.size.width, 80)];
[_notifView setBackgroundColor:[UIColor blackColor]];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,15,30,30)];
imageView.image = [UIImage imageNamed:@"AppLogo.png"];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(60, 15, self.window.frame.size.width - 100 , 30)];
myLabel.font = [UIFont fontWithName:@"Helvetica" size:10.0];
myLabel.text = notifMessage;
[myLabel setTextColor:[UIColor whiteColor]];
[myLabel setNumberOfLines:0];
[_notifView setAlpha:0.95];
//The Icon
[_notifView addSubview:imageView];
//The Text
[_notifView addSubview:myLabel];
//The View
[self.window addSubview:_notifView];
UITapGestureRecognizer *tapToDismissNotif = [[UITapGestureRecognizer alloc] initWithTarget:self
action:@selector(dismissNotifFromScreen)];
tapToDismissNotif.numberOfTapsRequired = 1;
tapToDismissNotif.numberOfTouchesRequired = 1;
[_notifView addGestureRecognizer:tapToDismissNotif];
[UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{
[_notifView setFrame:CGRectMake(0, 0, self.window.frame.size.width, 60)];
} completion:^(BOOL finished) {
}];
//Remove from top view after 5 seconds
[self performSelector:@selector(dismissNotifFromScreen) withObject:nil afterDelay:5.0];
return;
}
//If the user touches the view or to remove from view after 5 seconds
- (void)dismissNotifFromScreen{
[UIView animateWithDuration:1.0 delay:.1 usingSpringWithDamping:0.5 initialSpringVelocity:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{
[_notifView setFrame:CGRectMake(0, -70, self.window.frame.size.width, 60)];
} completion:^(BOOL finished) {
}];
}
アプリがフォアグラウンドまたはオープンステージ、iOS 10およびSwift 2.3のときにプッシュ通知を受信するコードを次に示します。
@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
のコードを使用します。
メソッドuserNotificationCenter(_:willPresent:withCompletionHandler:)
は、属性content-available:1
をペイロードに追加する場合にのみ呼び出されます。最終的なペイロードは次のようになります。
{
"aps":{
"alert":"Testing.. (7)",
"badge":1,"sound":"default"
},
"content-available":1
}
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.body = body;
content.userInfo = userInfo;
content.sound = [UNNotificationSound defaultSound];
[content setValue:@(YES) forKeyPath:@"shouldAlwaysAlertWhileAppIsForeground"];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"Notif" content:content trigger:nil];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
DLog(@"Error:%@", error);
}];
アプリがアクティブなときにプッシュ通知を表示できますiOS 10。
サーバーからのプッシュ通知はsilentでなければなりません。
サーバーからリモート通知を受信すると、ローカル通知を送信し、keyPath:shouldAlwaysAlertWhileAppIsForeground = Trueの値を設定します
通知を自分で処理して、カスタムアラートを表示できます。 Viber、Whatsapp、BisPhoneなどのアプリはこのアプローチを使用します。
サードパーティのカスタムアラートの一例は、 CRToast です。
アプリがフォアグラウンドにあるときにローカル通知をスケジュールしてみると、ストックiOSアラートが表示されないことがわかります。
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 3バージョン
これは、アプリケーションがフォアグラウンドにあるときにアラートを示します。
if #available(iOS 10.0, *)
{
// need to setup the global notification delegate somewhere when your app starts
//
UNUserNotificationCenter.current().delegate = applicationDelegate
// to show a message
//
let content = UNMutableNotificationContent()
content.body = "MESSAGE"
let request = UNNotificationRequest(identifier: "fred", content: content, trigger: nil)
UNUserNotificationCenter.current().add(request)
{
error in // called when message has been sent
debugPrint("Error: \(error)")
}
}
UNUserNotificationCenterDelegate
のApplicationDelegateの実装
@available(iOS 10.0, *)
public func userNotificationCenter(_ center : UNUserNotificationCenter, willPresent notification : UNNotification, withCompletionHandler completionHandler : @escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler([.alert]) // only-always show the alert
}
ローカル通知を表示するには、これが最適なオプションです。 「BRYXBanner」をライトするために必要なコードが少ない https://cocoapods.org/pods/BRYXBanner
let banner = Banner(title: "title", subtitle: "subtitle", image: UIImage(named: "addContact"), backgroundColor: UIColor(red:137.0/255.0, green:172.0/255.0, blue:2.0/255.0, alpha:1.000))
banner.dismissesOnTap = true
banner.show(duration: 1.0)
デプロイメントターゲットがiOS10以上の場合、以下のようなUNUserNotificationを使用します。
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
// Change this to your preferred presentation option
completionHandler([.alert, .sound])
}