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. Как это делают уведомления? Или я просто ошибаюсь в отношении цели вышеуказанного кода?

Ответ 1

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

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

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

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

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

Ответ 2

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

[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];
}

Ответ 3

Я нашел об этом на форумах 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

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

Ответ 4

Я не тестировал это, но в соответствии с этим сообщением: 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];

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