Excluding the IDFA from the final binary using Countly - ios

I'm trying to exclude the IDFA from my final binary using Countly so I can answer no to the Export Compliance question "Does your app use the IDFA?".
Adding COUNTLY_EXCLUDE_IDFA=1 to Build Settings > Preprocessor Macros as mentioned here doesn't work.
I've narrowed it down to #ifndef not behaving as expected. This is what I've tried:
With COUNTLY_EXCLUDE_IDFA=1 added in Build Settings > Preprocessor Macros:
#ifndef COUNTLY_EXCLUDE_IDFA
printf("!EXCLUDED\n");
#else
printf("EXCLUDED\n");
#endif
>> prints !EXCLUDED
With COUNTLY_EXCLUDE_IDFA not defined in Build Settings > Preprocessor Macros:
#ifndef COUNTLY_EXCLUDE_IDFA
printf("!EXCLUDED\n");
#else
printf("EXCLUDED\n");
#endif
>> prints !EXCLUDED
I expect #ifndef to include a block if the Macro is not defined. Now the #ifndef block is included wether or not I have the Macro defined in Build Settings > Preprocessor Macros.

Please make sure you set COUNTLY_EXCLUDE_IDFA for the correct target and build configuration.
If you are adding Countly iOS SDK source files directly to your project, make sure the flag is added to your app target.
If you are adding it as a framework, make sure the flag is added to framework target.

I have this in Podfile, and it works fine.
post_install do |installer|
installer.pods_project.targets.each do |target|
if target.name == "Countly"
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', 'COUNTLY_EXCLUDE_IDFA=1']
end
end
end
end

Related

Cocoapods post_install, how to add target membership in Pods project

I have a Podfile, that when constructing the Pods.xcodeProj ends up with an included xcframework that is a Pods.xcodeproj file reference, that I need to add as a target reference to one of the pods built targets.
I think it's possible to do such a thing in the Podfile post_install phase, but I cannot figure out the xcodeproj gem syntax required to (A) find the Nami.xcframework reference I need to add to the target, then (B) add that file reference to the desired target (see image below for the framework I wish to adjust target membership for, I basically just want to automate checking that target membership box).
My start to this Podfile script looks like:
post_install do |installer|
nami_target = installer.pods_project.targets { |f| f.name == "react-native-nami-sdk" }
#Pseudocode begins here, this is what I cannot figure out
nami_xcframework_fileref = ??
nami_target.addBuildReference(nami_xcframework)
end
Thanks for any help on this, I've found a number of example pod file scripts but none seem to do quite what I am trying to do.
I managed to figure out the full script I needed, the Podfile post_install script below does exactly what I was looking for.
Note that a key was that while you can examine targets by using the .name property, for file references only .path will always have contents you can examine, .name is often blank. Also another key item, is that you need to add the file reference to the frameworks_build_phase aspect of the target.
The final script (added to the end of a Podfile):
post_install do |installer|
puts("Attempting to add Nami.xcframework reference to react-native-nami-sdk project.")
installer.pods_project.targets.each do |target|
if target.name == "react-native-nami-sdk"
puts("Found react-native-nami-sdk target.")
all_filerefs = installer.pods_project.files
all_filerefs.each do |fileref|
if fileref.path.end_with? "Nami.xcframework"
puts("Found Nami.xcframework fileref.")
build_phase = target.frameworks_build_phase
puts("Determining if react-native-nami-sdk build phase needs correction.")
unless build_phase.files_references.include?(fileref)
puts("Adding Nami.xcframework to react-native-nami-sdk target")
build_phase.add_file_reference(fileref)
end
end
end
end
end
end

How to set CLANG_ENABLE_MODULES = NO for pod generated project?

I'm trying to integrate ccache on my project which doesn't support clang modules. So I disabled clang modules in my main xcode project like below.
But for cocoapods generated project files, clang modules are enabled by default. Even if I change this setting, cocoapods will change it back on next pod update.
Is there anyway to let pod know that I want to fall back to the old behavior before apple introduced clang modules? Turn off CLANG_ENABLE_MODULES, and link system frameworks used by other pod generated static library for me in my main project automatically, like AVFoundation, MapKit, etc
Are you a Chinese developer? Have you seen this article before?
https://zhuanlan.zhihu.com/p/27584726
It's a tutorial of using ccache to speed up Xcode build process.It also provide the config of cocoapods.
I copied the code here, to let others who don't know Chinese and encounter the same problem know how to solve this problem.
post_install do |installer_representation|
installer_representation.pods_project.targets.each do |target|
target.build_configurations.each do |config|
#关闭 Enable Modules (Translation:Close Enable Modules)
config.build_settings['CLANG_ENABLE_MODULES'] = 'NO'
# 在生成的 Pods 项目文件中加入 CC 参数,路径的值根据你自己的项目来修改(Translation: Add CC parameter to pods project. You can change the path to whatever you want.)
config.build_settings['CC'] = '$(PODS_ROOT)/../ccache-clang'
end
end
end
but this configuration only turn off CLANG_ENABLE_MODULES.
As far as I know, there is no way to link system frameworks when using ccache and cocoapods.
Hope it helps.
If you are creating a custom pod, in your podspec file, write something like this,
Pod::Spec.new do |s|
# some configuration
s.pod_target_xcconfig = {
'OTHER_LDFLAGS' => '-lObjC', # if you created a category for a class from other lib
'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
'CLANG_ENABLE_MODULES' => 'NO', # here is what you want
'CLANG_WARN_DOCUMENTATION_COMMENTS' => 'NO',
'GCC_C_LANGUAGE_STANDARD' => 'gnu17'
}
end

