Unable to add iOS dependency to Flutter plugin - ios

I am creating a Flutter plugin. But when I am trying to add a dependency to iOS part of the plugin I am not finding any proper guideline for this. I declared the dependency in the podspec file of my plugin. But the dependency is only available in the example/ios through Pod but I want access that dependency in my ios folder of my plugin. This is my podspec:
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#
Pod::Spec.new do |s|
s.name = 'comet_chat'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin.'
s.description = <<-DESC
A new Flutter plugin.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email#example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.dependency 'CometChatPro', '1.4.0'
s.ios.deployment_target = '10.0'
s.preserve_paths = 'CometChatPro.framework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework CometChatPro' }
s.vendored_frameworks = 'CometChatPro.framework'
end
I followed this issue but it was of no help. How to solve this issue? How can I get my dependency only for the plugin?

There is no way to "only open the plugin's classes", and the dependencies you add in your podspec are only available to your plugin, unless explicitly made it public.
TL;DR
By design, your iOS Flutter plugin will always run when embedded in a Flutter application project. Also, there is a conflict in your podspec; it should never specify the same framework in both dependency and vendored_frameworks.
If you have a CometChatPro.framework folder, copy it in your plugin's ios/Libraries folder and declare its path in your podspec in vendored_frameworks. Personally, I've never used the dependency specifier but there is an example in the flutter-webrtc plugin's implementation.
Either way, the ios/Classes folder of your plugin does have access to the dependencies that you specify in your ios/plugin_name.podpsec file. It just doesn't "know it" when you edit your plugin in any editor other than Xcode (Visual Studio Code, Android Studio, etc).
To develop the Swift or Objective-C classes for your plugin's iOS implementation, you should :
Open the example's Xcode workspace located at example/ios/Runner.xcworkspace.
Edit your plugin's iOS classes by navigating in Xcode to Pods/Development Pods/plugin_name/../../ios/.symlinks/plugins/plugin_name/ios/Classes
Build your project to fix any compiling errors.
If at this point you still don't have access to the framework in your plugin's iOS classes, it means that it wasn't properly setup by Cocoapods. In that case, you'll need to find which Xcode Build Setting is not properly set and then specify these Build Settings in your plugin's podspec, like so:
s.xcconfig = {
'FRAMEWORK_SEARCH_PATHS' => ['${PODS_TARGET_SRCROOT}/Libraries'],
'HEADER_SEARCH_PATHS' => ["${PODS_ROOT}/../.symlinks/plugins/plugin_name/ios/Libraries/CometChatPro.framework/Headers"
}
This explicitly adds the framework to your plugin target's FRAMEWORK_SEARCH_PATHS, and the framework's Headers path to the HEADER_SEARCH_PATH.
When linking vendored_frameworks, you want to make sure that Cocoapods did successfully embed the framework, and that you are building for the right architectures.

Related

What should be the Podspec file for using local .xcframework in React Native library?

I created a React Native library that is a wrapper for using the native iOS framework in the React Native Projects. Earlier I was using .framework & it was working fine. Now I am facing an issue in using this library with .xcframework instead of .framework.
I added this library as a dependency to the project & then on running pod install getting the below error:
[!] [Xcodeproj] Generated duplicate UUIDs:
When I opened the project & try to build it, it builds successfully for the device but fails on the simulator.
Below is the Podspec file that I am using in the library project:
Pod::Spec.new do |s|
s.name = "react-native-myLibrary"
s.version = "1.0.0"
s.summary = "react-native-myLibrary"
s.description = <<-DESC
react-native-myLibrary
DESC
s.homepage = "https://github.com/geektimecoil/react-native-onesignal"
s.license = "MIT"
s.author = { "author" => "author#domain.cn" }
s.platform = :ios, "10.0"
s.source = { :http => 'file:' + __dir__ + '/' }
s.source_files = "**/*.{h,m,swift}"
s.requires_arc = true
s.vendored_frameworks = 'MyLibrary.xcframework'
s.dependency "React"
end
On searching for the solution I found that this error is caused by s.source_files = "**/*.{h,m,swift}". So, I commented this line & run pod install again. The error was gone but no dependency is being added to the Project target. Can anyone provide me the Podspec file to use for local .xcframework in React Native Library. Thanks in advance!
I was able to fix this issue using:
s.source_files = "ios/*.{h,m,swift}"
s.vendored_frameworks = 'ios/Frameworks/MyLibrary.xcframework'
& also by updating the Framework Search Paths from the Build Settings to $(inherited).
Try this:
s.preserve_paths = 'MyFraemwork.xcframework/*'
s.source_files = 'MyFraemwork.xcframework/ios-arm64_armv7/PicUPSDKv3.framework/Headers/*.{h,m,swift}'

iOS Dyanmic Framework with Firebase Dependencies

We are developing a framework that is dependent on some firebase dependencies like login, analytics, etc. Once our framework is developed we will distribute it to our customers.
Things to be taken care of are
Code should not be visible(Best suggestion is to create XCFramework)
If possible create a dynamic framework instead of a static framework
Can be distributed via Swift package manager or cocoapods
What we have tried
We have tried to create a dynamic framework using pods and then create a XCFramework. But while importing into client app, pods module are not found
We created static library and add firebase manually(In project directly) instead of pods, in that case XCFramework is not imported
We have tried to create XCFrame Work as mentioned here (for dynamic framework)
XCFramework with Pods Dependencies
To hide code umbrella framework and universal library can be used,but with firebase, this approach is to typical and also not suggested on the internet at many places
Is there any other/alternative way where we can fulfill our requirements?
We have the exact same setup right now, and it works quite well. Hope that'll also be of help for you.
Things that are taken care of:
It's an XCFramework distribution.
It's been distributed by CocoaPods (albeit in a private Podspec repository)
It's a dynamic framework.
Prerequisites:
CocoaPods version >= 1.10.1
Xcode version >= 11.6 (could be lower though, not sure)
After creating your .xcframework, you need to have a .podspec for your framework, which should look like:
Pod::Spec.new do |s|
# ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
s.name = "MyAwesomeSDK"
s.version = "1.0.0"
s.summary = "Best framework ever: MyAwesomeSDK"
s.description = <<-DESC
"Best framework ever: MyAwesomeSDK"
DESC
s.homepage = "http://github.com"
s.license = "MIT"
s.author = { "ItIsI" => "me#myself.com" }
# ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
#
s.platform = :ios
s.ios.deployment_target = '11.3'
# ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
s.source = { :http => '<MyAwesomeSDK.zip> (We're storing our zipped .xcframework in a hosted page)' }
s.vendored_frameworks = 'MyAwesomeSDK.xcframework'
s.swift_version = "5.0"
# ――― Dependencies ―――――――――――――――――――――――――――---――――――――――――――――――――――――――――――― #
s.dependency 'SwiftProtobuf', '1.12.0'
s.dependency 'lottie-ios', '3.1.8'
# Any other dependency you might need.
end
Then, we are consuming it in another project via Podfile, that will look like:
platform :ios, '13.0'
# If you're going to have a private Podspec repo, add the source URL here.
# Don't forget to add the original source if you're going to specify another source.
# source 'https://cdn.cocoapods.org/'
target 'Test' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# If you are publishing the SDK publicly or in a private Podspec repository, this is it:
pod 'MyAwesomeSDK'
# If not, you should provide the .podspec to your customers, and:
pod 'MyAwesomeSDK', :podspec => '<path/to/MyAwesomeSDK.podspec>'
target 'TestTests' do
inherit! :search_paths
# Pods for testing
end
target 'TestUITests' do
# Pods for testing
end
end
Then, that's it! When running pod install, you should see:
Analyzing dependencies
Downloading dependencies
Installing MyAwesomeSDK (1.0.0)
# These are our own:
# ---
Installing SwiftProtobuf (1.12.0)
Installing lottie-ios (3.1.8)
# ---
Generating Pods project
Integrating client project
Pod installation complete! There is 1 dependency from the Podfile and 3 total pods installed.
P.S: We also had to add a post_install setup in our Podfile, otherwise it'll not properly link the dependency frameworks:
if ["SwiftProtobuf", "lottie-ios"].include? target.name
target.build_configurations.each do |config|
config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
end
end

Importing a static library (Rust .a) to Flutter project in iOS

I have followed the instructions from here and here
And although the .a library and the functions work as expected on Debug (simulator and real device), when I Archive and test through TestFlight the Flutter App begins with a grey background (which I read that it means some kind of error).
If I go ahead and remove all calls of the Rust lib then the Testflight opens normally.
Note: I have also added the .a library as a Linked framework from the XCode and I have included the .h file to the bridging-header.h of the project.
I have also
run flutter build --release
cleared the derived data
pods cache
even re-made the iOS folder
from scratch.
Is there something else that I'm missing here?
I managed to make it work by creating a Flutter plugin flutter create -t plugin then I imported the .a file on the /iOS folder and included all the rust functions on the .h file inside /iOS/Classes (these are automatically created).
Then add a sample function for each of the rust functions inside the .Swift file in /iOS/Classes
And make sure to include
flutter:
plugin:
pluginClass: ApproverRustPlugin
On your .yaml file of the plugin.
Also include these on the plugin .podspec file
s.public_header_files = 'Classes**/*.h'
s.source_files = 'Classes/**/*'
s.static_framework = true
s.vendored_libraries = "**/*.a"
Once all these are done. Make sure to include your plugin (assuming it exists on the same folder as the main App) on the main app .yaml file.
dependencies:
flutter:
sdk: flutter
approver_rust:
path: "./approver_rust"
For reference:
Pod::Spec.new do |s|
s.name = 'approver_rust'
s.version = '0.0.1'
s.summary = 'A new flutter plugin project.'
s.description = <<-DESC
A new flutter plugin project.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email#example.com' }
s.source = { :path => '.' }
s.public_header_files = 'Classes**/*.h'
s.source_files = 'Classes/**/*'
s.static_framework = true
s.vendored_libraries = "**/*.a"
s.dependency 'Flutter'
s.platform = :ios, '9.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'
end

How to import Alamofire/AFNetworking in my custom cocoapod

How do I include Alamofire (a web request pod like AFNetworking) in my cocoapod source files? I have a service in my cocoapod that needs to make web requests using Alamofire, my cocoapod doesn't seem to have a podfile that I can see, so I don't know how to add the dependency to my cocoapod.
I am creating a cocoapod using pod lib create The build fails whenever I go to import Alamofire in any of my files. In a normal project, I'd just add Alamofire to my podfile, but this is a cocoapod, so I can't figure out where to add the dependency, or how to get it to build successfully.
I followed the guide here but it doesn't say anything about importing another pod into my cocoapod's files.
My directory structure looks like this:
MyLib.podspec
Example/
MyLib example project
Pod/
Source files for my cocoapod
If your pod depends on other pods you can define that in your pod's .podspec file. You can add dependencies there.
Have a look at RealmSwift's podspec file as an example. The RealmSwift pod has a dependency to the Realm pod. This is defined in RealmSwift.podspec:
Pod::Spec.new do |s|
s.name = 'RealmSwift'
s.version = `sh build.sh get-version`
s.summary = 'Realm is a modern data framework & database for iOS & OS X.'
s.description = <<-DESC
The Realm database, for Swift. (If you want to use Realm from Objective-C, see the “Realm” pod.)
Realm is a mobile database: a replacement for Core Data & SQLite. You can use it on iOS & OS X. Realm is not an ORM on top SQLite: instead it uses its own persistence engine, built for simplicity (& speed). Learn more and get help at https://realm.io
DESC
s.homepage = "https://realm.io"
s.source = { :git => 'https://github.com/realm/realm-cocoa.git', :tag => "v#{s.version}" }
s.author = { 'Realm' => 'help#realm.io' }
s.requires_arc = true
s.social_media_url = 'https://twitter.com/realm'
s.documentation_url = "https://realm.io/docs/swift/#{s.version}"
s.license = { :type => 'Apache 2.0', :file => 'LICENSE' }
# ↓↓↓ THIS IS WHERE YOU DEFINE THE DEPENDENCY TO ANOTHER POD ↓↓↓
s.dependency 'Realm', "= #{s.version}"
# ↑↑↑ THIS IS WHERE YOU DEFINE THE DEPENDENCY TO ANOTHER POD ↑↑↑
s.source_files = 'RealmSwift/*.swift'
s.prepare_command = 'sh build.sh cocoapods-setup without-core'
s.preserve_paths = %w(build.sh)
s.pod_target_xcconfig = { 'SWIFT_WHOLE_MODULE_OPTIMIZATION' => 'YES',
'APPLICATION_EXTENSION_API_ONLY' => 'YES' }
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.9'
s.watchos.deployment_target = '2.0' if s.respond_to?(:watchos)
end
You should check out the AlamofireImage project. It uses Carthage to add the Alamofire submodule to the project. The Alamofire project is then added as a dependency to the AlamofireImage project.
The AlamofireImage.podspec also demonstrates how to add Alamofire as a dependency for CocoaPods. If you follow the AlamofireImage project structure exactly, you'll be up and running in no time. Here are some useful commands to get you going:
Cartfile
github "Alamofire/Alamofire" ~> 3.0
Checkout through Carthage
brew update
brew doctor
brew install carthage
// or
brew upgrade carthage
carthage update --no-build --use-submodules
Hopefully that helps!
If you have created a pod and in your .podspec file you are trying to add a dependency (like Alamofire, RealmSwift..) after that you should go to the Example/.. folder and do a pod install to make the dependencies required from the .podspec of your custom pod visible to the .swift files in your custom pod/framework.
A typical example of a pod project folder hierarchy would be:
- MyLib/
- _Pods.xcodeproj
- Example/ // <-- do a pod install under this folder in order to get the dependencies declared in your .podspec
- Podfile
- MyLib.xcodeproj
- MyLib.xcworkspace
- MyLib/
- Classes/ // <-- folder with pod specific logic that also uses Alamofire
- Assets/
- MyLib.podspec // <-- your podspec with dependencies (Alamofire..)

Cannot build manual ref count CocoaPod

I have an iOS CocoaPod that is a couple of years old as a pod, and several years older than that as a reusable component. Previously built with older versions of Xcode. It was developed with and remains "manual reference counting". I am now trying to import it into a "new" project (actually reconstructed from an old project and also manual reference counting), but I cannot get it to build.
As I said, the enclosing project is manual reference counting and compiles OK that way with no pods installed. "Automatic Reference Counting" is set to "No" in "Build Settings".
However, even though the exact same Build Settings "No" value is present in the pods project, it always generates a compile script with -fobjc-arc, and calls to retain and release are flagged as errors. (Eg, error: 'release' is unavailable: not available in automatic reference counting mode.)
The version of Xcode is 6.0.1.
The version of pod is 0.34.4 (installed fresh yesterday).
The podspec for the pod in question:
Pod::Spec.new do |s|
s.name = "libXXX"
s.version = "1.0"
s.summary = "Exchange library for XYZ."
s.description = "Static library pod for the XXX framework."
s.homepage = "http://example.com"
s.license = { :type => 'MIT', :text => 'Copyright 2012 XYZ' }
s.author = { "Bill Nye" => "bnye#example.com" }
s.source = { :git => 'https://code.example.com/ios/XXX.git', :tag => '1.0' }
s.platform = :ios
s.source_files = 'StaticLib/Headers/*.h'
s.preserve_paths = 'StaticLib/libXXX.a'
s.library = 'XChangeA'
s.xcconfig = { 'LIBRARY_SEARCH_PATHS' => '$(PODS_ROOT)/libXXX/StaticLib' }
s.dependency 'libSignatureToken'
end
I tried adding s.requires_arc = false to the pod spec (and performing pod update), but nothing changed. I also tried s.compiler_flags = '-fno-objc-arc', with no success.
So, how do I convince Xcode to compile the pod with manual reference counting?
Resolved
Apparently "unrelated" problems during pod update caused it to fail silently without configuring the compile mode info. Running pod update --verbose repeatedly helped smoke out the problems.
You need to use s.requires_arc = false
This is documented here. The default recently changed from false to true. Also this error should appear if you run pod spec lint.

Resources