How to manually add a .xcframework to a Flutter iOS Plugin?
Solution 1
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
Solution 2
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)
Add xxxxxx.xcframework
to Pods
scheme to be able to import it
The 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)
- Navigate to
Pods
scheme and right-click onFrameworks
- Click
Add Files to "Pods"...
- Navigate to the root of the
ios
directory where thexxxxxx.xcframework
is located - Uncheck
Copy items if needed
- Select
Create folder references
- Check
Pods-Runner
- Check your plugin ie.
xxx
- Click
Add
Embed xxxxxx.xcframework
into your project
(this should allow you to run/publish to real devices)
- Click on the
Pods
scheme - In
TARGETS
selectPods-Runner
- Click on the
General
tab - Ensure the
xxxxx.xcframework
is present underneathFrameworks and Libraries
(if not, add it by clicking on the +) - Change
Embed
toEmbed & Sign
- Click on your plugin ie.
xxx
- Ensure the
xxxxx.xcframework
is present underneathFrameworks and Libraries
- Change
Embed
toEmbed & Sign
- Again, for both targets below
Pods
scheme, the next steps should already be fine, but just check it - Click
Build Phases
- Click
Link Binary With Libraries
- Ensure
xxxxx.xcframework
is present, if not add it by clicking the + and that theStatus
is set toRequired
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
Comments
-
siega over 1 year
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:
- I've added the plugin to the Example project with Swift Package Manager
- Manually copied
MyDependency.xcframework
folder toMyPlugin/ios
folder - Referenced it in podspec file, like this:
s.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.