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.
Related
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.
I am trying to figure out why I get two different results after running pod install on what should be identical podspec files. The component is called EarlGreyApp, which had a 2.0.0 release this year. The podspec for the 2.0.0 release is here in the earlgrey2 branch of the EarlGrey repo: https://github.com/google/EarlGrey/blob/earlgrey2/EarlGreyApp.podspec
When I have this defined in the podfile (I am using Demo/EarlGreyExample to reproduce) :
target 'EarlGreyExampleSwift' do
pod 'EarlGreyApp', '2.0.0'
end
It correctly modifies this section of EarlGreyExample.xcodeproj/project.pbxproj to reference EarlGrepApp's AppFramework.framework component:
/* Begin PBXShellScriptBuildPhase section */
4D216774E658C2E4470F936E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-EarlGreyExampleSwift/Pods-EarlGreyExampleSwift-frameworks.sh",
"${PODS_ROOT}/EarlGreyApp/AppFramework.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AppFramework.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-EarlGreyExampleSwift/Pods-EarlGreyExampleSwift-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
However when I change the podfile to point to the branch:
target 'EarlGreyExampleSwift' do
pod 'EarlGreyApp', :git => 'https://github.com/google/EarlGrey.git', :branch => 'earlgrey2'
end
The above section does not get generated into the project.pbxproj file.
I am at a loss to explain why as the podspec registered for EarlGreyApp should be the same. When I do pod spec cat EarlGreyApp I see the same contents as what is in the earlgrey2 branch.
pod spec cat EarlGreyApp --show-all
Shows me that there are only two Podspecs available, 2.0.0 and 2.0.0-rc
Any ideas on what the difference could be?
The reason for this is because the Podspec is not published through the earlgrey2 branch it is published through the earlgrey2pod branch.
The reason for this is some users want to use EarlGrey without CocoaPods and some want to use it with. The two branches have subtle differences to allow for both use cases (compiling issues).
Additionally there are further intricacies with CocoaPods when you do a manual pod install, as you did when you referenced the github directly. I would recommend not trying that. Since EarlGreyApp is compiled as a Framework you cannot just do that unfortunately (you can with EarlGreyTest which is compiled from source). CocoaPods has poor undefined behavior in this regard.
I'm receiving "[!] An internal server error occurred. Please check for any known status issues at https://twitter.com/CocoaPods and try again later." when trying to push a new version of my pod NRSPieChart. I just created this last night and it's the my first time creating my own pod. Everything seemed to have worked on the first submission. Today I updated my version in order to expand my example project and expand my README.md file to provide better Usage instructions. Upon trying to push to Trunk though I get the above error. Since I'm new to this my assumption is I've done something wrong rather than coincidentally there's an error with the spec repo?
I saw one reference to the s.source tag might need a hard code tag string. I tried that but same problem. This is the before (commented line) and after of that attempt:
# s.source = { :git => 'https://github.com/neils4fun/NRSPieChart.git', :tag => s.version.to_s }
s.source = { :git => "https://github.com/neils4fun/NRSPieChart.git", :tag => "0.1.1" }
Update: I tried again "later" as the error message suggested and it's now working. I made no changes to my pod code or pod spec, so chalk this up to something internal on the cocoa pods side of the fence.
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.
I have some apps that are quite similar. Therefore, I'd like to create a or some private pod(s) containing all common reusable code. My first version contains some networking functionality that uses AFNetworking and also uses KeychainItemWrapper:
Pod::Spec.new do |s|
s.name = 'CommonLib'
s.version = '0.0.1'
s.homepage = '****'
s.summary = 'My Common lib'
s.description = 'Library with common code'
s.author = { "Rens Verhage" => "*****" }
s.platform = :ios, '5.0'
s.source = { :git => "ssh://****/CommonLib.git", :tag => s.version.to_s }
s.source_files = 'CommonLib/*.{h,m}'
s.requires_arc = true
s.dependency 'AFNetworking', '~> 1.3.1'
s.dependency 'KeychainItemWrapper', '~> 1.2'
end
Running pod spec lint CommonLib.podspec gives a couple of WARN and NOTE messages:
-> CommonLib (0.0.1)
- WARN | Missing required attribute `license`.
- WARN | Missing license type.
- NOTE | [xcodebuild] AFNetworking/AFNetworking/AFHTTPClient.h:84:9: warning: SystemConfiguration framework not found in project, or not included in precompiled header. Network reachability functionality will not be available. [-W#pragma-messages]
- NOTE | [xcodebuild] AFNetworking/AFNetworking/AFHTTPClient.h:89:9: warning: MobileCoreServices framework not found in project, or not included in precompiled header. Automatic MIME type detection when uploading files in multipart requests will not be available. [-W#pragma-messages]
- NOTE | [xcodebuild] CommonLib/CommonLib/NSArray+NSArray_PerformSelector.m:19:35: warning: performSelector may cause a leak because its selector is unknown [-Warc-performSelector-leaks]
- NOTE | [xcodebuild] CommonLib/CommonLib/NSArray+NSArray_PerformSelector.m:19:51: note: used here
- WARN | [iOS] Unable to find a license file
Analyzed 1 podspec.
[!] The spec did not pass validation.
Notice there are no ERROR messages, but the spec doesn't pass validation however. I don't really no where to go from here. The message that the SystemConfiguration and MobileCoreServices frameworks are missing looks like an error to me. I tried fixing this warning by adding
s.ios.frameworks = 'MobileCoreServices', 'SystemConfiguration'
to my podspec, but that doesn't work.
So, two questions in one:
What is the error that keeps my podspec from passing validation?
How can I fix the warning about missing frameworks?
Recently I had this problem and adding --allow-warnings fixes the issue.
pod spec lint MyProject.podspec --allow-warnings
Ok. Got my answer from the Cocoapods guys. Podspec validation fails on all errors and warnings. Failing on warnings doesn't mean the project fails as a Pod. Turns out I can simply ignore the warning.
As for AFNetworking, the issue has been resolved with version 2.0.
[Updated]
Follow cocoapods guide to configure you podspec file and resolve the error if you are getting any and while validating it, If you are getting warnings only and if you just want to ignore it then yes you can do it by running following command.
Validating podspec with warnings
Add--allow-warningsat the end it will forcefully validate podspec.👇🏻
pod spec lint your_project_name.podspec --allow-warnings
Push podspec repo with warnings
Make sure that you have added your repo, if not run the following command (ignore it, if you have already added it)
pod repo add your-pods pods_git_url
For Pushing podspec to repo use this 👇🏻
pod repo push your-pods your_project_name.podspec --allow-warnings