How can I silence warnings from all pods except local pods? - cocoapods

I'm assuming something along the lines of
post_install do |installer|
# Debug symbols
installer.pod_project.targets.each do |target|
target.build_configurations.each do |config|
if ? == ?
config.build_settings['?'] = '?'
end
end
end
end

I encountered a similar problem today and figured out two ways to achieve this depending on the complexity of your dependencies.
The first way is simple and should work if your local development pods are in your main pod file and not nested in another dependency. Basically inhibit all the warnings as per usual, but specify false on each local pod:
inhibit_all_warnings!
pod 'LocalPod', :path => '../LocalPod', :inhibit_warnings => false
pod 'ThirdPartyPod',
The second way which is more comprehensive and should work for complex nested dependencies is by creating a whitelist of your local pods and then during post install, inhibit the warnings of any pod that is not part of the whitelist:
$local_pods = Hash[
'LocalPod0' => true,
'LocalPod1' => true,
'LocalPod2' => true,
]
def inhibit_warnings_for_third_party_pods(target, build_settings)
return if $local_pods[target.name]
if build_settings["OTHER_SWIFT_FLAGS"].nil?
build_settings["OTHER_SWIFT_FLAGS"] = "-suppress-warnings"
else
build_settings["OTHER_SWIFT_FLAGS"] += " -suppress-warnings"
end
build_settings["GCC_WARN_INHIBIT_ALL_WARNINGS"] = "YES"
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
inhibit_warnings_for_third_party_pods(target, config.build_settings)
end
end
end
This will now only inhibit 3rd party dependencies but keep the warnings on any local pods.

Podfile Solution
While ignore_all_warnings is an all or none proposition, you can :inhibit_warnings => true on any individual pod in the Podfile.
# Disable warnings for each remote Pod
pod 'TGPControls', :inhibit_warnings => true
# Do not disable warnings for your own development Pod
pod 'Name', :path => '~/code/Pods/'

