I'm trying to create a Flutter Plugin to use a native library. This library I'm trying to use is stored in a private repository and can be used with Swift Dependency Manager.
This is causing me a headache, cause I can't add a private repository dependency in my plugin (I couldn't find a way to do this in .podspec file), so what I've done:
MyDependency.xcframework
folder to MyPlugin/ios
folders.preserve_paths = 'MyDependency.xcframework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework MyDependency' }
s.vendored_frameworks = 'MyDependency.xcframework'
Doing this I'm able to use MyDependency inside plugin's sources.
My current problem is: This is only working in Simulator.
Before doing this, the project was running without any problem in real devices.
This is the error message I'm receiving every time I tried to run in a real device:
Also, I've made a test using the dependency directly from Swift Dependency Manager and is working fine. I think the problem is the way I'm adding the framework to my plugin.
If you only want to add support for specific enabled platforms, you can do that by supplying the --platforms argument: flutter create --platforms=web,macos . I get the error No option specified for the output directory. when run flutter create or flutter create --platforms web .
When Xcode builds an archive, it builds it for a specific architecture. Therefore if you want to create an XCFramework to run on both iPhone and Simulators, you will need to create two versions of the archive. Here’s the command line for archiving a framework with the iPhone sdk:
Creating the XCFramework is just a matter of a simple command in Terminal; the xcodebuild -create-xcframework. Provided options must contain two things: The path to each framework; in this case it’s going to be the path to the framework inside each package as just said right above.
A XCFramework can wrap up a variant of a framework that would be working on iOS devices, another variant that would be working on Simulator, another one for macOS, one more for watchOS, and so on. In short, XCFramework can bundle up any framework with flavours for any platform or device that Xcode supports.
If your XCFramework includes a library, edit the Header Search Paths and Library Search Paths . If you link against a library that is not part of the same repo, you will need to copy over the public header files as well (in addition of the XCFramework of course!).
I got mine working by adding the following lines to the xxx.podspec
:
s.preserve_paths = 'xxxxxx.xcframework/**/*'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework xxxxxx' }
s.vendored_frameworks = 'xxxxxx.xcframework'
Notice the /**/*
at the end of s.preserve_paths
Here is the full xxx.podspec
file:
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint xxx.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'xxx'
s.version = '1.0.0'
s.summary = 'xxx'
s.description = <<-DESC
xxx is a flutter plugin
DESC
s.homepage = 'https://example.com'
s.license = { :file => '../LICENSE', :type => 'BSD' }
s.author = { 'xxx' => '[email protected]' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '10.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
s.preserve_paths = 'xxxxxx.xcframework/**/*'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework xxxxxx' }
s.vendored_frameworks = 'xxxxxx.xcframework'
end
Make sure to copy the xxxxxx.xcframework
directory to .../xxx/ios/xxxxxx.xcframework
(where your plugin xxx.podspec
is located)
xxxxxx.xcframework
to Pods
scheme to be able to import itThe Frameworks
directory should be below the Pods
scheme when running the flutter command to create a plugin ie.
flutter create --org com.xxx --template=plugin --platforms=android,ios -a java -i swift xxx
Source: Developing packages & plugins
(If not, add it)
Pods
scheme and right-click on Frameworks
Add Files to "Pods"...
ios
directory where the xxxxxx.xcframework
is locatedCopy items if needed
Create folder references
Pods-Runner
xxx
Add
xxxxxx.xcframework
into your project(this should allow you to run/publish to real devices)
Pods
schemeTARGETS
select Pods-Runner
General
tabxxxxx.xcframework
is present underneath Frameworks and Libraries
(if not, add it by clicking on the +)Embed
to Embed & Sign
xxx
xxxxx.xcframework
is present underneath Frameworks and Libraries
Embed
to Embed & Sign
Pods
scheme, the next steps should already be fine, but just check itBuild Phases
Link Binary With Libraries
xxxxx.xcframework
is present, if not add it by clicking the + and that the Status
is set to Required
Now you should be able to import the framework and reference it in your code and should also publish perfectly fine.
Hope this helps, and good luck. I hope this doesn't change again soon
fingers crossed
After doing some research, I've found some links giving me an ideia about the real problem...
To solve this, I've added a simple script to my main project's build process.
This script adds the code signing to inner .framework
files.
cd "${CODESIGNING_FOLDER_PATH}/Frameworks/"
# flatten nested frameworks by copying to APP.app/Frameworks
for framework in *; do
if [ -d "$framework" ]; then
if [ -d "${framework}/Frameworks" ]; then
echo "Moving embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
cp -R "${framework}/Frameworks/" .
rm -rf "${framework}/Frameworks"
fi
fi
done
# remove any leftover nested frameworks (i.e. 'PackageName_359AFEED79E48935_PackageProduct.framework')
for framework in *; do
if [ -d "$framework" ]; then
if [ -d "${framework}/Frameworks" ]; then
echo "Removing embedded frameworks from ${framework} to ${PRODUCT_NAME}.app/Frameworks"
rm -rf "${framework}/Frameworks"
fi
fi
done
# codesign for Debugging on device
if [ "${CONFIGURATION}" == "Debug" ] & [ "${SDKROOT}" != *Simulator* ] ; then
echo "Code signing frameworks..."
find "${CODESIGNING_FOLDER_PATH}/Frameworks" -maxdepth 1 -name '*.framework' -print0 | while read -d $'\0' framework
do
# only sign frameworks without a signature
if ! codesign -v "${framework}"; then
codesign --force --sign "${EXPANDED_CODE_SIGN_IDENTITY}" --preserve-metadata=identifier,entitlements --timestamp=none "${framework}"
echo "Added missing signature to '${framework}'"
fi
done
fi
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With