Cocoapods and custom xcconfig

I am trying to use Cocoapods with some custom configurations in an iOS project.
I have 3 (Dev, Stage, Prod) and each of them has some custom GCC_PREPROCESSOR_DEFINITIONS.
I have seen around people suggesting to us #include <path-to-pods.xcconfig>, but this seems to the old way to do this.
I have seen Cocoapods 0.39 is automatically generating its config files based on my configurations and adding them to my targets automatically (and this is good).
This is also confirmed by this article who is talking about a "new way" to create Podfiles.
The problem is these files don't contain my configurations.
I was trying to use xcodeproj and link_with, but without success.
Does anyone know what is the correct way to deal with Cocoapods + custom xcconfig files?
The problem is that CocoaPods is based on xcconfig files and sets the actual variables. But these values cannot be used in any way when the full configuration is in xcconfig files like:
#include "../Pods/Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig"
GCC_PREPROCESSOR_DEFINITIONS = ...
In this case GCC_PREPROCESSOR_DEFINITIONS overwrites the previous value.
Here is the way to solve it:
Update the Podfile to re-define the GCC_PREPROCESSOR_DEFINITIONS value with PODS_ prefix on post_install:
post_install do |installer|
work_dir = Dir.pwd
Dir.glob("Pods/Target Support Files/Pods-Demo/*.xcconfig") do |xc_config_filename|
full_path_name = "#{work_dir}/#{xc_config_filename}"
xc_config = File.read(full_path_name)
new_xc_config = new_xc_config.sub(/GCC_PREPROCESSOR_DEFINITIONS/, 'PODS_GCC_PREPROCESSOR_DEFINITIONS')
File.open(full_path_name, 'w') { |file| file << new_xc_config }
end
end
Define xcconfig file in the next way:
#include "../Pods/Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig"
GCC_PREPROCESSOR_DEFINITIONS = $(PODS_GCC_PREPROCESSOR_DEFINITIONS) ...
In this case GCC_PREPROCESSOR_DEFINITIONS should contain PODS_GCC_PREPROCESSOR_DEFINITIONS & you custom values.

Cocoapods "OTHER_LDFLAGS " Duplicate symbols because of -all_load

My app uses a vendor - static library that doesn't like the "-all_load" linker flag. It would throw duplicate errors if i used it.
The problem i have right now is i need to use the new box sdk as well. The podspec of the SDK has the below.
s.xcconfig = { "OTHER_LDFLAGS" => "-ObjC -all_load" }
Therefore, the build fails with duplicate symbols in the vendor lib.
I've read online that i can avoid getting in such a situation by using -force_load only on the library that needs -ObjC -all_load. I cannot use that as a solution because i have no control over BOX podspec
Is there a way i can override any of these in my app; I'd really appreciate any help.
After battling with this for a few hours, i figured how to get this done. Posting it here so that it might help someone who get into a similar problem. I added the below post_install hook to the Podfile and voi-la it worked!!
post_install do |installer_representation|
installer_representation.project.targets.each do |target|
target.build_configurations.each do |config|
if target.name == "Pods"
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
new_xcconfig = xcconfig.gsub("-ObjC -all_load",'-force_load $(BUILT_PRODUCTS_DIR)/libPods-box-ios-sdk.a')
File.open(xcconfig_path, "w") { |file| file << new_xcconfig }
end
end
end
end

Test selected target with preprocessors macro

I want to test the selected Target with preprocessors macro. Anybody have an idea ?
#if TARGET1
#myVar #"aValue"
#elsif TARGET2
#myVar #"anotherValue"
#endif
Thank you by advance !
See please 'Build Settings' tab in xcode project for a specific target and 'Preprocessor macros' option. You can define a macros there and use it in code like:
#ifdef DEBUG
#myVar #"aValue"
#else
#myVar #"anotherValue"
#endif

Resources