There's CocoaPods plugin, https://github.com/leavez/cocoapods-developing-folder that has inhibit_warnings_with_condition. Citing the README:
🔸 Inhibit warnings for specific pods
Add the following to your podfile
plugin 'cocoapods-developing-folder'
inhibit_warnings_with_condition do |pod_name, pod_target|
# your condition written in ruby, like:
# `not pod_name.start_with? "LE"` or
# `['Asuka', 'Ayanami', 'Shinji'].include? pod_name`
end
pod_target is a instance of Pod::PodTarget class, containing many more
info than the name. You can use it to set up complex rules.
This function will override the warning inhibition settings by the
original methods, like: inhibit_all_warnings!, pod 'Ayanami',
:inhibit_warnings => true
So if you know the names of the local pods you can filter them like shown in the above example. Or you can try something like this (that tries to exploit the fact that local pods are not under Pods directory):
inhibit_warnings_with_condition do |pod_name, pod_target|
pod_target.file_accessors.first.root.to_path.start_with? pod_target.sandbox.root.to_path
end
Beware that, if I get the last statement there correctly, it will rule out inhibit_all_warnings! and :inhibit_warnings from effect (I checked the implementation and it looks like it's indeed the case). So you can not use both inhibit_warnings_with_condition and inhibit_all_warnings! or :inhibit_warnings, but at the end, that kind of makes sense.

Related

How to edit project build settings via CocoaPod podfile?

I basically need to set MARKETING_VERSION in my own project build settings based on a value in a json file in the same directory.
Am hoping I can piggyback on Podfile to edit my project's own configuration.
Couldn't find anything on this, as most of it is about editing the Pods configuration themselves.
Is this possible or it's not meant to do it like this?
Managed to solve it by modifying the xconfigs manually:
require 'json'
post_install do |installer|
# Getting my version from outside.
json_from_file = File.read("../package.json")
hash = JSON.parse(json_from_file, {:symbolize_names => true})
work_dir = Dir.pwd
# Get the files and add on my own build settings.
Dir.glob("Pods/Target Support Files/Pods-MyApp/*.xcconfig") do |xc_config_filename|
full_path_name = "#{work_dir}/#{xc_config_filename}"
File.open(full_path_name, 'a') { |f| f.write('MARKETING_VERSION = ' + hash[:version]) }
end
end
Feel free to edit/post comment or even as a new answer if there is a cleaner way.

pod install error: The name of the given podspec `Yoga` doesn't match the expected one `yoga`

I'm getting the following error while doing pod install.
The name of the given podspec `Yoga` doesn't match the expected one `yoga`
Inside the Podfile these are the only lines with the word yoga and they are in lowercase...so I don't know what's causing this problem..
pod 'yoga',
:path => "../node_modules/react-native/ReactCommon/yoga",
:inhibit_warnings => true
How to solve?
It looks like it should be pod 'Yoga'. See https://github.com/facebook/react-native/blob/master/ReactCommon/yoga/Yoga.podspec#L18
When you .podfile pod '<name>' is not equal .podspec <variable>.name = "name" you get
The name of the given podspec `<name>` doesn't match the expected one

Is there a way to include an image asset that will only be available in previews for SwiftUI?

I'm developing a CocoaPod and I'd like to include images in my target that I can use in SwiftUI previews. I don't want them included in the binary or the pod when I ship it. Is that possible?
If I don't include the asset bundle in the podspec it doesn't seem to appear under my development pods, but I don't want it in the podspec because I don't want to ship the images.
I'm thinking there's perhaps a way to do this by running a custom step after pod install that will copy an asset bundle from the example app to the development pod but I haven't quite figured that out yet.
When you create SwiftUI based project it creates the following group, with Preview-only assets catalog
Target build settings:
Following #Asperi's answer, I wrote the following post_install step for my development pod. Remember to change ${TARGET_NAME} for your target:
post_install do |installer_representation|
project = installer_representation.pods_project
subdir = "PreviewAssets"
# First add the PreviewAssets folder to the build settings for the debug configuration
project.targets.each do |target|
if target.name == "${TARGET_NAME}"
target.build_configurations.each do |config|
if config.name == 'Debug'
config.build_settings['DEVELOPMENT_ASSET_PATHS'] ||= ['${PODS_TARGET_SRCROOT}/' + subdir]
end
end
end
end
# Second grab all the xcassets from the PreviewAssets folder and add them to the ${TARGET_NAME} group in
# the Development Pods group
group = project.pod_group("${TARGET_NAME}")
references = []
# Is there a better way to get the root of your project?
directory = installer_representation.sandbox.root.join("../..", subdir)
Dir.chdir(directory)
Dir.glob("*").each do |f|
if File.directory?(f)
full_path = File.expand_path(f)
references << project.add_file_reference(full_path, group)
end
end
# Last add the asset catalogs to the target
project.targets.each do |target|
if target.name == "${TARGET_NAME}"
target.add_file_references(references)
end
end
end

Specific many gems from the same github account

like with path and source I'd like to do this:
git 'https://github.com/my_company', branch: 'rm_2422-rails5-upgrade' do
gem 'foo'
gem 'bar'
# many more gems...
end
The idea being this would fetch the foo gem with the URL's https://github.com/my_company/foo.git using the rm_2422-rails5-upgrade branch.
I can see from the bundler docs that this is not how it works and I know I can do:
git 'foo', git: 'https://github.com/my_company/foo.git', branch: 'rm_2422-rails5-upgrade'
But I have lots of gems which need to be pulled from said branch.
I also looked at git_source but this does not seem to work for this case either.
You may define a new git_source in your Gemfile:
git_source(:your_source_name) do |repo_name|
repo_name = "company/#{repo_name}"
"https://github.com/#{repo_name}.git"
end
And then use it:
gem "gem_name", your_company: "gem_repo_name"
This was very simple example, but you may pass more options to the block. We use this approach to redefine original github source to be able to pass auth token for private repositories:
git_source(:github) do |(repo_name, auth_token)|
repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
auth_data = !!auth_token ? "#{auth_token}:x-oauth-basic#" : ""
"https://#{auth_data}github.com/#{repo_name}.git"
end
UPDATE: I found a way to do what you need, but this is quite a dirty hack IMHO. Since Gemfile is a pure ruby file you may define your own functions there:
def my_gem(name, *args)
options = args.last.is_a?(Hash) ? args.pop.dup : {}
version = args || [">= 0"]
options[:branch] = "develop"
gem(name, version, options)
end
And then use it, instead of original gem method:
my_gem "gem_name"
So one solution I used this:
['foo', 'bar'].each do |gem_name|
gem gem_name, git: "https://github.com/my_company/#{gem_name}.git", branch: 'rm_2422-rails5-upgrade'
end

Cocoapods: unable to set pod build setting

In my current project, I'm trying to include an in-house pod with two subspecs - one for the regular app, one for the today widget extension. Unfortunately, Cocoapods (1.2.1) is wrongly inferring the build flags for the pod target. Both targets - the extension pod target and the normal app pod target - have the "Require only App-Extension-Safe API" set to YES, resulting in the -fapplication-extension CLANG compiler flag. Sadly, one target doesn't build in this configuration.
Manually setting the flag to NO resolves the issue, but only until the next pod update. To be specific, this is the setting I'm trying to address:
I'm not even sure what heuristic Cocoapods is using to infer wether this needs to be turned on or off, but is there a way to explicitly set the target build setting? I tried
s.subspec 'Core' do |core|
core.dependency 'xxxxxxx','~> 1.0.1'
core.source_files = 'Pod/Sources/**/*.{h,m,mm}'
core.ios.xcconfig = {
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
'APPLICATION_EXTENSION_API_ONLY' => 'NO'
}
core.tvos.xcconfig = {
'GCC_PREPROCESSOR_DEFINITIONS' => 'TVOS=1',
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES'
}
end
and
s.subspec 'Core' do |core|
core.dependency 'xxxxxxx','~> 1.0.1'
core.source_files = 'Pod/Sources/**/*.{h,m,mm}'
core.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'NO' }
core.ios.xcconfig = {
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
}
core.tvos.xcconfig = {
'GCC_PREPROCESSOR_DEFINITIONS' => 'TVOS=1',
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES'
}
end
Unfortunately, both to no avail. The setting remains stubbornly at YES. I'm at my wit's end here. Anything I can try?
Self-answering: I still don't know how to force the setting, but the problem was actually in our (multi-tiered) dependency graph. A depended-upon subspec was used by both the app and the app extension target, hence forcing the compiler flag for that subspec target.
I fixed it by adding yet another subspec so that the pod target isn't shared by the app and the extension.

Resources