I'm trying to create an iOS project that includes C code that is shared across other platforms (Android). Some of the third party libraries I'm compiling rely on having certain directories included as search paths. However, no matter what I've tried, I've been unable to the CocoaPods .podspec file to include a given directory in the compilation search path. I'm using CocoaPods 1.8.4.
Whilst this is a Flutter plugin, it's my understanding that this is an issue with CocoaPods/Xcode, since Flutter has merely set up the project files. However, it's worth noting that Flutter sets up an example workspace, which I do not want to modify. I want the Plugin itself to be modified to compile in the requisite code, not the example workspace/project. In other words, I want only the ios/repro_cocoapods_issue.podspec file to be modified.
In case it matters, I used the following Flutter command to create the project:
flutter create -t plugin -i objc -a java repro_cocoapods_issue
I have a full repro up on GitHub here. To reproduce, open the workspace at example/ios/Runner.xcworkspace in Xcode and try to build.
These are the things I've tried in the ios/repro_cocoapods_issue.podspec file:
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/external/"'}
s.xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/external/"'}
s.user_target_xcconfig = { 'HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/external/"'}
s.user_target_xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/external/"'}
s.pod_target_xcconfig = { 'HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/external/"'}
s.pod_target_xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '"${PROJECT_DIR}/external/"'}
s.compiler_flags = '-Iexternal/'
s.preserve_paths = 'external/**'
s.preserve_paths = '${PROJECT_DIR}/external/**'
In all cases, I get:
'external_dir.c' file not found
If I change the code to #include ../external/external_dir.c then it works, but this does not help with my actual use case.
How can I configure my podspec so that a specified directory is included in the search path during compilation?
Output of pod env
Stack
CocoaPods : 1.8.4
Ruby : ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
RubyGems : 2.5.2.3
Host : Mac OS X 10.14.6 (18G95)
Xcode : 11.1 (11A1027)
Git : git version 2.23.0
Ruby lib dir : /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib
Repositories : master - git - https://github.com/CocoaPods/Specs.git # d13a0869021d940f32f0543a03500755b39be998
Installation Source
Executable Path: /usr/local/bin/pod
Plugins
cocoapods-deintegrate : 1.0.4
cocoapods-plugins : 1.0.0
cocoapods-search : 1.0.0
cocoapods-stats : 1.1.0
cocoapods-trunk : 1.4.1
cocoapods-try : 1.1.0
Answering my own question after finally figuring it out.
Something is aggressively caching the "output" of .podspec files. What was causing the issue is that I was changing the .podspec and cleaning+rebuilding, expecting that to be sufficient to pick up my changes, but it was not. If I instead do a git clean -xdf and then build, my changes are picked up.
I ended up using the properties I expected should work (with slight tweaks to the above that were easy to figure out once the options were actually being used):
s.source_files = [
'Classes/**/*',
'shared_c/**/*'
]
s.public_header_files = [
'Classes/**/*.h',
'shared_c/*.h'
]
s.xcconfig = {
'HEADER_SEARCH_PATHS' => [
'"${PODS_TARGET_SRCROOT}/shared_c/"'
],
'GCC_PREPROCESSOR_DEFINITIONS' => 'SOME_SYMBOL_FOR_THIRD_PARTY_CODE=1 SOME_OTHER_SYMBOL=1'
}
s.dependency 'Flutter'
s.ios.deployment_target = '9.0'
As for why the files are being so aggressively cached, I need to chase that up with the Flutter team (and I'm expecting them to say it's a CocoaPods/XCode issue).
Make sure that every edit to the podspec file also increases its version.
CocoaPods podspecs versions are assumed to be immutable and cached as such. See pod cache list and pod cache clean.
Related
Im trying to upload the new version of my pod to cocoapods spec repo. The current live version is 0.3.1 and it is a framework build with swift 4.2. Now i updated the library and build with Xcode 11.1 (swift 5). But while linting the podspec file, im getting an unknown DSL error in the terminal.
I have tried with changing the name of podspec and with same framework. but no use. anyone please help
pod spec lint AsistaCore.podspec --verbose
Podspec file
Pod::Spec.new do |spec|
spec.name = 'AsistaCore'
spec.version = '1.0.0'
spec.summary = 'Official Asista SDK in Swift to access Asista Platform core feature'
spec.description = <<-DESC
The Asista SDK in Swift Core framework provides:
* Create new tickets
* Update Ticket State
* Add comments to ticket
* Asset list
* Update profile
* Knowledge Base Articles
DESC
spec.homepage = 'https://asista.com/developer'
spec.license = { :type => 'MIT', :file => 'LICENSE' }
spec.authors = { 'Cherrylabs' => 'vaisakh.kp#cherrylabs.com' }
spec.documentation_url = 'https://asista.com/developer/docs/asista-sdk-for-ios'
spec.platform = :ios
spec.source = { :git => 'https://github.com/cherrylabstech/asista-sdk-ios.git', :tag => spec.version }
spec.swift_version = '5.0'
spec.ios.deployment_target = '8.0'
spec.static_framework = true
spec.ios.vendored_frameworks = 'AsistaSupport/AsistaCore.framework'
end
-> AsistaCore (1.0.0)
- ERROR | [iOS] unknown: Encountered an unknown error (Pod::DSLError
/Library/Ruby/Gems/2.6.0/gems/cocoapods-core-1.8.4/lib/cocoapods-core/specification.rb:808:in `rescue in _eval_podspec'
....
...
We ran into this issue when we try creating a release and publishing a library. This error occurs when you are trying to run pod spec lint or pod repo push. The error says "DSLError" and doesn't give much information on what is causing it. I found little help online and some places they say, there could be a syntax error in the podspec file. We didn't have any in our podspec. However, this answer from stackoverflow gave me some direction https://stackoverflow.com/a/64779582
It looks like while making a release for one SDK/library, the pod spec lint and pod repo push validates all the podspecs in the folder besides the ones you ran. I don't know how that works internally. You should look for the following scenarios to identify the issue:
If there are other podspecs for capabilities that have different tags(Example: ABC.podspec pointed to source tag 1.0.0-ABC and XYZ.podspec pointed to source tag 2.0.0-XYZ)
Multiple podspecs have dependencies on different versions of the same module(Example: Module1.podspec depends on Module 5 version 10.0.0 and Module2.podspec also depends on Module 5 but on the version 11.0.0).
Syntax errors in any of the podspecs
If you come across either or both 1 & 2, it could be a potential cause for the DSLError.
When you run into this issue, make sure you look for and update the following:
All podspecs to have pointed to one source tag
All dependencies on a module pointed to one version of it in each capability.
Fix the sytanx errors.
This issue will go away or reduce significantly when the SDK libraries can be separated into their repositories instead of all in one repository, or perhaps even by keeping each podspec in their own individual folder.
After running pod outdated, I get the following output
Updating spec repo `master`
Analyzing dependencies
The following pod updates are available:
- AFNetworking 2.4.4 -> 2.5.4 (latest version 3.0.0-beta.2)
- HexColors 2.2.1 -> 2.2.1 (latest version 3.0.0)
- Overcoat 3.0.0 -> (unused) (latest version 3.2.1)
- ReactiveCocoa 2.5 -> 2.5 (latest version 4.0.4-alpha-4)
I have not seen this "unused" term before
i.e.
Overcoat 3.0.0 ->(unused) (latest version 3.2.1)
What is this? And what does it mean?
After analyzing the source code, I think that (unused) means that the Pod is not in your Podfile (probably you removed it and didn't reinstall)
AFNetworking 2.4.4 -> 2.5.4 (latest version 3.0.0-beta.2)
^ ^ ^ ^
Pod name Installed version Podfile version Latest
Based on the source code which inserts this tag, which looks like this:
if source_version > lockfile_version
matching_spec = unlocked_pods.find { |s| s.name == pod_name }
matching_version =
matching_spec ? matching_spec.version : '(unused)'
[pod_name, lockfile_version, matching_version, source_version]
end
It appears that this simply means that CocoaPods could not find that Pod within your 'unlocked pods'.
I don't speak Ruby well enough to determine exactly what an "unlocked" pod is (nor am I familiar enough with CocoaPods to have heard the term necessarily... but I am aware of a 'lockfile', and maybe this is related), but here is the source code for determining that:
def unlocked_pods
#unlocked_pods ||= begin
pods = []
UI.titled_section('Analyzing dependencies') do
pods = Installer::Analyzer.new(config.sandbox, config.podfile).
analyze(false).
specs_by_target.values.flatten.uniq
end
pods
end
end
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..)
I am trying to create a Cocoapods library. My library will include Google-Mobile-Ads-SDK as dependency. I used following commands
pod lib create BannerViewController
> my email address
What language do you want to use?? [ ObjC / Swift ]
> Swift
Would you like to include a demo application with your library? [ Yes / No ]
> Yes
Which testing frameworks will you use? [ Quick / None ]
> None
Would you like to do view based testing? [ Yes / No ]
> No
I then edited BannerViewController.podspec added following line
s.dependency 'Google-Mobile-Ads-SDK', '~> 7.0'
I tried to use pod lib lint BannerViewController.podspec
[!] BannerViewController did not pass validation, due to 1 error and 3 warnings.
You can use the `--no-clean` option to inspect any issue.
I tried to pod update in Example directory and got following error
[!] The 'Pods-BannerViewController_Example' target has transitive dependencies that include static binaries: (/Developer/BannerViewController/Example/Pods/Google-Mobile-Ads-SDK/GoogleMobileAdsSdkiOS-7.4.0/GoogleMobileAds.framework)
I don't know how can I add Google-Mobile-Ads-SDK to my development pod so that I can test my code locally. Cocoapods documentation is not clear. I am using Cocoapods 0.38.2
Use pod lib lint BannerViewController.podspec --use-libraries
How do I remove dependency from a pod?
I have a podfile with
pod 'GData'
which seems to be broken, because it generates 163 duplicate symbols errors. I think I know what it is. While installing this can be observed:
Installing GTMHTTPFetcher (1.141)
Installing gtm-http-fetcher (1.0.141)
[!] GTMHTTPFetcher has been deprecated in favor of gtm-http-fetcher
One of these is not needed. So to remove it I try to modify podfile to use custom, local podspec file:
podspec :path => '~/GData.podspec.json'
In which podspec file I copy all of original JSON podspec contents without GTMHTTPFetcher, GData DOES not install. It even happens if I just copy original contentes and don't change anything at all. All dependencies are installed, but GData itself is not. I think that I'm missing something here.
Here is proper podfile syntax for using custom podspec (in a JSON format):
pod 'pod_name_goes_here', :podspec => 'path/to/your/file.podspec.json'
And to delete dependency, simply remove an entry from 'dependencies', for example change
"dependencies": {
"GTMHTTPFetcher": [
],
"gtm-oauth2": [
]
}
to
"dependencies": {
"gtm-oauth2": [
]
}
And now pod will be installed without "GTMHTTPFetcher".