Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read .xcconfig file constants with ruby to use them as Fastlane lane variables?

I'm trying to deploy my iOS apps with Fastlane with the current configuration: a single project with multiple targets and multiple environments (using .xccconfig files). I created 3 lanes: development, beta, distribution. Theses lanes takes a "brand_name" as parameter so I can use the same lane for every targets.

What I'm trying to achieve is to "read" the constants in the target's .xcconfig file (e.g PRODUCT_BUNDLE_IDENTIFIER) and use it as a variable in my lane. I managed to do this by creating and reading a yaml file containing the target's bundle id, but since I'm already using .xcconfig files I would like to avoid duplication. I did some searching to find an answer but since I'm fairly new to ruby I'm stuck right now. Is there a way to achieve this please?

If it helps, here is a working lane I'm currently using with a comment on the part I want to replace using a .xcconfig file instead of a yaml file :

lane :development do |options|

    # Getting lane settings

    #adding lane_name to the options
    options = options.merge(lane_name: 'development') 

    # THIS IS THE PART I'D LIKE TO REPLACE WITH .XCCONFIG FILE INSTEAD OF YAML
    #fastlane config path
    config = YAML.load_file(File.join(File.dirname(__FILE__),"../Brand", options[:brand_name],"Configs/fastlane_config.yaml"))
    settings = OpenStruct.new(config)
    lane_settings = settings[options[:lane_name]]

    # Settings the App Identifier
    app_identifier = lane_settings["bundle_identifier"]

    pilot(skip_submission: true)
end

Thank you

like image 252
BastienPenalba Avatar asked Jun 14 '17 14:06

BastienPenalba


1 Answers

I've been working on a similar task and have found a solution that seems to work. Answering your question, we can open the .xcconfig file and read a value by key.

lane :development do |options|
    fastlane_require 'Xcodeproj'

    # Compose .xcconfig file path
    configuration_file = "../Brand" + options[:brand_name] + "Configs/config.xcconfig"

    # Read values from the .xcconfig file
    configuration = Xcodeproj::Config.new(configuration_file)
    app_identifier = configuration.attributes['PRODUCT_BUNDLE_IDENTIFIER']

    ... 
end

But I find it as a quite dirty solution, as there is still some duplication: we've specified a config file for target/configuration in the Xcode project, and now we manually specifying it again.

There are even more issues appear as soon as we begin to "inherit" (include) configuration files from each other. It can be useful in case you have lots of build configurations and most of them share same settings, but only some settings differ across configurations.

The right way to achieve what you most likely need is to get the flag value by merging all applicable sources: project, target, configuration, configuration files. This can be done by getting build settings from your configuration, not from the .xcconfig itself.

lane :development do |options|
    fastlane_require 'Xcodeproj'


    # Here we can define some hardcoded values,
    # or read them from lane options,
    # or read them from environment variables...
    project_name = '../XXX.xcodeproj'
    target_name = 'YYY'
    configuration_name = 'ZZZ'

    # Read values from the configuration,
    # specified in project settings for a specific target.
    project = Xcodeproj::Project.open(project_name)
    target = project.native_targets.find {|s| s.name == target_name }
    configuration = target.build_configurations.find {|s| s.name == configuration_name}
    app_identifier = configuration.resolve_build_setting('PRODUCT_BUNDLE_IDENTIFIER')

    ...

end
like image 74
fedulvtubudul Avatar answered Oct 12 '22 23:10

fedulvtubudul