Friday, December 20, 2013

Rubymotion: Controlling Info.plist generation with environment variables

I've been doing a fair amount of Rubymotion development these days and one trick that I'm using in my local development is to control the generation of the Info.plist via environment variables and some Ruby coding in the Rakefile. I can't stop raving about the excellent tools and development cadence that Rubymotion affords the iOS developer. I really like that I'm working out of Rubymine and not Xcode and using standard Ruby tools like rake and Bundler.

Like I said, using rake, you have the opportunity to change your Info.plist because it's generated through the rake process. I have a login view that needs a username and password entered into the text fields. I've rigged it up that these are prepopulated when working in dev, using environment variables and adding some logic to my Rakefile and the view controller. First up are the environment variables:

export DEV_MODE="true"
export DEV_USERNAME=""
export DEV_PASSWORD="fahj2734hfjg86776dg$48df676"

Nothing earth shattering here. Normal environment variable assignments. Next up is the Rakefile changes:

Motion::Project::App.setup do |app|

    if ENV['DEV_MODE']
        puts '==========================================='
        puts '===> Using DEV_MODE Info.plist values <===='
        puts '==========================================='

        app.info_plist['DEV_USERNAME'] = ENV['DEV_USERNAME']
        app.info_plist['DEV_PASSWORD'] = ENV['DEV_PASSWORD']

    app.pods do

Again, pretty simple Ruby stuff here. If the DEV_HOME environment variable is set, add the username and password to the Info.plist during generation. Now, in your app, you can reference these values in your viewDidLoad method of your view controller, prepopulating the UI elements in your views:

dev_username = NSBundle.mainBundle.objectForInfoDictionaryKey('DEV_USERNAME')
dev_password = NSBundle.mainBundle.objectForInfoDictionaryKey('DEV_PASSWORD')
@email_field.text = dev_username || ''
@password_field.text = dev_password || ''

I probably sound like a broken record, but if you haven't used Rubymotion, definitely give it a try. Much different developer experience using Rubymotion tools vs. Apple's Xcode tooling.

Retrieving logs from your deployed Google App Engine Java application

If you need to see your application logs from your deployed Google App Engine (GAE) Java application, you can use the GAE tool to do so. Issue the following command from your GAE app directory: --num_days=0 --severity=0 request_logs ./web ./logs/gae.log


--num_days=0 will retrieve all of the logs available,
--severity=0 will retrieve DEBUG and above log levels,
./web is where the ./WEB-INF/appengine-web.xml descriptor file can be found, and
./logs/gae.log is the local log file to write records to.

There are other options available for this command. Execute help request_logs to see more information on the options available for request logs command. This will dump all of your logs and they will not be truncated like they are in the Logs view of the GAE administration application.

Thursday, December 19, 2013

CoffeeScript Application Development by Ian Young

I had the opportunity to read CoffeeScript Application Development by Ian Young recently and thought I would put together a book review.

The author does a nice job describing why parentheses are required for executing CoffeeScript no-argument functions. This is an idiom that I have seen many developers trip over when first coming to CoffeeScript. CoffeeScript preserves JavaScript’s view of functions as first-class citizens. Parentheses are optional except when necessary to avoid ambiguity.

The author gives some nice examples of loop comprehensions, one of the snazzier features of CoffeeScript. Loop comprehensions come from Python and they make for a more readable way to iterate a list and selectively act on list elements which meet a certain criteria. I’m always looking for more examples of loop comprehensions in CoffeeScript and this book has some nice examples.

The CoffeeScript switch statement is explained thoroughly. This is a handy flow-control statement that works really well in its incarnation in CoffeeScript. There are numerous examples in the book where different usage scenarios are demonstrated. Very handy and welcomed.

I found the author’s treatment of classes and inheritance in CoffeeScript to be a nice, gentle introduction. The examples that are given in the book work well and the explanations that accompany the examples are clear and concise. It would have been nice to get an explanation of the boilerplate code that CoffeeScript generates for you when defining a class, but I guess that’s considered part of the magic of CoffeeScript. It isn’t until the discussion on inheritance that the author starts to poke his head under the hood to investigate the generated JavaScript. The inheritance discussion is extremely valuable and a big plus for this book. If you get this book for anything, it’s for this discussion. CoffeeScript is doing a whole bunch of interesting stuff when creating classes and implementing inheritance, and this is one of the first times that I have seen the generated JavaScript described line by line.

In typical fashion, the author introduces the fat arrow syntax in a gentle manner, clearly explaining the reasoning for such a feature. The author then gives a very good explanation why you should not overuse the fat arrow syntax in your CoffeeScript (hint, it’s due to memory usage). He also includes a very succinct definition and example around memoization in CoffeeScript. This is a feature that I have not had much exposure to, so it was great to see it described and used in an example.

IcedCoffeeScript is introduced in the chapter on Going Asynchronous. I have not used IcedCoffeeScript, so that was an interesting exploration into an extension to CoffeeScript for managing asynchronous invocations. Looks interesting.

The topic of debugging CoffeeScript is broached. This is an interesting subject, as I have seen a few developers really get frustrated with the mapping of generated JavaScript back to the original CoffeeScript. Luckily the author introduces source maps, which does this work for us. The author shows us how to set this feature up in Firefox and Chrome developer tools. Your mileage will vary on this feature, but it is an interesting tool for easing the inertia of moving to CoffeeScript. This discussion comes with a lot of screenshots that help you understand how the source maps feature can be used in the developer tools.

Overall I really liked this book and it’s a worthy addition to my other documentation on CoffeeScript. Link to the book