My Web Log Book

iOS 7 and Skeumorphism

I’m glad to see Apple take skeuomorphism to the next level in iOS 7. It always felt like what the design community really hated was not skeuomorphism, but the emulation of existing materials like green felt or leather. Both these concepts would appear to be the identical at first sight, and they absolutely are, until we consider the idea that skeuomorphism extends beyond just visual emulation of materials. If the sound made by the Camera app in an iPhone is skeuomorphic because there is no mechanical shutter in an iPhone, then sound can also be skeuomorphic, and the definition of this term must include design elements beyond just visual looks.

One concept that spans both space and time and is omnipresent in iOS 7 is depth which seems to be heavily baked in to iOS 7. The depth and the parallax is not just on the home-screen but it’s pervasive throughout most elements in the OS.

Let’s visit the alternative definition of skeuomorphism on Wikipedia before we come back to the parallax. Wikipedia defines it as:

“an element of design or structure that serves little or no purpose in the artifact fashioned from the new material but was essential to the object made from the original material”

When we talk about a phone or a tablet, the new material is the digital screen, speakers, camera, etc. Parallax is an element of design or structure that serves little or no purpose on this screen. The original material here is perspective in a three dimensional space. By this reasoning, iOS 7 is heavily skeuomorphic, and Apple didn’t get rid of skeuomorphism in this version, but instead turned it up a notch.

Skeuomorphism is dead. Long live skeuomorphism.

Building Dart on Snow Leopard

I was stuck at the unsupported GCC error in building Dart on my Snow Leopard. The fix was simple - to remove the explicit version requirement, and let it use the system default. Hope it doesn’t break anything.

Unsupported compiler 'GCC 4.2' selected for architecture 'x86_64'

Basically we have to clear out all references to GCC 4.2 from


GCC_VERSION = 4.2;

to


GCC_VERSION = ""

Since this version has been references in a thousand places, a global search and replace was needed. I am inside the dart/ directory.

$ find . -name "*.pbxproj" -print -exec sed -i 's/GCC_VERSION = 4.2/GCC_VERSION = ""/g' {} \;

And ** BUILD SUCCEEDED **

Cool!

Responding with non-empty JSON when updating a resource via PUT in Rails 3

Rails 3 responds with an empty object when making PUT requests to update a resource. This could be undesirable for some cases, and certainly is in our case where expect the JSON representation of the modified object as the response.

The quick-fix is easy - we override the default behavior of respond_with using a block that returns forces the response to be the complete JSON object.

respond_with(@program) do |format|
  format.json {
    if @program.valid?
      render json: @program
    else
      render json: @program.errors, status: :unprocessable_entity
    end
  }
end

A neater fix, at least for me, would be in Rails itself inside the Responder class. GET and POST requests already work as expected. For other requests Rails returns an empty response. This is how things look right now

# This is the common behavior for formats associated with APIs, such as :xml and :json.
def api_behavior(error)
  raise error unless resourceful?

  if get?
    display resource
  elsif post?
    display resource, :status => :created, :location => api_location
  elsif has_empty_resource_definition?
    display empty_resource, :status => :ok
  else
    head :ok
  end
end

Instead of responding with an empty resource for non GET/POST requests, we could have returned the resource itself for PUT requests as well. Here’s how my ideal solution would look like (notice the elsif put? line):

# This is the common behavior for formats associated with APIs, such as :xml and :json.
def api_behavior(error)
  raise error unless resourceful?

  if get?
    display resource
  elsif post?
    display resource, :status => :created, :location => api_location
  elsif put?
    display resource, :status => :ok
  elsif has_empty_resource_definition?
    display empty_resource, :status => :ok
  else
    head :ok
  end
end

Now what can I do to get this merged in Rails?

Linker errors with iOS 5 and libz

So this has happened a few times across different projects where my iOS app failed to compile. The first one was particularly sad because when building a static framework that I include in my work app, because of libz. We were referencing libz.1.2.3 which is apparently not included in iOS 5 SDK. I think it only contains version 1.2.5 now. The worst part was that libtool was failing, and it gave absolutely no clue as to why. The error simply said,

libtool failed with error code 1

Bravo. After head-banging for a couple hours and trying random stuff, I removed libz and suddenly the project compiled.

In another project, XCode for more helpful and guided me to the error rightaway by uttering some useful errors,

ld: library not found for -lz.1.2.3

Lesson learnt. Now I’m just referencing libz.dylib in the project as it is a symbolic link to the actual library and hopefully will always be there when needed.

How do you dynamically set AJAX request data with Rails 3.1, jQuery, CoffeeScript, and all that jazz?

Rails 3.1 is awesome. CoffeeScript is great. The jQuery addition is brilliant. But recently I came across a simple problem that took quite a while to figure out and with all these additions being fairly new, there was not much online help available, so I had to turn to the source code.

