当应用程序打开并在前台显示股票iOS通知横幅?
当苹果的官方iOS消息应用程序处于打开状态并处于前台时,来自其他联系人的新消息触发股票,iOS本地通知警报横幅。 看下面的图片。
这可能在App Store上的第三方应用程序? 在应用程序打开并处于前台的情况下为您的应用程序提供本地和/或推送通知?
在testing我的应用程序时 ,会收到通知,但不会显示iOS提醒UI 。
但是这种行为在苹果的官方消息应用程序中看到:
本地和远程通知编程指南说:
当操作系统提供本地通知或远程通知,并且目标应用程序未在前台运行时 ,它可以通过警报 ,图标徽章号或声音向用户显示通知。
如果应用程序在传递通知时在前台运行,则应用程序委托会收到本地或远程通知。
所以是的,我们可以在前台收到通知数据 。 但我看不出本机iOS通知警报用户界面 。
-(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上build议任何第三方的“敬酒”popup式警报等等。我只是感兴趣,如果这可以使用股票iOS本地或推送通知警报用户界面, 而你的应用程序是开放和在前台 。
iOS 10添加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;
UNNotificationPresentationOptions标志允许您指定UNNotificationPresentationOptionAlert
以使用通知提供的文本显示警报。
这是关键,因为它允许您在应用程序处于打开状态时显示警报,并在 iOS 10的新版本的前台显示警报。
示例代码:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler(.alert) }
要在app处于前台时显示横幅消息,请使用以下方法。
iOS 10,Swift 3 :
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler(UNNotificationPresentationOptions.alert) }
要在应用程序打开时显示通知,我们需要手动处理。 所以我在下面做的是处理收到的通知。
在AppDelegate.m中添加下面的所有内容
- 处理呼叫通知
- 创build视图,添加AppIcon,通知消息并将其显示为animation
- 添加触摸识别器删除如果触摸或在5秒内删除与animation。
让我知道如果这是一个好的解决scheme。 为我工作很好,但不确定这是否正确。
- (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
添加有效content-available:1
调用content-available:1
。 最后的有效载荷应该是这样的:
{ "aps":{ "alert":"Testing.. (7)", "badge":1,"sound":"default" }, "content-available":1 }
编辑:
前景提醒现在可以在iOS 10! 请看这个答案 。
对于iOS 9及以下版本:
当您的应用程序打开并处于前台时,似乎无法显示股票iOS通知警报。 Messages.app必须使用私有API。
系统不显示任何警报,标记应用程序的图标,或者当应用程序已经在最前面时播放任何声音。 – UILocalNotification文档
UIApplicationDelegate
方法仍将被调用,允许您的应用程序响应本地或远程通知:
application:didReceiveLocalNotification: application:didReceiveRemoteNotification:
但是,股票iOS通知警报横幅用户界面将不会显示在Apple的Messages.app中,该用户必须使用私有API。
你可以做的最好的是滚动你自己的警报横幅或使用现有的框架:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // Use a 3rd party toast alert framework to display a banner [self toastAlertFromGithub] }
我在这里打开了这个行为的雷达:rdar:// 22313177
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的应用程序处于活动状态时,我可以显示推送通知。
1 /从服务器的推送通知应保持沉默 。
2 /当从服务器接收远程通知时,您发送本地通知并为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)") } }
ApplicationDelegate的UNUserNotificationCenterDelegate
实现
@available(iOS 10.0, *) public func userNotificationCenter(_ center : UNUserNotificationCenter, willPresent notification : UNNotification, withCompletionHandler completionHandler : @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert]) // only-always show the alert }
要显示本地通知,这是最好的select。 需要更less的代码赖特“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)