syedfa
syedfa

Reputation: 2809

Need to convert method from Objective-C to just C in iOS

I am working on iOS app that has a file of the form .mm, and contains code entirely in C. I have the following blocks of code that I need to put inside this file:

void initAudioSession()
{
    BOOL success = NO;
    NSError *error = nil;

    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setActive:YES error:&error];


//the above code is the method where the block below goes in

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

which in turn calls the following method:

- (void)audioSessionDidChangeInterruptionType:(NSNotification *)notification
{
    AVAudioSessionInterruptionType interruptionType = [[[notification userInfo]
    objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
    if (AVAudioSessionInterruptionTypeBegan == interruptionType)
    {
    }
    else if (AVAudioSessionInterruptionTypeEnded == interruptionType)
    {
    }
}

Both blocks of code that I've posted above are in Objective-C, and I need to convert both of them to C, and put them inside the .mm file. The problem is that I don't have a C background, and not sure what changes I need to make to do this. One obvious problem I'm having is that the compiler is not recognizing the keyword self. Why is it not recognizing self, and what should it be changed to in C?

Upvotes: 0

Views: 316

Answers (1)

kdhp
kdhp

Reputation: 2116

To write Objective-C code in C you have to use the C API for Objective-C, the headers can be found as <objc/objc.h>, <objc/runtime.h>, and <objc/message.h>. You can call selectors that you get from sel_registerName with objc_msgSend, and get classes with objc_getRequiredClass and objc_getClass. Note that I am listing the easiest ones to use, there are functions for everything needed to make Objective-C work.

Here is your second code block in this style. The magic numbers were found in the header file that cannot be read by C. Also note that code compiled from Objective-C code will probably be more efficient, because of value caching and things like that.

extern id *const AVAudioSessionInterruptionTypeKey;
void audioSessionDidChangeInterruptionType(id self, SEL _cmd, id notification) {
    SEL userInfo = sel_registerName("userInfo");
    SEL objectForKey = sel_registerName("objectForKey:");
    SEL unsignedIntegerValue = sel_registerName("unsignedIntegerValue");
    id tmpid = objc_msgSend(notification, userInfo);
    tmpid = objc_msgSend(tmpid, objectForKey, AVAudioSessionInterruptionTypeKey);
    unsigned interruptionType = objc_msgSend(tmpid, unsignedIntegerValue);
    if (interruptionType == 1) {
        // AVAudioSessionInterruptionTypeBegan
    } else {
        // AVAudioSessionInterruptionTypeEnded
    }
}

It might be worth checking if your code can be ported to apples C audio API CoreAudio, it would probably work better than any C conversion.

Upvotes: 1

Related Questions