So what was the problem? How do we dynamically modify the AJAX request data with rails using a link_to. If I was using pure jQuery the solution would be as simple as,

$.ajax('/some/path', {
    type: 'POST',
    data: { foo: 'bar' },
    success: function() { .. },
    error: function() { .. }
});

But since I was trying to keep it Railsy and use link_to to create a POST request, there were a few hurdles. Initially, I was trying to use the ajax:beforeSend event callback which was useless for this task, as all form data gets set before this callback is made by Rails. The only use of this callback would be to abort the ajax request altogether if you suddenly discovered something. So I had to use the ajax:before event. But inside the ajax:before callback, we are only passed an event object totally unrelated to ajax, so to set custom ajax data, I had to checkout how any data gets passed to jQuery.ajax by Rails in the first place. Here’s the relevant snippet from Rails UJS. Stripped out the form handling part as we’re dealing with a link here.

if (rails.fire(element, 'ajax:before')) {
    if (element.is('form')) {
        ...
    } else {
        method = element.data('method');
        url = element.attr('href');
        data = element.data('params') || null;
    }
    ...
}

So Rails looks for custom data inside the params data object of the element triggering the ajax request which is where I had to implant it. The CoffeeScript code for intercepting the ajax request and injecting the data dynamically looked like,

$ ->
    $('#my_link').bind('ajax:before', ->
        $(this).data('params', { foo: 'bar' })
    )

Or if you don’t like CoffeeScript for some reason, here’s the equivalent in JavaScript.

$(function() {
    $('#my_link').bind('ajax:before', function() {
        $(this).data('params', { foo: 'bar' });
    });
});

The corresponding link in rails erb was,

<%= link_to 'Foo', foo_path, method: :post, remote: true, id: 'my_link' %>

This new syntax of creating hashes in Ruby 1.9 is cool and almost similar to JavaScript’s object literals.

Ruby version of Facebook’s get_facebook_cookie in PHP

Facebook provides an example of Single Sign-on that includes a method of verifying the authenticity of facebook’s cookie that is set by their JavaScript SDK. The method is defined as:

<?php
  define('FACEBOOK_APP_ID', 'your application id');
  define('FACEBOOK_SECRET', 'your application secret');
  
  function get_facebook_cookie($app_id, $application_secret)
  {
      $args = array();
      parse_str(trim($_COOKIE['fbs_' . $app_id], '\\"'), $args);
      ksort($args);
      $payload = '';
      foreach ($args as $key => $value) {
          if ($key != 'sig') {
              $payload .= $key . '=' . $value;
          }
      }
      if (md5($payload . $application_secret) != $args['sig']) {
          return null;
      }
      return $args;
  }
  
  $cookie = get_facebook_cookie(FACEBOOK_APP_ID, FACEBOOK_SECRET);
?>

Here’s one for Ruby.

require 'cgi'
require 'digest/md5'

def get_facebook_params(app_id, app_secret, cookie)
  # unquote cookie value
  cookie.gsub!(/^"|"$/, '')
  
  # construct key, value pairs
  params = CGI.parse(cookie)
  
  # params contains keys and values of the form
  # {"session_key" => ["..abcdef.."], "uid" => ["123456789"]}
  # we need to unwrap each value out of the array into something like this
  # {"session_key" => "..abcdef..", "uid" => "123456789"}
  params = Hash[*params.sort.flatten]

  # take sig out
  sig = params.delete("sig")
  
  payload = ''
  params.sort.each do |pair|
    key, value = pair
    payload = payload + "#{key}=#{value}"
  end
  
  return nil if sig != Digest::MD5.hexdigest(payload + app_secret)
  
  return params
end

Enumerating Arrays and Objects in JavaScript

JavaScript arrays are an ordered collection of values, and objects are an unordered collection of key, value pairs. The members of both types can be enumerated and a variety of looping mechanisms can be used for doing that, however, these mechanisms are not interchangeable.

When we are dealing with objects, the order of enumeration is not guaranteed. With arrays it is. That’s all there is to know about enumerating collections. Four of the ways to do so are listed below.

  • for in
  • for each in
  • for
  • forEach

for in and for each in are perfect for enumerating properties, and values of an object respectively when order does not matter. To give an example, consider this object:

var phone = {
    screen: "320x480",
    wifi: true,
    price: 99
};

for in can be used to enumerate all the properties and once we know the property name, the corresponding value can be accessed as phone[property].

for(var prop in phone) {
    console.log(prop); // "screen", "wifi", and "price"
}

The corresponding values can be accessed by using the bracket notation and passing the property name to the object.

for(var prop in phone) {
    console.log(phone[prop]); // "320x480", true, 99
}

With the addition of for each in to JavaScript, which is only supported by Firefox at the moment, the above loop can be rewritten as:

