当应用程序处于后台时接收 Apple 推送通知
Posted
技术标签:
【中文标题】当应用程序处于后台时接收 Apple 推送通知【英文标题】:Receiving Apple Push Notifications when app is in background 【发布时间】:2015-05-04 21:55:47 【问题描述】:我已经在我的 ios8 应用中实现了推送通知。收到通知后,我正在尝试播放音频文件。
当应用程序在前台时,代码正在播放音频,但当应用程序在后台时,没有任何反应。
我已尝试重新生成证书和配置文件。而且我已确保该应用程序在后台运行,即用户没有向上滑动以将其删除。在后台模式下,我启用了远程通知、后台获取以及音频和 Airplay。
我从AppDelegate.m
文件中添加了代码 sn-ps:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
// More code here ---------------------------------------------------
if (launchOptions)
NSDictionary *userInfo = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSDictionary *apsInfo = [userInfo objectForKey:@"aps"];
if (apsInfo) //apsInfo is not nil
[self performSelector:@selector(playCarAlarmAudio)
withObject:nil
afterDelay:1];
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
[[UIApplication sharedApplication] registerForRemoteNotifications];
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
|UIUserNotificationTypeSound
|UIUserNotificationTypeAlert) categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
// More code here ---------------------------------------------------
处理推送通知的委托方法:
-(void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
NSLog(@"Failed to register for push");
-(void) application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
[self respondToEventNotification:userInfo];
-(void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
// [self respondToEventNotification:userInfo];
[self playAlarmAudio];
-(void) respondToEventNotification : (NSDictionary *) userInfo
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
[localNotification setSoundName:@"alarm.mp3"];
[localNotification setFireDate:[NSDate date]];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
[self playAlarmAudio];
然后播放闹钟:
-(void) playAlarmAudio
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"alarm" ofType:@"mp3"];
NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:nil];
self.audioPlayer.numberOfLoops = 1;
[self.audioPlayer play];
【问题讨论】:
【参考方案1】:根据以下 Apple 文档,要播放的通知声音在通知负载字典 (https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html) 中指定:
通知负载
每个远程通知都包含一个有效负载。有效负载包含有关系统应如何提醒用户的信息以及您提供的任何自定义数据。在 iOS 8 及更高版本中,通知负载允许的最大大小为 2 KB; Apple Push Notification 服务拒绝任何超过此限制的通知。 (在 iOS 8 之前和 OS X 中,最大有效负载大小为 256 字节。)
对于每个通知,编写一个 JSON 字典对象(由 RFC 4627 定义)。该字典必须包含另一个由键 aps 标识的字典。 aps 字典可以包含一个或多个指定以下用户通知类型的属性:
向用户显示的警报消息 用于标记应用图标的数字 播放声音
【讨论】:
当我使用沙盒 SSL 证书时,该应用程序似乎运行良好。这是为什么呢? 应用在前台时,可以响应通知并播放声音,但在后台时,它一直在后台,直到用户选择通知激活应用。在此之前,该应用只能执行后台操作,例如下载数据等。但除非您的应用是音频或音乐播放器应用,否则不太可能允许在后台播放声音。 当我使用 Apple 的 Sandbox SSL 证书(用于开发)时,即使应用程序在后台,我也可以使用相同的代码 只有当我从 Sandbox 切换到生产 SSL 时才会出现此问题以上是关于当应用程序处于后台时接收 Apple 推送通知的主要内容,如果未能解决你的问题,请参考以下文章
当应用程序处于后台时,Android 2nd 推送通知有效负载数据未在附加中接收