diff --git a/editions/free/Free-Info.plist b/editions/free/Free-Info.plist index a78b3e89..bb6e9ba3 100644 --- a/editions/free/Free-Info.plist +++ b/editions/free/Free-Info.plist @@ -2,8 +2,6 @@ - LSSupportsOpeningDocumentsInPlace - NSMicrophoneUsageDescription Used to record sounds for your projects NSCameraUsageDescription diff --git a/ios/Podfile b/ios/Podfile index 86d7267f..f49b7fdc 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,3 +1,5 @@ +load 'remove_unsupported_libraries.rb' + # Uncomment this line to define a global platform for your project platform :ios, '8.0' @@ -11,3 +13,18 @@ end target 'ScratchJrTests' do end + +# define unsupported pods +def unsupported_pods + ['Firebase/Analytics'] +end + +def supported_pods + ['SSZipArchive'] +end + +# Remove unsupported pods from your project +post_install do |installer| + $verbose = true # remove or set to false to avoid printing + installer.configure_support_catalyst(supported_pods, unsupported_pods) +end \ No newline at end of file diff --git a/ios/Podfile.lock b/ios/Podfile.lock index beebfaef..69c5f07b 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -99,6 +99,6 @@ SPEC CHECKSUMS: nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 SSZipArchive: cefe1364104a0231268a5deb8495bdf2861f52f0 -PODFILE CHECKSUM: 43eaf7714849e36c6216d378a51f3dc168eda736 +PODFILE CHECKSUM: 046f57a5087fb12afecf0de2ddc52f29bed6fa98 -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.1 diff --git a/ios/ScratchJr Free.entitlements b/ios/ScratchJr Free.entitlements new file mode 100644 index 00000000..3fef2bf9 --- /dev/null +++ b/ios/ScratchJr Free.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.device.audio-input + + com.apple.security.device.camera + + com.apple.security.network.client + + + diff --git a/ios/ScratchJr.xcodeproj/project.pbxproj b/ios/ScratchJr.xcodeproj/project.pbxproj index e7c87bc6..1becf304 100644 --- a/ios/ScratchJr.xcodeproj/project.pbxproj +++ b/ios/ScratchJr.xcodeproj/project.pbxproj @@ -49,7 +49,7 @@ isEditable = 1; outputFiles = ( ); - script = ""; + script = "# Type a script or drag a script file from your workspace to insert its path.\n"; }; /* End PBXBuildRule section */ @@ -68,6 +68,7 @@ 20B2226818A4404B003BDE44 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = SOURCE_ROOT; }; 20B2226E18A46327003BDE44 /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; }; 20B2227818A53688003BDE44 /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; }; + 40A3556426A8E31100FF2C2D /* ScratchJr Free.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "ScratchJr Free.entitlements"; sourceTree = ""; }; 40AF1E472619DB10000F853E /* NSDictionary+JSONString.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+JSONString.h"; path = "src/NSDictionary+JSONString.h"; sourceTree = ""; }; 40AF1E482619DB10000F853E /* NSDictionary+JSONString.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+JSONString.m"; path = "src/NSDictionary+JSONString.m"; sourceTree = ""; }; 512C88D0E9938AB5972ACF38 /* libPods-ScratchJrTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ScratchJrTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -131,6 +132,7 @@ 204D809C18A4140600ECBB8B = { isa = PBXGroup; children = ( + 40A3556426A8E31100FF2C2D /* ScratchJr Free.entitlements */, D92D0FE41C335BDE00C573AD /* src */, 20B2226818A4404B003BDE44 /* Settings.bundle */, D9104A9F1C220516004D1708 /* Editions */, @@ -430,7 +432,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "EDITION=free;\n\n../bin/bundle-compile.sh;\n\nrsync -pvtrlL --cvs-exclude \\\n ../editions/$EDITION/ios-resources/* \\\n \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/\";\n\nrsync -pvtrlL --cvs-exclude \\\n ../editions/$EDITION/src/* \\\n \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/HTML5\";\n \nmkdir -p \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/HTML5/pnglibrary\";\n\n../bin/convert-svg-to-png.py -i \"../editions/$EDITION/src/svglibrary/\" -o \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/HTML5/pnglibrary\";\n"; + shellScript = "EDITION=free;\n\n#../bin/bundle-compile.sh;\n\nrsync -pvtrlL --cvs-exclude \\\n ../editions/$EDITION/ios-resources/* \\\n \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/\";\n\nrsync -pvtrlL --cvs-exclude \\\n ../editions/$EDITION/src/* \\\n \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/HTML5\";\n\nmkdir -p \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/HTML5/pnglibrary\";\n\n../bin/convert-svg-to-png.py -i \"../editions/$EDITION/src/svglibrary/\" -o \"$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/HTML5/pnglibrary\";\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -648,6 +650,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "Free-AppIcon"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "Free-LaunchImage"; + CODE_SIGN_ENTITLEMENTS = "ScratchJr Free.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = W7AR3WMP87; @@ -659,9 +662,11 @@ ); INFOPLIST_FILE = "$(SRCROOT)/../editions/free/Free-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.3; + OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = edu.mitmedialab.scratchjrfree; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + SUPPORTS_MACCATALYST = YES; TARGETED_DEVICE_FAMILY = 2; WRAPPER_EXTENSION = app; }; @@ -673,6 +678,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "Free-AppIcon"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = "Free-LaunchImage"; + CODE_SIGN_ENTITLEMENTS = "ScratchJr Free.entitlements"; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DEVELOPMENT_TEAM = W7AR3WMP87; @@ -684,9 +690,11 @@ ); INFOPLIST_FILE = "$(SRCROOT)/../editions/free/Free-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.3; + OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = edu.mitmedialab.scratchjrfree; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + SUPPORTS_MACCATALYST = YES; TARGETED_DEVICE_FAMILY = 2; WRAPPER_EXTENSION = app; }; diff --git a/ios/ScratchJr/src/AppDelegate.m b/ios/ScratchJr/src/AppDelegate.m index b1a2fea2..bff9e415 100644 --- a/ios/ScratchJr/src/AppDelegate.m +++ b/ios/ScratchJr/src/AppDelegate.m @@ -1,6 +1,8 @@ #import "AppDelegate.h" #import "ScratchJr.h" +#if !TARGET_OS_MACCATALYST @import Firebase; +#endif @implementation AppDelegate @@ -20,8 +22,10 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( self.window.rootViewController = [[ViewController alloc] initWithNibName:@"View" bundle:nil]; [self.window makeKeyAndVisible]; +#if !TARGET_OS_MACCATALYST // Configure Firebase [FIRApp configure]; +#endif return YES; } diff --git a/ios/ScratchJr/src/JsBridge.m b/ios/ScratchJr/src/JsBridge.m index 1f3e7913..a5bb647c 100644 --- a/ios/ScratchJr/src/JsBridge.m +++ b/ios/ScratchJr/src/JsBridge.m @@ -7,7 +7,9 @@ #import "ScratchJr.h" #import +#if !TARGET_OS_MACCATALYST @import Firebase; +#endif @implementation JsBridge @@ -182,16 +184,20 @@ -(void) analyticsEvent: (JsRequest *) request { if (![request.params[2] isEqual:[NSNull null]]) { label = request.params[2]; } +#if !TARGET_OS_MACCATALYST [FIRAnalytics logEventWithName:request.params[1] // action parameters:@{ kFIRParameterItemName:label, // label kFIRParameterItemCategory:request.params[0] // category }]; +#endif [request callback:@"ok"]; } -(void) setAnalyticsPlacePref: (JsRequest *) request { +#if !TARGET_OS_MACCATALYST [FIRAnalytics setUserPropertyString:request.params[0] forName:@"place_preference"]; +#endif [request callback:@"ok"]; } @@ -199,7 +205,9 @@ -(void) setAnalyticsPlacePref: (JsRequest *) request { -(void) setAnalyticsPref: (JsRequest *) request { NSString *name = [NSString stringWithFormat:@"%@", request.params[0]]; NSString *propertyString = [NSString stringWithFormat:@"%@", request.params[1]]; +#if !TARGET_OS_MACCATALYST [FIRAnalytics setUserPropertyString:propertyString forName:name]; +#endif [request callback:@"ok"]; } diff --git a/ios/ScratchJr/src/ViewController.m b/ios/ScratchJr/src/ViewController.m index 1df91fbc..7c27f58f 100644 --- a/ios/ScratchJr/src/ViewController.m +++ b/ios/ScratchJr/src/ViewController.m @@ -1,7 +1,9 @@ #import "ScratchJr.h" #import // @import MessageUI; +#if !TARGET_OS_MACCATALYST @import Firebase; +#endif WKWebView *webview; NSDate* startDate; @@ -183,8 +185,10 @@ - (void) webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)naviga NSArray* parts = [screenString componentsSeparatedByString:@"/"]; NSString* page = [[[parts lastObject] componentsSeparatedByString:@"?"] firstObject]; +#if !TARGET_OS_MACCATALYST // Track pageview in Firebase? [FIRAnalytics setScreenName:page screenClass:NULL]; +#endif } - (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error { diff --git a/ios/remove_unsupported_libraries.rb b/ios/remove_unsupported_libraries.rb new file mode 100644 index 00000000..34fb2f04 --- /dev/null +++ b/ios/remove_unsupported_libraries.rb @@ -0,0 +1,447 @@ +###### 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 \ No newline at end of file