Search code examples
objective-crubymotion

Rubymotion - Multiple targets with same code


some time ago, I had to create two version of a same app using XCode (let say a Lite and a Paid for the example). It was quite easy, add a second target with a preprocessor define and in the code use

#if defined(SOME_DEFINE)
  [some code];
#else
  [some otherCode];
#endif

I now have to do the same using Rubymotion. What should be the best way to do that ?


Solution

  • Laurent answered this here: https://twitter.com/lrz/status/464079142065930240, I thought I would expound on that a little bit.

    So the idea is to generate a .rb file that includes constants, and that file is compiled and those constants are available in your app. It's up to you how you determine the values, but I'll use the example of parsing ENV variables, e.g.

    rake some_define=true
    

    In your Rakefile:

    Motion::Project::App.setup do |app|
      if ENV['some_define'] == 'true' || ENV['some_define'] == '1'
        some_define = true
      else
        some_define = false
      end
    
      constants_contents = "SOME_DEFINE = #{some_define.inspect}\n"
      File.open('app/.constants.rb', 'w') do |file|
        file.write(constants_contents)
      end
    
      # add this config file to the beginning of app.files, so you can
      # use the constant anywhere
      app.files.insert(0, 'app/.constants.rb')
    end
    

    So now you will have SOME_DEFINE available in your app; not as elegant as #define macros, but the end result is pretty much the same.

    If [some code] and [some otherCode] is a massive amount, you should put it in separate files and then you can just conditionally include those files. In this case, don't put them in app/, have them in platform/ or something like that, and then:

    Motion::Project::App.setup do |app|
      if ENV['some_define'] == 'true' || ENV['some_define'] == '1'
        app.files.insert(0, 'platform/special.rb')
      else
        app.files.insert(0, 'platform/default.rb')
      end
    end