I would like to use a modify version of stripe_ios library in flutter_stripe library to include a missing functionality I added.
for that I downloaded both libraries and copy them inside a packages directory of my flutter app.
then inside pubspec.yaml I declared the library like that:
flutter_stripe:
path: packages/stripe
then in flutter_stripe library folder I edited stripe_ios/ios/stripe_ios.podspec to make Stripe library reference point to my modified version:
Pod::Spec.new do |s|
s.name = 'stripe_ios'
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.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.dependency 'Stripe'
s.subspec 'Stripe' do |ss|
ss.source_files = '../../library/StripeIos/Stripe'
end
s.platform = :ios, '11.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
But it seems it's not working correctly and when I do pod install from ios folder it seems to download version 21.13.0 of Stripe ios library instead.
any idea how to achieve this correctly ?
I am trying to include .a files on the iOS side of the plugin. Below is my file structure.
Now when I try to add .a files via vendored_libraries on podspec, pod install is successfully completed. And when I compile the code, I get Library Not Found -lAccuraFace
I tried to add the .a file on the Link Binary With Libraries section on the build phase on the Pod target. It's still the same, how can I define the podspec in such a way that the .a file is included and linked automatically.
Here is my podspec file for the plugin
Pod::Spec.new do |s|
s.name = 'accuraemirates'
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.dependency 'Flutter'
s.public_header_files = 'Classes/*{.h}'
s.private_header_files = 'Classes/CodeScan/**/*{.h,.cpp,.a}'
s.platform = :ios, '8.0'
s.preserve_paths = 'opencv2.framework'
s.xcconfig = {
'OTHER_LDFLAGS' => '-framework opencv2 -lAccuraFace',
}
s.ios.vendored_frameworks = 'opencv2.framework', "CoreVideo.framework", "Foundation.framework", "CoreGrpahics.framework",
"Accelerate.framework", "CoreMedia.framework", "CoreImage.framework", "QuartzCore.framework", "AudioToolbox.framework", "CoreData.framework", "SystemConfiguration.framework"
s.ios.vendored_libraries = 'Classes/Framework/*{.a}', "libz.1.dylib", "c++", "stdc++"
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
s.swift_version = '5.0'
end
Here is the root podfile
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def parse_KV_file(file, separator='=')
file_abs_path = File.expand_path(file)
if !File.exists? file_abs_path
return [];
end
generated_key_values = {}
skip_line_start_symbols = ["#", "/"]
File.foreach(file_abs_path) do |line|
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
plugin = line.split(pattern=separator)
if plugin.length == 2
podname = plugin[0].strip()
path = plugin[1].strip()
podpath = File.expand_path("#{path}", file_abs_path)
generated_key_values[podname] = podpath
else
puts "Invalid plugin specification: #{line}"
end
end
generated_key_values
end
target 'Runner' do
use_frameworks!
use_modular_headers!
# Flutter Pod
copied_flutter_dir = File.join(__dir__, 'Flutter')
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
unless File.exist?(generated_xcode_build_settings_path)
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
unless File.exist?(copied_framework_path)
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
end
unless File.exist?(copied_podspec_path)
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
end
end
# Keep pod path relative so it can be checked into Podfile.lock.
pod 'Flutter', :path => 'Flutter'
# Plugin Pods
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
# referring to absolute paths on developers' machines.
system('rm -rf .symlinks')
system('mkdir -p .symlinks/plugins')
plugin_pods = parse_KV_file('../.flutter-plugins')
plugin_pods.each do |name, path|
symlink = File.join('.symlinks', 'plugins', name)
File.symlink(path, symlink)
pod name, :path => File.join(symlink, 'ios')
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
Is it not possible to add/link .a libraries from podspec file on a flutter plugin.
Finally found the issue..
Pod::Spec.new do |s|
# other obvious values
s.source_files = 'Classes//*{.h,.a,.swift,.mm,.m,.hpp}'
s.resources = 'Resources//'
s.static_framework = true
s.public_header_files = "Classes/VideoCamera/VideoCameraWrapperDelegate.h", "Classes/VideoCamera/VideoCameraWrapper.h",'Classes/.h',
s.private_header_files = 'Classes/CodeScan//{.h,.cpp,.hpp}'
s.platform = :ios, '8.0'
s.preserve_paths = 'opencv2.framework', 'Classes/Framework/.a'
s.xcconfig = {
# here on LDFLAG, I had to set -l and then the library name (without lib prefix although the file name has it).
'OTHER_LDFLAGS' => '-framework opencv2 -lc++ -lAccuraFace -lAccuraEmirate -lDocRecog -lz',
'USER_HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/.."/',
"LIBRARY_SEARCH_PATHS" => '"${PROJECT_DIR}/.."/*',
}
s.vendored_frameworks = 'opencv2.framework' # Various framworks you need
# Here the name of the library can include lib as the file name has it too.
s.vendored_libraries = 'AccuraFace','libAccuraEmirate','libDocRecog'
end
Notice two values here OTHER_LDFLAGS and vendored_libraries. Although I have same file, they need names with and without lib prefix. Weird but worked.
You definitely CAN add .a libraries, try to check the following configuration path
TARGETS->Build Settings->Search Paths-> Library Search Paths
Right there, add path where .a library was located.
Here is a valid path configuration demo:
==========================================================================
UPDATE
For flutter plugin
As for ship as flutter plugin ,file with .a suffix is actually static library, here is a snippet for how to do it in a .podspec file:
s.subspec 'Core' do |sc|
sc.ios.library = 'z'
sc.frameworks = 'SystemConfiguration', 'QuartzCore', 'CoreText', 'WebKit'
sc.source_files = 'AppboyKit/headers/AppboyKitLibrary/*.h', 'AppboyKit/ABKIdentifierForAdvertisingProvider.m', 'AppboyKit/ABKModalWebViewController.m', 'AppboyKit/ABKNoConnectionLocalization.m', 'AppboyKit/ABKLocationManagerProvider.m'
sc.resource = 'AppboyKit/Appboy.bundle'
sc.vendored_libraries = 'AppboyKit/libAppboyKitLibrary.a'
sc.weak_framework = 'CoreTelephony', 'Social', 'Accounts', 'AdSupport', 'UserNotifications'
end
Pay attention to line start with sc.vendored_libraries there.Here is the complete source.
ios framework into flutter_plugin
import your Famework or library in both path => Flutter_Plugin/example/ios and Flutter_Plugin/ios .
IN Flutter_plugin/ios/flutter_plugin.podspec file
s.preserve_paths = 'YOUR_FRAMEWORK.framework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework YOUR_FRAMEWORK' }
s.ios.vendored_frameworks = 'YOUR_FRAMEWORK.framework'
s.ios.vendored_libraries = 'YOUR_FRAMEWORK'
make your framework embeded and signin in xcode(Flutter_Plugin/example/ios).
!sometimes in DerivedData/.../debug_iphone/flutter_plugin.framework - its not there so make that Flutter_plugin.framework move to that debug_iphone folder , it inside the flutter_plugin folder.
Summary:
I am building a Flutter Plugin to be used for multiple projects I am developing. I have no experience writing custom platform-specific code.
I am having trouble importing SDK library for IOS *.Framework and *-Resources.bundle to my plugin.
I've tried to the solution for in https://github.com/flutter/flutter/issues/17978
Also, I've tried cleaning and re-building the app but with no success and tried cleaning and re-building the example app but with no success
and I receive the below error:
*.podspec:
Pod::Spec.new do |s|
s.name = 'plugin_name'
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.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.ios.deployment_target = '9.0'
end
Pod::Spec.new do |spec|
spec.name = "plugin_name"
spec.version = "2.3.7"
spec.summary = "SDK"
spec.homepage = "https://hkhars.com"
spec.author = "Hussain Alkhars"
spec.license = { :file => '../LICENSE' }
spec.source = { :path => '.' }
spec.ios.deployment_target = '9.0'
spec.preserve_paths = 'IOSFLUTTERSDK.framework'
spec.xcconfig = { 'OTHER_LDFLAGS' => '-framework IOSFLUTTERSDK' }
spec.vendored_frameworks = 'IOSFLUTTERSDK.framework'
spec.public_header_files = "IOSFLUTTERSDK.framework/Headers/*.h"
spec.resource_bundle = { 'IOSFLUTTERSDK-Resources' => './*' }
end
Error when trying to build with flutter build ios --no-codesign
fatal error: 'plugin_name/PluginNamePlugin.h' file not found
#import <plugin_name/PluginNamePlugin.h>```
You've mangled your Podspec file. There should only be one section starting Pod::Spec.new do |s|.... If you want to try the approach in the linked Github issue, your Podspec file should look like this:
Pod::Spec.new do |s|
s.name = 'plugin_name'
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.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.ios.deployment_target = '9.0'
s.preserve_paths = 'IOSFLUTTERSDK.framework'
s.xcconfig = { 'OTHER_LDFLAGS' => '-framework IOSFLUTTERSDK' }
s.vendored_frameworks = 'IOSFLUTTERSDK.framework'
s.resource_bundle = { 'IOSFLUTTERSDK-Resources' => './*' }
end
However, I've tried this before with no success - I needed to link everything manually via Xcode by opening the project:
open example/ios/Runner.xcworksapce
Click on the "Runner" project at the top, and click on the "Build Phases" item on the right hand side (if "Build Phases" doesn't show, make sure the folder icon on the left is selected, and you've clicked the Runner Target in the middle panel, not the Runner Project).
Find the "Link Binary with Libraries" panel, and click the "+" button:
Select your .framework file and click "Done". Repeat the same under "Embed Frameworks".
I'm not 100% sure, but I think you can do the same under "Copy Bundle Resources".
this is my podspec :
Pod::Spec.new do |spec|
spec.name = 'OoTracker'
spec.version = '1.0.0'
spec.license = 'Copyright Oodrive'
spec.source = { :git => 'https://oogit.oodrive.net/mobile-common/OoTracker.git', :tag => spec.version.to_s }
spec.summary = 'A small library to track actions and events using the Matomotracker library'
spec.homepage = 'https://oogit.oodrive.net/mobile-common/TrackerPod/blob/master/README.md'
spec.author = { 'Sandy Ludosky' => 's.ludosky#oodrive.com' }
spec.ios.deployment_target = '10.0'
spec.osx.deployment_target = '10.0'
spec.platform = :ios, "9.1"
spec.swift_version = '4.0'
spec.source_files = 'Source/*.{h,m,swift}'
spec.frameworks = 'UIKit', 'Foundation', 'CoreFoundation'
spec.dependency 'MatomoTracker', '~> 5.2.0'
spec.subspec 'OoTracker' do |s|
s.source_files = 'Source/**/*.swift'
end
end
and my Podfile: the pod is not public so I use the https to point to it
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'TrackerExample' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for TrackerExample
pod 'PodName', :git => '******'
target 'TrackerExampleTests' do
inherit! :search_paths
# Pods for testing
end
end
this is a screenshot of the pod folder. this is completely empty. No files or classes attached to the pod when I expand the folder
enter image description here
Any thoughts ?
I'm currently trying to create a pod for the first time that contains several dependencies.
The pods I'm currently including in my pod are as follows
FacebookCore
FacebookLogin
Fabric
TwitterKit
Google/SignIn
LinkedinSwift
My podspec file looks like this
Pod::Spec.new do |s|
s.platform = :ios
s.ios.deployment_target = '8.0'
s.name = "Socializin"
s.version = "0.0.1"
s.summary = "A short description of Socializin."
s.requires_arc = true
s.author = {"MyName" => "MyMail"}
s.homepage = "http://EXAMPLE/Socializin"
s.license = { :type => "MIT", :file => "LICENSE" }
s.source = { :git => "", :tag => "#{s.version}"}
s.framework = "UIKit"
s.dependency 'FacebookCore', '~> 0.2.0'
s.dependency 'FacebookLogin', '~> 0.2.0'
s.dependency 'FacebookShare', '~> 0.2.0'
s.dependency 'Fabric', '~> 1.6.11'
s.dependency 'TwitterKit', '~> 2.8.1'
s.dependency 'Google/SignIn', '~> 3.0.3'
s.dependency 'LinkedinSwift', '~> 1.7.4'
s.source_files = "Socializin/**/*.{swift}"
#s.resources = "Socializin/**/*.{png,jpeg,jpg,storyboard,xib}"
end
But the dependencies give me the following error
[!] The 'Pods-socializinTest' target has transitive dependencies that include static binaries: (/Users/x/projects/x/Examples/socializinTest/Pods/Fabric/iOS/Fabric.framework, /Users/x/projects/x/Examples/socializinTest/Pods/Google/Frameworks/GGLCore.framework, and /Users/x/projects/x/Examples/socializinTest/Pods/Google/Frameworks/GGLSignIn.framework)
Is there anyway to make sure it does work? All I want to do is create a pod that will make it easy to use all those services and being able to add more to it whenever needed.
I hope you are still looking for a solution.
This is what i did:
I put the Google SignIn framework under /Dependency/GoogleDependency
And i put the TwitterKit, TwitterCore and Fabric frameworks under /Dependency/TwitterDependency/
Pod::Spec.new do |s|
s.platform = :ios
s.ios.deployment_target = '9.0'
s.name = "Socializin"
s.version = "0.0.1"
s.summary = "A short description of Socializin."
s.requires_arc = true
s.author = {"MyName" => "MyMail"}
s.homepage = "http://EXAMPLE/Socializin"
s.license = { :type => "MIT", :file => "LICENSE" }
s.source = { :git => "", :tag => "#{s.version}"}
s.framework = "UIKit"
s.dependency 'FacebookCore', '~> 0.2.0'
s.dependency 'FacebookLogin', '~> 0.2.0'
s.dependency 'FacebookShare', '~> 0.2.0'
s.dependency 'LinkedinSwift', '~> 1.7.4'
s.source_files = "Socializin/**/*.{swift}"
#s.resources = "Socializin/**/*.{png,jpeg,jpg,storyboard,xib}"
#----------------------------Sub Modules-----------------#
s.subspec 'GoogleAuthentication' do |ss|
ss.ios.deployment_target = '9.0'
ss.source_files = 'Socializin/Dependency/GoogleDependency/**/*.{swift}'
ss.resources = ['Socializin/Dependency/GoogleDependency/**/*.{xib,xcdatamodeld,bundle}']
ss.vendored_frameworks = ['Socializin/Dependency/GoogleDependency/**/*.{framework}']
ss.preserve_paths = ['Socializin/Dependency/GoogleDependency/**/*.{framework}']
frameworkPaths = ''
Dir.glob('Socializin/Dependency/GoogleDependency/**/*.{framework}') do |filename|
filePath = Pathname.new(filename)
newFilename = filePath.dirname
if frameworkPaths != ""
frameworkPaths = "#{frameworkPaths} \"$(PODS_ROOT)/#{newFilename}\""
else
frameworkPaths = "\"$(PODS_ROOT)/#{newFilename}\""
end
end
ss.xcconfig = {
'FRAMEWORK_SEARCH_PATHS' => frameworkPaths,
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Socializin/Dependency/GoogleDependency"',
}
#Authentication
# ss.dependency 'GoogleSignIn'
ss.dependency 'GoogleToolboxForMac/NSDictionary+URLArguments'
ss.dependency 'GoogleToolboxForMac/NSData+zlib'
end
s.subspec 'TwitterAuthentication' do |ss|
ss.ios.deployment_target = '9.0'
ss.source_files = 'Socializin/Dependency/TwitterDependency/**/*.{swift}'
ss.resources = ['Socializin/Dependency/TwitterDependency/TwitterKit/iOS/TwitterKit.framework/*.{xib,xcdatamodeld,bundle}']
ss.vendored_frameworks = ['Socializin/Dependency/TwitterDependency/**/*.{framework}']
ss.preserve_paths = ['Socializin/Dependency/TwitterDependency/**/*.{framework}']
frameworkPaths = ''
Dir.glob('Socializin/Dependency/TwitterDependency/**/*.{framework}') do |filename|
filePath = Pathname.new(filename)
newFilename = filePath.dirname
if frameworkPaths != ""
frameworkPaths = "#{frameworkPaths} \"$(PODS_ROOT)/#{newFilename}\""
else
frameworkPaths = "\"$(PODS_ROOT)/#{newFilename}\""
end
end
ss.xcconfig = {
'FRAMEWORK_SEARCH_PATHS' => frameworkPaths,
'HEADER_SEARCH_PATHS' => '"$(PODS_ROOT)/Socializin/Dependency/TwitterDependency"',
}
#Authentication
# ss.dependency 'Fabric'
# ss.dependency 'TwitterKit'
# ss.dependency 'TwitterCore'
end
end