Using Cocoa (Objective-C) with JUCE

Hi,

I’ve built an audio plugin for Windows that I would now like to compile for mac. JUCE has made the whole thing very nice and easy but now I’m trying to integrate some objective-c and I cannot get it to work. I’ve tried following others posts and looking at how JUCE does it and although it compiles properly, I cannot access cocoa objects outside of the directive where I import the library. This is my code:

test.cpp
if JUCE_WINDOWS
#include <Windows.h>
#elif JUCE_MAC
#import <AppKit/AppKit.h>
NSWindow* t; //Works!
#endif
#include “test.h”
NSWindow* t2; //Error: Unknown type name ‘NSWindow’

test.h
ifndef CONTROLMODALDIALOG_H_INCLUDED
#define CONTROLMODALDIALOG_H_INCLUDED

#include “otherHeader1.h”
#include “otherHeader2.h”

test.mm
#include “test.cpp”

If I create an NSWindow object right after importing the library in the same #if directive then it compiles no problem but if I create the object anywhere else in my code then it does not recognize it. What am I doing wrong here? Any help would be greatly appreciated!!

Add this line at the start of test.cpp:

#include <juce_core/juce_core.h>

If you don’t include anything from JUCE before testing JUCE_WINDOWS / JUCE_MAC, they aren’t defined at all.

So this part isn’t being compiled:

#import <AppKit/AppKit.h>
NSWindow* t; //Works!

You could type anything in there and your project would compile.

You can get compile errors if you include the juce headers before the system headers. Redefinition of Component I think. Probably better to just use #if __APPLE__ or #if _WIN32

1 Like

Thank you for the quick responses! I tried your suggestions and I realized that there are a few other issues at play here. I re-organized my code so that test.h is the first thing included in test.cpp. test.h includes other headers which themselves include “JuceHeader.h” so if that is first in my file then JUCE_MAC and JUCE_WINDOWS are defined first.

test.cpp
define JUCE_CORE_INCLUDE_NATIVE_HEADERS 1
#include “ControlModalDialog.h”

#if JUCE_WINDOWS
#include <Windows.h>
#elif JUCE_MAC
#define Point CarbonDummyPointName
#define Component CarbonDummyCompName
#import <AppKit/AppKit.h>
#undef Point
#undef Component
#endif

test.h
ifndef CONTROLMODALDIALOG_H_INCLUDED
#define CONTROLMODALDIALOG_H_INCLUDED

#include “otherHeader1.h” //this header includes JuceHeader.h
#include “otherHeader2.h” //this header includes JuceHeader.h

test.mm
#include “test.cpp”

However now I am receiving “Expected Unqualified-id” errors which trace back to the JuceHeader.h file so I’m not sure how to fix it. I did some more testing and noticed that if both test.cpp and test.mm are included in the project then only test.cpp gets compiled. The only way test.mm is compiled is if I remove test.cpp from my project. I thought that the Projucer would choose .mm instead of .cpp if the file name is the same but it seems like XCode is compiling .cpp instead of .mm if both are present.

Is there a flag that needs to be set to tell the projucer/xcode to compile .mm files instead of .cpp files if they have the same name? From everything I’m reading it sounds like this is supposed to be done automatically but it’s very apparent in my testing that xcode is ignoring the .mm file if the .cpp file is also in the project. If I remove the .cpp file then everything compiles correctly. I feel like I must be missing something obvious but I don’t have much experience with this so any suggestions would be greatly appreciated!

I believe this only happens automatically when you are creating a juce module. I don’t think there is a good way to do this from projucer.

I usually add foo_win.cpp and foo_mac.mm and the both include foo.cpp which is set to not compile.