for each(var value in phone) {
    console.log(value); // "320x480", true, 99
}

The for each in statement works beautifully when used with E4X, but that is for a later post. You wouldn’t use either of the above statements for arrays because firstly order is not guaranteed, and secondly these are used to list all enumerable properties of an object which may not be desirable for Arrays as several frameworks add properties to the Array prototype which will also get enumerated. Consider this example:

var arr = ["a", "b"];

Array.prototype.justHangingOut = true;

for(var prop in arr) {
    console.log(prop); // "0", "1", "justHangingOut"
}

Now justHangingOut may just be hanging out with the Array prototype coming from some framework or library, and not necessarily be a part of your code, but it will show up when you try to enumerate an array in the above manner. Just to prove that I am not hallunicating about frameworks extending the Array prototype, here is the list of all methods added to Array.prototype when I run a small piece of code in Chrome’s console for tumblr.com. The following few properties are listed:

0
1
justHangingOut
each
eachSlice
all
every
any
some
collect
map
detect
findAll
select
filter
grep
include
member
inGroupsOf
inject
invoke
max
min
partition
pluck
reject
sortBy
toArray
entries
zip
size
inspect
find
_reverse
_each
clear
first
last
compact
flatten
without
reverse
uniq
intersect
clone
toJSON

Hopefully the above example is sufficient to convince you that it’s a bad idea to try to enumerate an array using a for in or for each in statement. There is a way using the hasOwnProperty method that is available for all objects to find out if a given property belongs to that object or is coming from its prototype chain, but let’s not get into that for now.

So, moving on to enumerating arrays, a native and a somewhat faster way is to use a plain ol’ for loop. Here’s an example:

var foo = [2, 3, 5, 7, 11];

for(var i = 0; i < foo.length; i++) {
    console.log(foo[i]); // 2, 3, 5, 7, 11
}

This may be a little more performant than function-based looping, but I really dislike the use of so many indexes. All that is needed is going over each value and logging it, and all those i’s are just noise. So, I prefer the forEach method of an array that’s part of ECMAScript 5th ed. It helps keep the noise levels low.

var foo = [2, 3, 5, 7, 11];

foo.forEach(function(v) {
    console.log(v); // 2, 3, 5, 7, 11
});

If your browser does not have native support for forEach, it’s easy to plug it in yourself. The following code from MDC defines the forEach method for enumerating array values if it’s not already present.

if (!Array.prototype.forEach)
{
    Array.prototype.forEach = function(fun /*, thisp*/)
    {
        var len = this.length >>> 0;
        if (typeof fun != "function")
            throw new TypeError();

        var thisp = arguments[1];
        for (var i = 0; i < len; i++)
        {
            if (i in this)
                fun.call(thisp, this[i], i, this);
        }
    };
}

On an unrelated note, although the above example of extending a native object (Array) with user defined functions may be seen as polluting the native object and even outrageous by some, I see nothing wrong with it. In fact, I am all in favor of it when such methods are put in the right place. The forEach method that’s now part of ECMAScript 5 was adapted from the Prototype framework, and it’s very much possible that if Prototype hadn’t “polluted the native Array object”, then the spec would have been a little different today.

I think if we extend the native types judiciously, it makes code a lot more readable and fun. A great example that comes to mind is the extension to Numeric types in Rails with some neat methods that allow code like:

5.days + 2.days

No, I’m not making this up. That is valid code in Rails thanks to ActiveSupport extensions. Of course, we can always write methods that do exactly the same, but then we face the problem of either making too many things global:

days(2) + days(5)

or namespacing them and making code uglier than it should’ve been.

Time.Range.days(2) + Time.Range.days(5)

Note that the first form 3.days uses a loose form of namespacing as it’s only added for Numeric types and not available globally as in the second example days(3). The third example Time.Range.days(3), on the other hand, uses a seemingly well-defined namespace. I would prefer using the first form because it reads like prose, and at the same time doesn’t throw everything into the global namespace.

That said, its largely a matter of developer preference, and factors like type of project, scale of project, number of developers, etc. should also weigh in when deciding whether extension of native-types aka monkey-patching is acceptable for the project. It can be a huge asset of liability in building up your codebase depending on how it’s done.

Think I’ve segway’d enough for one post. Time to sleep.

authlogic_facebook_connect with a custom callback URL

If you’re using authlogic_facebook_connect to have facebook integration in your site and don’t want to use the standard callback url of http:///user_session, then pass a controller option to the authlogic_facebook_login_button function and pass the controller name. Actually you don’t need a controller name, just the path from the root url would do.

Here’s the code I am using, that’s facebook redirects to /authenticate using HTTP Post.

<%= authlogic_facebook_login_button :length => "long", :controller => 'authenticate' %>

evil is as eval does

—Anurag Mishra