Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
###### CONSISTENCY BETWEEN MACOS AND IOS #####
#
# In order to use the same PodFile with MacOS, we need to unlink the libraries that do not support Catalyst, filter
# files in native targets build phases, filter dependencies and make sure the unsupported frameworks along with their
# their bundle resources are not included in the final archive. For that, we use `platform_filter` to specify 'ios' and
# 'OTHER_LDFLAGS[sdk=iphone*]' to link those libraries for iPhone and iPad. Besides, we modify "*frameworks.sh" and
# "*resrouces.sh" to skip installation for architecture x86_64.
#
# *Notice*: 'sdk=iphone*' excludes macOS, even though Catalyst is compiled with iOS SDK.
#
# ADDING A NEW LIBRARY
#
# Pass the name of the new library to the script
#
###### RESOURCES #######
#
# https://www.bitbuildr.com/tech-blog/mac-catalyst-porting-an-app-using-crashlytics-firebase - Article that inspired this script
# https://github.com/CocoaPods/Xcodeproj - Xcode configuration using ruby. This Framework is already included on cocoapods environment
# https://www.rubydoc.info/gems/xcodeproj/Xcodeproj/Project/Object/AbstractTarget Wiki for Xcodeproj
#
include Xcodeproj::Project::Object
include Pod
$verbose = false
def loggs string
if $verbose
puts string
end
return
end
# EXTENSIONS
class String
def filter_lines
lines = []
each_line do |line|
if yield line
lines = lines + [line]
end
end
return lines
end
end
class PBXNativeTarget
###### STEP 4 ######
# In "Pods-" targets, modify "*frameworks.sh" to not install unsupported frameworks for platform architectures
def uninstall_frameworks frameworks, platform, configurations
uninstall frameworks, "#{name}-frameworks.sh", platform.architectures, configurations
end
###### STEP 5 ######
# In "Pods-" targets, modify "*resources.sh" to not install unsupported frameworks for platform architectures
def uninstall_resources resources, platform, configurations
uninstall resources, "#{name}-resources.sh", platform.architectures, configurations
end
def support_files_folder
build_configurations.filter do |config| not config.base_configuration_reference.nil? end.first.base_configuration_reference.real_path.parent
end
@private
def uninstall keys, file_name, architectures, configurations=nil
configurations = configurations.nil? ? build_configurations.map { |b| b.name } : configurations
keys = keys.to_set.to_a
loggs "\t\t\tUninstalling for configurations: #{configurations}"
if support_files_folder.nil?
loggs "\t\t\tNothing to uninstall"
return
end
script_path = support_files_folder.join file_name
if !script_path.exist?
loggs "\t\t\tNothing to uninstall"
return
end
script = File.read(script_path)
snippets = script.scan(/if \[\[ \"\$CONFIGURATION\" [\S\s]*?(?=fi\n)fi/)
condition = architectures.map do |arch| "[ \"$ARCHS\" != \"#{arch}\" ]" end.reduce("") do |total, piece| total.empty? ? piece : total + " || " + piece end
changed = false
snippets.filter do |snippet|
configurations.map do |string| snippet.include? string end.reduce(false) do |total, condition| total = total || condition end
end.each do |snippet|
new_snippet = snippet.clone
keys.each do |key|
lines_to_replace = snippet.filter_lines do |line| line.include? "#{key}" end.to_set.to_a
unless lines_to_replace.empty?
changed = true
lines_to_replace.each do |line|
new_snippet.gsub! line, "\tif #{condition}; then \n\t#{line}\tfi\n"
end
end
end
script.gsub! snippet, new_snippet
end
if changed
File.open(script_path, "w") { |file| file << script }
end
loggs "\t\t\t#{changed ? "Succeded" : "Nothing to uninstall"}"
end
###### STEP 1 ######
# In native target's build phases, add platform filter to:
# - Resources
# - Compile Sources
# - Frameworks
# - Headers
def add_platform_filter_to_build_phases platform
loggs "\t\t- Filtering resources"
resources_build_phase.files.to_a.map do |build_file| build_file.platform_filter = platform.name end
loggs "\t\t- Filtering compile sources"
source_build_phase.files.to_a.map do |build_file| build_file.platform_filter = platform.name end
loggs "\t\t- Filtering frameworks"
frameworks_build_phase.files.to_a.map do |build_file| build_file.platform_filter = platform.name end
loggs "\t\t- Filtering headers"
headers_build_phase.files.to_a.map do |build_file| build_file.platform_filter = platform.name end
end
end
class PodTarget
def module_name
string = name.clone.gsub! /-iOS[0-9]+(\.[0-9])+$/, ''
return string.nil? ? name : string
end
def resources
return file_accessors.flat_map do |accessor| accessor.resources end.map do |path| "#{path.basename}" end
end
def vendor_products
return file_accessors.flat_map do |accessor|
accessor.vendored_frameworks + accessor.vendored_libraries
end.map do |s| s.basename
end.map do |s|
name = "#{s}"
if name.include? "framework"
PodDependency.newFramework name.sub(".framework", "")
else
PodDependency.newLibrary name.sub("lib", "").sub(".a", "")
end
end
end
def frameworks
return file_accessors.flat_map do |accessor|
accessor.spec_consumer.frameworks.map do |name| PodDependency.newFramework name end + accessor.spec_consumer.libraries.map do |name| PodDependency.newLibrary name end
end
end
end
class PBXTargetDependency
def module_name
string = name.clone.gsub! /-iOS[0-9]+(\.[0-9])+$/, ''
return string.nil? ? name : string
end
end
class AbstractTarget
def module_name
string = name.clone.gsub! /-iOS[0-9]+(\.[0-9])+$/, ''
return string.nil? ? name : string
end
###### STEP 2 ######
# In all targets (aggregates + native), filter dependencies
def add_platform_filter_to_dependencies platform
loggs "\t\t- Filtering dependencies"
dependencies.each do |dependency|
dependency.platform_filter = platform.name
end
end
###### STEP 3 ######
# If any unsupported library, then flag as platform-dependant for every build configuration
def flag_libraries libraries, platform
loggs "\tTarget: #{name}"
build_configurations.filter do |config| not config.base_configuration_reference.nil?
end.each do |config|
loggs "\t\tScheme: #{config.name}"
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
changed = false
libraries.each do |framework|
if xcconfig.include? framework
xcconfig.gsub!(framework, '')
unless xcconfig.include? "OTHER_LDFLAGS[sdk=#{platform.sdk}]"
changed = true
xcconfig += "OTHER_LDFLAGS[sdk=#{platform.sdk}] = $(inherited) -ObjC "
end
xcconfig += framework + ' '
end
end
File.open(xcconfig_path, "w") { |file| file << xcconfig }
loggs "\t\t\t#{changed ? "Succeded" : "Nothing to flag"}"
end
end
def to_dependency
# We return both as we don't know if build as library or framework
return [PodDependency.newFramework(module_name), PodDependency.newLibrary(module_name)]
end
# Dependencies contained in Other Linker Flags
def other_linker_flags_dependencies
frameworks = Array.new
libraries = Array.new
config = build_configurations.filter do |config| not config.base_configuration_reference.nil? end.first
xcconfig_path = config.base_configuration_reference.real_path
xcconfig = File.read(xcconfig_path)
xcconfig.gsub!(/\r\n?/, "\n")
xcconfig.each_line do |line|
if line.start_with? 'OTHER_LDFLAGS'
frameworks = frameworks + line.split("-framework").map do |s|
s.strip.delete("\n") end.filter do |s|
s.strip.start_with? '"' end
libraries = libraries + line.split("-l").filter do |s| s.strip.start_with? '"' end.map do |s| s.strip.split(' ').first end
end
end
libraries = libraries.map do |name| PodDependency.newLibrary(name.gsub!("\"", "")) end
frameworks = frameworks.map do |name| PodDependency.newFramework(name.gsub!("\"", "")) end
return OtherLinkerFlagsDependencies.new libraries, frameworks
end
end
# HELPER CLASSES
class PodDependency
attr_reader :name
attr_reader :type
def link
if library?
return "-l\"#{name}\""
else
return "-framework \"#{name}\""
end
end
def library?
return type == "library"
end
def framework?
return type == "framework"
end
def self.newFramework name
return PodDependency.new(name, "framework")
end
def self.newLibrary name
return PodDependency.new(name, "library")
end
def ==(other)
name == other.name && type == other.type
end
def eql?(other)
name == other.name
end
private
def initialize(name, type)
@name = name
@type = type
end
end
class OtherLinkerFlagsDependencies
attr_reader :libraries
attr_reader :frameworks
def initialize(libraries = [], frameworks = [])
@libraries = libraries
@frameworks = frameworks
end
def combine dependencies
frameworks = (dependencies.frameworks + @frameworks).to_set.to_a
libraries = (dependencies.libraries + @libraries).to_set.to_a
return OtherLinkerFlagsDependencies.new libraries, frameworks
end
def dependencies
libraries + frameworks
end
end
class OSPlatform
attr_reader :sdk
attr_reader :name
attr_reader :architectures
def self.ios
OSPlatform.new 'ios', 'iphone*', ['arm64', 'armv7s', 'armv7']
end
def self.macos
OSPlatform.new 'macos', 'macosx*', ['x86_64']
end
def self.wtachos
OSPlatform.new 'watchos', 'watchos*', ['arm64_32', 'armv7k']
end
def self.tvos
OSPlatform.new 'tvos', 'appletvos*', ['arm64']
end
private
def initialize(name, sdk, architectures)
@name = name
@sdk = sdk
@architectures = architectures
end
end
# SCRIPT
class Installer
def configure_support_catalyst pod_names_to_keep, pod_names_to_remove, configurations=nil
###### Variable definition ######
targets = pods_project.targets
pod_names_to_remove = pod_names_to_remove.map do |name| name.sub('/', '') end
pod_names_to_keep = pod_names_to_keep.map do |name| name.sub('/', '') end
pod_names_to_keep = recursive_dependencies pod_names_to_keep
pod_names_to_remove = recursive_dependencies(pod_names_to_remove).filter do |name| !pod_names_to_keep.include? name end
pod_targets_to_keep = pod_targets.filter do |pod| pod_names_to_keep.include? pod.module_name end # PodTarget
pod_targets_to_remove = pod_targets.filter do |pod| pod_names_to_remove.include? pod.module_name end # PodTarget
loggs "\n#### Unsupported Libraries ####\n#{pod_names_to_remove}\n"
targets_to_remove = targets.filter do |target| pod_names_to_remove.include?(target.module_name) end # AbstractTarget
pods_targets = targets.filter do |target| target.name.start_with? "Pods-" end # AbstractTarget
cross_platform_targets = targets.filter do |target| !targets_to_remove.include?(target) && !pods_targets.include?(target) end # AbstractTarget
###### Determine which dependencies should be removed ######
dependencies_to_keep = cross_platform_targets.reduce(OtherLinkerFlagsDependencies.new) do |dependencies, target|
dependencies.combine target.other_linker_flags_dependencies
end.dependencies
# [PodDependency]
dependencies_to_keep = dependencies_to_keep + cross_platform_targets.flat_map do |target| target.to_dependency end + pod_targets_to_keep.flat_map do |pod| pod.vendor_products + pod.frameworks end
dependencies_to_remove = targets_to_remove.reduce(OtherLinkerFlagsDependencies.new) do |dependencies, target|
dependencies.combine target.other_linker_flags_dependencies
end.dependencies
# [PodDependency]
dependencies_to_remove = dependencies_to_remove + targets_to_remove.flat_map do |target| target.to_dependency end + pod_targets_to_remove.flat_map do |pod| pod.vendor_products + pod.frameworks end
dependencies_to_remove = dependencies_to_remove.filter do |d| !dependencies_to_keep.include? d end
###### CATALYST NOT SUPPORTED LINKS ######
unsupported_links = dependencies_to_remove.map do |d| d.link end.to_set.to_a
loggs "#### Unsupported dependencies ####\n"
loggs "#{dependencies_to_remove.map do |d| d.name end.to_set.to_a }\n\n"
###### CATALYST NOT SUPPORTED FRAMEWORKS AND RESOURCES
frameworks_to_uninstall = dependencies_to_remove.filter do |d| d.framework? end.map do |d| "#{d.name}.framework" end.to_set.to_a
resources_to_uninstall = pod_targets_to_remove.flat_map do |pod| pod.resources end.to_set.to_a
loggs "#### Frameworks not to be included in the Archive ####\n"
loggs "#{frameworks_to_uninstall}\n\n"
loggs "#### Resources not to be included in the Archive ####\n"
loggs "#{resources_to_uninstall}\n\n"
###### OTHER LINKER FLAGS -> to iphone* ######
loggs "#### Flagging unsupported libraries ####"
targets.each do |target| target.flag_libraries unsupported_links, OSPlatform.ios end
###### BUILD_PHASES AND DEPENDENCIES -> PLATFORM_FILTER 'ios' ######
loggs "\n#### Filtering build phases ####"
targets_to_remove.filter do |target|
pods_project.native_targets.include? target
end.each do |target|
loggs "\tTarget: #{target.name}"
target.add_platform_filter_to_build_phases OSPlatform.ios
target.add_platform_filter_to_dependencies OSPlatform.ios
end
loggs "\n#### Filtering dependencies ####"
targets_to_remove.filter do |target|
!pods_project.native_targets.include? target
end.each do |target|
loggs "\tTarget: #{target.name}"
target.add_platform_filter_to_dependencies OSPlatform.ios
end
###### FRAMEWORKS AND RESOURCES SCRIPT -> if [ "$ARCHS" != "x86_64" ]; then #######
loggs "\n#### Chagings frameworks and resources script ####"
pods_targets.each do |target|
loggs "\tTarget: #{target.name}"
loggs "\t\t-Uninstalling frameworks"
target.uninstall_frameworks frameworks_to_uninstall, OSPlatform.macos, configurations
loggs "\t\t-Uninstalling resources"
target.uninstall_resources resources_to_uninstall, OSPlatform.macos, configurations
end
end
@private
def recursive_dependencies to_filter_names
targets = pods_project.targets
targets_to_remove = targets.filter do |target| to_filter_names.include? target.module_name end
dependencies = targets_to_remove.flat_map do |target| target.dependencies end
dependencies_names = dependencies.map do |d| d.module_name end
if dependencies.empty?
return to_filter_names + dependencies_names
else
return to_filter_names + recursive_dependencies(dependencies_names)
end
end
end
@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented Apr 26, 2020

This works really great, thanks for writing this! One issue I found is it doesn't strip resources that a Framework may contain. For example, GoogleSignIn.bundle is still present from the 'GoogleSignIn' pod. It doesn't prevent it from building but prevents it from uploading to App Store Connect.

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented Apr 27, 2020

Thanks, I appreciate it. That sounds weird, I’d swear Cocoapods scripts strip the frameworks, here I’m just unlinking them.

Maybe I’m missing something. I have my App uploaded to the App Store and works like a charm. I just have some warnings symbol-related.

I’ll dig into this, thanks a lot for your feedback.

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented Apr 27, 2020

Hi again,

Can you try adding this after line 168?

targets_to_filter.each do |target| 
  target.build_configurations.each do |config|
#    config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf'
    config.build_settings['STRIP_INSTALLED_PRODUCT'] = 'YES'
    config.build_settings['COPY_PHASE_STRIP'] = 'YES'
    config.build_settings['DEPLOYMENT_POSTPROCESSING'] = 'YES'
  end
end

You can try commenting or uncommenting config.build_settings['DEBUG_INFORMATION_FORMAT'] = 'dwarf'. Let me know if it works, this should strip the symbols.

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented Apr 30, 2020

Sure, I'll give it a try and let you know.

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 1, 2020

Doesn't seem to work:
ERROR ITMS-90276: "Missing Bundle Identifier. The application bundle contains a tool or framework ${PRODUCT_NAME} [com.myapp.myapp.pkg/Payload/MyApp.app/Contents/Resources/GoogleSignIn.bundle] that is missing the bundle identifier in its Info.plist file."

@Phacometer

This comment has been minimized.

Copy link

Phacometer commented May 3, 2020

Hi, I tried your script on GoogleAppMeasurement, it works and removes the Mac Catalyst error, but it gives two new errors:
"Undefined symbol: OBJC_CLASS$_GADMobileAds"
and
"Undefined symbol: OBJC_CLASS$_GADRequest".

Any thoughts on how to fix that? Thanks.

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 3, 2020

Hi @Phacometer, can you share your Podfile please?

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 3, 2020

Hi @henrytkirk, I'm trying to figure out a way to unlink that bundle. The problem is it doesn't appear in GoogleSignIn's Build phase. What you could do is maybe when you're going to upload an IPA to the App Store, have Fastlane (or other tool) or manually delete that bundle from your ipa. So export it and then delete this bundle or do so directly in the project. I'm still seeing what it can be done

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 3, 2020

Hi @fermoya - yes, I'm doing that manually for now. I'm not blocked from submitting anymore. Thanks for trying to fix this issue and providing this script.

@Phacometer

This comment has been minimized.

Copy link

Phacometer commented May 4, 2020

Hi @fermoya, here is my Podfile:

load 'remove_unsupported_libraries.rb'
target 'What2Do When Bored' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  pod 'Google-Mobile-Ads-SDK'
	
end

def unsupported_pods
   ['GoogleAppMeasurement']
end
post_install do |installer|
   configure_support_catalyst installer, unsupported_pods
end
@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 4, 2020

Hi @Phacometer,

Unfortunately, this isn't how the script is thought to work. If a framework isn't compatible with MacOS, you need to "unlink" that framework, not a dependency. Otherwise, it won't compile. So it should be:

def unsupported_pods
   ['Google-Mobile-Ads-SDK']
end

This will configure this framework and its dependencies so that they're not link for macOS.

Anyway, I've installed Google-Mobile-Ads-SDK in a sample project, version is 7.58.0, Xcode 11.3.1 (not updated yet, I'm having some issues) and it compiles so you wouldn't need to add this framework to the unsupported_pods list

@Phacometer

This comment has been minimized.

Copy link

Phacometer commented May 4, 2020

Hi @fermoya,

I removed Google Mobile Ads SDK from unsupported_pods and updated the pods with pod install --repo-update. However it is giving me the old error building for Mac Catalyst, but linking in object file built for iOS Simulator. How did you manage to compile the Mobile Ads SDK for Mac Catalyst? Am I not installing the latest version?

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 4, 2020

Hi @henrytkirk,

Good to hear you're not blocked. If you check your project folder, you should have a file called Pod-MyProjectName-resources.sh. You should have an if condition like this:

if [[ "$CONFIGURATION" == "Release" ]]; then
    install_resource "${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle"
fi

You can swap if with this:

if [[ "$CONFIGURATION" == "Release" ]] && [ "$ARCHS" != "x86_64" ]; then
    install_resource "${PODS_ROOT}/GoogleSignIn/Resources/GoogleSignIn.bundle"
fi

This will install the resource in your bundle only if it's not a macOS architecture. That should do the trick. Notice if you run pod install or pod update, this script will be generated again and you'll have to modify the script again. I'll keep digging to see if I can do this automatically from the script.

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 4, 2020

Hi @Phacometer,

Sorry, you're right it doesn't compile. All in all, the pod you're installing is Google-Mobile-Ads-SDK which has a dependency, GoogleAppMeasurement that's incompatible with macCatalyst. The script needs to be needed with Google-Mobile-Ads-SDK, not its dependency, as it'll unlink this library for macOS. If you pass GoogleAppMeasurement then it'll successfully unlink this framework for macOS but Google-Mobile-Ads-SDK won't compile.

So, Google-Mobile-Ads-SDK needs GoogleAppMeasurement to compile and the latter doesn't compile for macCatalyst. Therefore, Google-Mobile-Ads-SDK is incompatible with macCatalyst. You'll need to feed the script with Google-Mobile-Ads-SDK and use #if !targetEnvironment(macCatalyst) to not import this framework in your file.

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 13, 2020

Hi @henrytkirk,

I've updated the script to automatically remove bundle resources that could come with the Pod. I've been trying it with GoogleSignIn and worked for me, not included for macOS but yes for iOS. I hope it works.

Best

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 18, 2020

@fermoya,
I'm getting an error, did you add an argument to the script? I see "pod_names_to_keep" was added.

[!] An error occurred while processing the post-install hook of the Podfile.
wrong number of arguments (given 2, expected 3)
remove_unsupported_libraries.rb:320:in 'configure_support_catalyst'

The way I'm calling the script in my Podfile is as follows:

load 'remove_unsupported_libraries.rb'
def unsupported_pods
  ['Firebase/Analytics', 'GoogleSignIn']
end

post_install do |installer|
  # Remove unsupported pods.
  configure_support_catalyst installer, unsupported_pods
end
@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 18, 2020

Hi @henrytkirk,

That’s right, I added it 2 weeks ago I think. I noticed that dependencies might be shared between pods and I would be wrongly unlinking them if needed for a cross-platform pod.

So the script needs to know the pods you’re installing that support macOS architectures and the pods that don’t support macOS architectures.

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 18, 2020

Ok, I guess it's not too bad to manage those lists. My project has a lot of targets and pods.

Thanks!

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 18, 2020

@henrytkirk, let me know if you find any issue. So the last additions are:

  • Matching supported and unsupported to determine the dependencies to remove
  • Modifying "-resources.sh" and "-frameworks.sh" to skip installation for architecture x86_64
@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 18, 2020

@fermoya,

So far so good - except this CocoaPod fails, and I can't figure out how to resolve:

Firebase Analytics:
https://github.com/CocoaPods/Specs/blob/master/Specs/e/2/1/FirebaseAnalytics/6.5.0/FirebaseAnalytics.podspec.json

ld: in /Users/.../Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector(FIRAnalyticsConnector_c162b9f6e9dd193ef13757b8d7ebe6f7.o), building for Mac Catalyst, but linking in object file built for iOS Simulator, file '/Users/.../Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector' for architecture x86_64

Ideas? This used to work before, not sure if it's a change in Firebase or the script.

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 18, 2020

I wonder if it's this umbrella header:
https://github.com/firebase/firebase-ios-sdk/blob/master/CoreOnly/Sources/Firebase.h

I'll try manually adding the ones I need.

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 18, 2020

Hi @henrytkirk,

How are you using Firebase pods? I'm using them too and I'm not having that problem. Notice Firebase/Analytics contains pods that aren't compiled for macOS.

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 18, 2020

@fermoya,

Firebase Analytics isn't supported in Catalyst. I'm also using Auth, Core, Remote Config, etc. It was working fine about two-three weeks ago. Which ones are you using? What does your pod file look like?

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 18, 2020

def cross_platform_libraries
  [
    'Firebase/Auth',
   'Firebase/Database',
    'Firebase/RemoteConfig'
 ]
end

def ios_only_libraries
  [
    'Firebase/Analytics'
 ]
end
@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 21, 2020

@fermoya,

Still can't get this to work correctly. Keeps failing on FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework.

Here is are my supported/unsupported pods so far:

def supported_pods
  ['AFNetworking', 'FBSDKCoreKit', 'Firebase/Auth', 'GTMAppAuth', 'Colours', 'Firebase/RemoteConfig', 'Bolts', 'FBSDKLoginKit']
end
def unsupported_pods
  ['Firebase/Messaging', 'Firebase/Crashlytics', 'Firebase/Analytics', 'GoogleSignIn']
end

Any ideas? Could the script be missing something?

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 21, 2020

Hi @henrytkirk, can you look up "FIRAnalyticsConnector.framework" in your project and verify is always under "OTHER_LDFLAGS[sdk=iphone*]"?

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 21, 2020

@fermoya, sorry I'm not familiar with how to identify that. Can you provide some steps?

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 21, 2020

@fermoya, if you're speaking about the pod .xcconfig, here's the FirebaseAnalytics one:

CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FirebaseAnalytics-iOS13.4
FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore-iOS10.0" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreDiagnostics-iOS10.0" "${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations-iOS10.0" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransport-iOS10.0" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleDataTransportCCTSupport-iOS10.0" "${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities-1cc9386e" "${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC-iOS10.0" "${PODS_CONFIGURATION_BUILD_DIR}/nanopb-iOS10.0" "${PODS_ROOT}/FirebaseAnalytics/Frameworks" "${PODS_ROOT}/GoogleAppMeasurement/Frameworks"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public"
OTHER_LDFLAGS = $(inherited) -l"c++" -l"sqlite3" -l"z" -framework "StoreKit"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_ROOT = ${SRCROOT}
PODS_TARGET_SRCROOT = ${PODS_ROOT}/FirebaseAnalytics
PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
SKIP_INSTALL = YES
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 21, 2020

Hi @henrytkirk,

I meant you should see something like this:

OTHER_LDFLAGS[sdk=iphone*] = $(inherited) -ObjC -l"sqlite3" -framework "CoreGraphics" -framework "CoreText" -framework "LocalAuthentication" -framework "StoreKit" -framework "FirebaseAnalytics" -framework "FirebaseCrashlytics" -framework "FirebaseInstanceID" -framework "FirebaseMessaging" -framework "GoogleAppMeasurement" -framework "GoogleSignIn" -framework "FIRAnalyticsConnector" 

In "Pod-YourAppName.debug.xcconfig".

I just created a new project, I'm installing the libraries you mentioned and it building fine, I'm sharing the Podfile below. Notice I'm explicitly using a version for Firebase pods, 6.23.0. This is because Cocoapods was for some reason installing Firebase.h 3.6.0 for me, which is wrong. If you try using 6.24.0 or 6.25.0 you'll find the error:

[!] CocoaPods could not find compatible versions for pod "GoogleAppMeasurement":
  In Podfile:
    Firebase/Analytics (= 6.24.0) was resolved to 6.24.0, which depends on
      Firebase/Core (= 6.24.0) was resolved to 6.24.0, which depends on
        FirebaseAnalytics (= 6.5.0) was resolved to 6.5.0, which depends on
          GoogleAppMeasurement (= 6.5.0)

I guess they'll be looking into this now. The PodFile is this:

load 'remove_ios_only_frameworks.rb'

def supported_pods
  [
  'AFNetworking',
  'FBSDKCoreKit',
  'Firebase/Auth',
  'GTMAppAuth',
  'Colours',
  'Firebase/RemoteConfig',
  'Bolts',
  'FBSDKLoginKit'
  ]
end

def unsupported_pods
  [
  'Firebase/Messaging',
  'Firebase/Crashlytics',
  'Firebase/Analytics',
  'GoogleSignIn'
  ]
end

target 'CollectionViewLayoutExample' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for CollectionViewLayoutExample

  pod 'AFNetworking'
  pod 'FBSDKCoreKit'
  pod 'GTMAppAuth'
  pod 'Colours'
  pod 'Bolts'
  pod 'FBSDKLoginKit'
  pod 'Firebase/Messaging', '6.23.0'
  pod 'Firebase/Crashlytics', '6.23.0'
  pod 'Firebase/Analytics', '6.23.0'
  pod 'Firebase/RemoteConfig', '6.23.0'
  pod 'Firebase/Auth', '6.23.0'
  pod 'GoogleSignIn'

end

post_install do |installer|
  configure_support_catalyst installer, supported_pods, unsupported_pods
end
@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 21, 2020

@fermoya,

None of my Cocoapods xcconfig files have "OTHER_LDFLAGS[sdk=iphone*]". How is that set?

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 21, 2020

@henrytkirk, you need to go to your project folder and run pod install from the terminal so that configure_support_catalyst is called from your Podfile.
Screenshot 2020-05-21 at 13 47 39

@henrytkirk

This comment has been minimized.

Copy link

henrytkirk commented May 21, 2020

Yes, that's how I've been doing it.

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented May 21, 2020

@henrytkirk, do you maybe want to schedule a Skype call? Reach me out at fmdr.ct@gmail.com

@Brett-Best

This comment has been minimized.

Copy link

Brett-Best commented Jun 10, 2020

@fermoya have you used this with the unsupported pod AppCenter/Distribute?

@fermoya

This comment has been minimized.

Copy link
Owner Author

fermoya commented Jun 11, 2020

@Brett-Best, no I haven't. When you do pod AppCenter/Distribute it seems that the pod target installed is called AppCenter and not AppCenterDistribute as the script expects. So instead, you should add AppCenter to the unsupported list.

Please, refer to CatalystPodSupport in the future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.