Search code examples
iphoneobjective-ciosavaudioplayersubclassing

How to subclass or store extra information in AVAudioPlayer player objects


I need to create a new NSNumber or integer property called primaryKey to be included with all AVAudioPlayer objects that I create so that I can read the value of that property within the audioPlayerDidFinishPlaying callback and know exactly which database record was played.

The reason I need to do this is: I can't use the player URL property to determine which database record it was since the same sound file can be used multiple times within the playlist.

How can I add a new property to an existing iOS class like this?


Example:

AVAudioPlayer *newAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];  

self.theAudio = newAudio; // automatically retain audio and dealloc old file if new file is loaded
if (theAudio != nil) [audioPlayers addObject:theAudio];

[newAudio release];

[theAudio setDelegate: theDelegate];
[theAudio setNumberOfLoops: 0];
[theAudio setVolume: callVolume];

// This is the new property that I want to add
[theAudio setPrimaryKey: thePrimaryKey];

[theAudio play];

Then I'd retrieve it in the callback like this:

- (void) audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag 
{    
   NSNumber *finishedSound = [NSNumber numberWithInt:[player primaryKey]];

   // Do something with this information now...
}

Solution

  • You can create a subclass and add your property just like you would when subclassing anything.

    Interface

    @interface MyAudioPlayer : AVAudioPlayer
    
    @property (nonatomic) int primaryKey;
    
    @end
    

    Implementation

    @implementation MyAudioPlayer
    
    @synthesize primaryKey = _primaryKey;
    
    @end
    

    Creating

    MyAudioPlayer *player = [[MyAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
    player.primaryKey = thePrimaryKey;
    ...
    

    Delegate

    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag {
        if ([player isKindOfClass:[MyAudioPlayer class]]) {
            MyAudioPlayer *myPlayer = (MyAudioPlayer *)player;
            NSNumber *primaryKeyObject = [NSNumber numberWithInt:myPlayer.primaryKey];
            ...
        }
    }