Cocos2D 2.1: делегат устарел в iOS 6. Как установить делегата для этого AVAudioSession?

Запустил шаблон Cocos2D 2.1 (без физического движка) в Xcode 4.5, предназначенный для iOS 6 и iPad. В файле CDAudioManager.m следующий код...

AVAudioSession* session = [AVAudioSession sharedInstance];
session.delegate = self;  // Which is what is automatically generated by the template.

... генерирует следующее предупреждение...

"delegate deprecated:  first deprecated in iOS 6"

Итак, я обращаюсь к документации разработчика Apple, и в разделе «Делегировать» говорится: «Устарело в iOS 6.0. Вместо этого используйте уведомления, описанные в разделе «Уведомления» этого класса».

http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioSession_ClassReference/DeprecationAppendix/AppendixADeprecatedAPI.html#//apple_ref/occ/instp/AVAudioSession/delegate

Проблема в том, что мне кажется, что все, что мы пытаемся сделать — простите мою неопытность — установить делегата для AVAudioSession в сам экземпляр CDAudioManager. Как уведомления делают это? Или я просто ошибаюсь в отношении цели приведенного выше кода?


person baptzmoffire    schedule 25.10.2012    source источник


Ответы (4)


Ошибка, с которой вы сталкиваетесь, находится в этом блоке кода

AVAudioSession* session = [AVAudioSession sharedInstance];
session.delegate = self;// <-------- DEPRECATED IN IOS 6.0

Чтобы отключить предупреждение, измените эти 2 строки на это:

[[AVAudioSession sharedInstance] setActive:YES error:nil];

Надеюсь это поможет.

person Jason P.    schedule 09.11.2012
comment
Apple отказалась от установки делегата и протокола AVAudioSessionDelegate в iOS 6, и теперь вместо этого вам нужно прослушивать уведомления через центр NSNotification. - person geekinit; 28.12.2013
comment
Этот ответ выглядит неполным. - person Bijoy Thangaraj; 14.01.2014

Вместо использования делегата используйте уведомление для обработки следующим образом

[AVAudioSession sharedInstance];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil];

 - (void) interruption:(NSNotification*)notification
   {
    NSDictionary *interuptionDict = notification.userInfo;

    NSUInteger interuptionType = (NSUInteger)[interuptionDict valueForKey:AVAudioSessionInterruptionTypeKey];

   if (interuptionType == AVAudioSessionInterruptionTypeBegan)
        [self beginInterruption];

    else if (interuptionType == AVAudioSessionInterruptionTypeEnded)
        [self endInterruption];
}
person Gowtham R    schedule 04.10.2013

Я нашел сообщение об этом на форумах Cocos2D-iPhone.org. Хотя я не совсем понимаю это, но я работаю над этим, похоже, что это решило проблему, по крайней мере временно. Что он сделал, так это записал этот метод в файл CDAudioManger.m:

-(void) releaseBufferForFile:(NSString *) filePath {
    int bufferId = [self bufferForFile:filePath create:NO];
    if (bufferId != kCDNoBuffer) {
        [soundEngine unloadBuffer:bufferId];
        [loadedBuffers removeObjectForKey:filePath];
        NSNumber *freedBufferId = [[NSNumber alloc] initWithInt:bufferId];
        [freedBufferId autorelease];
        [freedBuffers addObject:freedBufferId];
    }
}
@end

- (void) interruption:(NSNotification*)notification
{
    NSDictionary *interuptionDict = notification.userInfo;
            NSNumber* interuptionTypeValue = [dict valueForKey:AVAudioSessionInterruptionTypeKey];
    NSUInteger interuptionType = [interuptionTypeValue intValue];

    if (interuptionType == AVAudioSessionInterruptionTypeBegan)
        [self beginInterruption];
#if __CC_PLATFORM_IOS >= 40000
    else if (interuptionType == AVAudioSessionInterruptionTypeEnded)
        [self endInterruptionWithFlags:(NSUInteger)[interuptionDict valueForKey:AVAudioSessionInterruptionOptionKey]];
#else
    else if (interuptionType == AVAudioSessionInterruptionTypeEnded)
        [self endInterruption];
#endif
}

Потом заменил:

AVAudioSession *session = [AVAudioSession sharedInstance];
session.delegate = self;

с этим:

[AVAudioSession sharedInstance];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil];

Вот ссылка: http://www.cocos2d-iphone.org/forum/topic/49956

Если и когда я лучше пойму, что делает этот код, я обязательно отредактирую этот пост.

person baptzmoffire    schedule 26.10.2012
comment
У меня нет CDAudioManager.m - person iWizard; 20.12.2012
comment
Ссылка, которую вы показали, также говорит о проблемах с использованием этой новой формы в центре NSNotification, выдает ошибку Bad Access в этой строке с iOS 5.0 ... оооо, какое конкретное решение? они предлагают проверить версию iOS и соответственно выбросить код. - person S.H.; 29.04.2013
comment
Эта строка просто неверна: NSUInteger interuptionType = (NSUInteger) [interuptionDict valueForKey: AVAudioSessionInterruptionTypeKey]; Это должно быть NSNumber* interuptionType = [dict valueForKey:AVAudioSessionInterruptionTypeKey]; переключатель ([interuptionType integerValue]) { - person Cherpak Evgeny; 26.11.2013

Я не проверял это, но согласно этому сообщению: http://www.cocos2d-iphone.org/forums/topic/cdaudiomanager-line-402-delegate-is-deprecated/#post-390211

float osVersion = [[UIDevice currentDevice].systemVersion floatValue];
if (osVersion >=6.0)
{
[AVAudioSession sharedInstance];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil];
}
else
{
AVAudioSession* session = [AVAudioSession sharedInstance];
session.delegate = self;
}

т.е. бросать разное время выполнения кода в зависимости от версии iOS.

В любом случае, мое приложение только для iOS 6.0+, поэтому я просто выберу:

[AVAudioSession sharedInstance];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(interruption:) name:AVAudioSessionInterruptionNotification object:nil];

И скрестить большие пальцы.

person Jonny    schedule 01.08.2013