Here’s a pattern I recently learned for integrating objectiveC stuff so it appears like regular JUCE classes, via the Listener pattern:
//Foo.h
struct Foo
{
Foo();
enum NativeAction
{
a, b, c, //etc
};
void handleNativeAction(NativeAction nativeAction);
struct Listener
{
virtual ~Listener() { }
virtual void nativeActionCallback(Foo*, NativeAction&) = 0;
};
Array<Listener*> listeners;
void addListener( Listener* L ) { listeners.addIfNotAlreadyThere( L ); }
void removeListener( Listener* L ) { listeners.removeFirstMatching( L ); }
//don't forget your listener locks!
};
//Foo.mm file
#include "Foo.h"
#import //CoreFoundations.h or UIKit or whatever
@interface MyObjCWrapper : NSObject
{
Foo* myFoo;
//other data members
};
//member functions of MyObjCWrapper
-(id) init;
-(void) setOwner:(Foo*)owner;
-(void) someCallback:(ArgType)args;
@end
@implementation MyObjCWrapper
-(id)init
{
if( self = [super init] )
{
//do all of the setup into native iOS calls here so
//someCallback gets called when the native callbacks are triggered
}
return self;
}
-(void) setOwner:(Foo*)owner
{
myFoo = owner;
}
-void someCallback:(ArgType)args
{
//convert args to Foo::NativeAction
Foo::NativeAction fooArg = convert(args);
myFoo->handleNativeAction(fooArg); //pass it to Foo instance
}
@end
//Foo implementation
Foo::Foo()
{
//I'm not sure how this doesn't leak.
//it probably doesn't matter on iOS, tbh because Apple just hard-crashes
//apps when memory is needed.
//maybe Foo needs a destructor to release this properly?
MyObjCWrapper* wrapper = [[MyObjCWrapper alloc] init];
[wrapper setOwner:this];
}
void Foo::handleNativeAction(NativeAction someParam)
{
//now your objC result has been passed to pure C++
for( auto* listener : listeners )
listener->nativeActionCallback(this, someParam);
}
Just add a Foo member to your class, and register your class as a Foo::Listener
struct MyClass : public Foo::Listener
{
void nativeActionCallback(Foo*, Foo::NativeAction& action) override
{
//tadah, your ObjC results get passed to JUCE here.
}
Foo foo;
MyClass() { foo.addListener(this); }
};
I’m not sure if that answers your question, but you can probably use this to wrap that openURL objectiveC function into a JUCE listener-based class.
