In my plugin.xml, I'm trying to declare a custom .framework and have it weak linked, but once I open Xcode I see the added framework is still marked as "required" instead of "optional".
Here's my plugin.xml entry:
<framework src="ios/libs/BlaBla.framework" custom="true" weak="true" />
It's a 3rd party custom .framework
I've received that contains Headers (obviously) and a shared dynamic lib file (which I will load during runtime using dlopen("TheDylib", RTLD_LAZY|RTLD_GLOBAL);
).
The reason I can't use <header-file src="BlaBla.framework/Headers/Bla.h" />
is that the headers in the .framework
themselves refer to inner headers with #import <BlaBla.framework/SomeHeader.h>
so the <header-file>
tag can't help in this case.
Important note
Better use "Embedded Frameworks" functionality instead of this solution because
dlopen
is forbidden since iOS 8.0 on non-mac/simulator devices (real iPhones/iPads).Take a look at Custom Cordova Plugin: Add framework to "Embedded Binaries"
END OF Important note
I ended up doing something a bit different, Instead of declaring the
.framework
as a<framework ... />
tag, I did the following.I created a plugin hook that adds the plugin dir to the FRAMEWORK_SEARCH_PATHS Xcode build property.
Hook Code:
Note: the hook depends on an NPM dependency named "xcode" so do
npm i xcode --save
before (no need to edit the hook code). Now the way we declare in plugin.xml to import the.framework
content to our project is the following:We use the
source-file
tag simply to import the.framework
because we only want it to be copied to the iOS platform plugins directory, we do not wish to have it "strongly" linked, the reason we need it there is only for it'sHeaders
, not it's binary. Our hook will add the correct framework search path for it.Then we use
resource-file
to import only the shared library file inside the.framework
directory, we add it as a resource so that when the app starts and we calldlopen(...)
, the shared library will be found in runtime.Finally, Now to use the shared library in your plugin code, do the following:
#import <dlfcn.h>
(also import your.framework
's headers).Under
-(void)pluginInitialize
method, load the shared lib:NSString* resourcePath = [[NSBundle mainBundle] resourcePath]; NSString* dlPath = [NSString stringWithFormat: @"%@/FrameworkFileNameInResourceTag", resourcePath]; const char* cdlpath = [dlPath UTF8String]; dlopen(cdlpath, RTLD_LAZY|RTLD_GLOBAL);
Now to use a class from the shared library:
SomeClassInFramework someInstance = [(SomeClassInFramework)[NSClassFromString(@"SomeClassInFramework") alloc] init];