AudioServicesPlayAlertSound 在应用程序期间未播放自定义声音:didReceiveRemoteNotification:

Posted

技术标签:

【中文标题】AudioServicesPlayAlertSound 在应用程序期间未播放自定义声音:didReceiveRemoteNotification:【英文标题】:AudioServicesPlayAlertSound not playing custom sound during application:didReceiveRemoteNotification: 【发布时间】:2013-09-22 15:29:37 【问题描述】:

我希望其他人能洞察这个问题...

我正在尝试播放加载到我的应用资源中的自定义声音。根据将音频转换为CAF format for playback on iPhone using OpenAL 线程中的建议,我使用 afconvert 工具创建了声音。为生成我的自定义声音文件而执行的具体命令是:

afconvert ~/Desktop/moof.au ~/Desktop/moof.caf -d ima4 -f caff -v

当我在测试设备(iPhone 5、ios 7.0 或 iPhone 4、iOS 6.1.3)上运行我的应用并发送包含我的自定义声音文件名称的推送通知时,设备会振动但没有声音播放。

这里有点奇怪...如果我在播放声音的方法开始处设置断点,并单步执行代码,设备会播放自定义声音并振动以响应推送通知!

这是有问题的代码:

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

    // If the app is running and receives a remote notification, the app calls this method to process
    // the notification payload. Your implementation of this method should use the app state to take an
    // appropriate course of action.

    ALog(@"push data package: %@", userInfo);
    NSDictionary *payload = [userInfo objectForKey:@"aps"];
    NSNumber *badgeNumber = [payload objectForKey:@"badge"];
    NSString *soundName = [payload objectForKey:@"sound"];

    // app is in foreground
    if (application.applicationState == UIApplicationStateActive) 
        ALog(@"active");
        if (badgeNumber) 
            application.applicationIconBadgeNumber = [badgeNumber integerValue];
        
        [self playPushNotificationAlertSound:soundName];
    
    // app is in background
    else if (application.applicationState == UIApplicationStateBackground) 
        ALog(@"background");
        if (badgeNumber) 
            application.applicationIconBadgeNumber = [badgeNumber integerValue];
        
        [self playPushNotificationAlertSound:soundName];
    
    // app was launched from inactive state
    else if ((application.applicationState == UIApplicationStateInactive)) 
        ALog(@"inactive");
        if (badgeNumber) 
            application.applicationIconBadgeNumber = [badgeNumber integerValue];
        
    


- (void)playPushNotificationAlertSound:(NSString *)soundName

    ALog(@"soundName = '%@'", soundName);

    if (![soundName isEqualToString:@"default"]) 

        NSURL *soundURL = [[NSBundle mainBundle] URLForResource:soundName withExtension:@"caf"];

        if (soundURL) 
            CFURLRef soundFileURLRef = (__bridge CFURLRef)soundURL;
            SystemSoundID soundFileObject = 0;
            OSStatus status = AudioServicesCreateSystemSoundID(soundFileURLRef, &soundFileObject);
            if (status == kAudioServicesNoError) 
                AudioServicesPlayAlertSound(soundFileObject);
                AudioServicesDisposeSystemSoundID(soundFileObject);
            
            ALog(@"soundFileURLRef = %@", soundFileURLRef);
            ALog(@"soundFileObject = %i, status = %i", (unsigned int)soundFileObject, (int)status);
        
    

这是没有激活断点的控制台日志,也没有播放自定义声音:

2013-09-22 11:02:40.123 MyAppUnderDevelopment[2489:60b] push data package: 
    "_" = BlyZ4SOYEeOEc5DiugJ6IA;
    aps =     
        alert = "Test #1";
        badge = 1;
        sound = moof;
    ;

2013-09-22 11:02:40.124 MyAppUnderDevelopment[2489:60b] active
2013-09-22 11:02:40.136 MyAppUnderDevelopment[2489:60b] soundName = 'moof'
2013-09-22 11:02:40.138 MyAppUnderDevelopment[2489:60b] soundFileURLRef = file:///var/mobile/Applications/31785684-2EFA-4FEB-95F3-3A6B82B16A4A/MyAppUnderDevelopment.app/moof.caf
2013-09-22 11:02:40.139 MyAppUnderDevelopment[2489:60b] soundFileObject = 4100, status = 0

并且断点处于活动状态、单步执行和声音播放的控制台日志:

2013-09-22 11:03:29.891 MyAppUnderDevelopment[2489:60b] push data package: 
    "_" = "I_yGQCOYEeO515DiugJkgA";
    aps =     
        alert = "Test #2";
        badge = 2;
        sound = moof;
    ;

2013-09-22 11:03:29.892 MyAppUnderDevelopment[2489:60b] active
2013-09-22 11:03:33.752 MyAppUnderDevelopment[2489:60b] soundName = 'moof'
2013-09-22 11:03:40.757 MyAppUnderDevelopment[2489:60b] soundFileURLRef = file:///var/mobile/Applications/31785684-2EFA-4FEB-95F3-3A6B82B16A4A/MyAppUnderDevelopment.app/moof.caf
2013-09-22 11:03:45.356 MyAppUnderDevelopment[2489:60b] soundFileObject = 4101, status = 0

对出了什么问题有什么有用的想法吗?

【问题讨论】:

【参考方案1】:

在准备好我的问题后,我正在运行我的测试序列,以确保我正确记录了我所采取的步骤。在单步快速浏览代码时,我发现调用...

            AudioServicesPlayAlertSound(soundFileObject);
            AudioServicesDisposeSystemSoundID(soundFileObject);

...这样会导致soundFileObject 在异步声音有机会播放之前被释放。短期的解决方案是将 soundFileObject 变成一个保留属性,并根据需要使用惰性实例化来创建它。

希望这可以帮助其他可能会撞到墙上的人。

【讨论】:

以上是关于AudioServicesPlayAlertSound 在应用程序期间未播放自定义声音:didReceiveRemoteNotification:的主要内容,如果未能解决你的问题,请参考以下文章