mike enriquez

Mac/iOS/Web Developer

Technical stuff

The End for gMessage and BigPhone

A few days ago, the Google Voice apps I developed stopped working. It turns out that Google changed something on their side that brought down gMessage and BigPhone. I don’t believe they were targetted specifically, but they simply made an update to how their authentication works. Since there is no official API for Google Voice, my “hack” for authentiation doesn’t work anymore.

I attempted to fix it this morning, but it turns out that it is not an easy fix. Even if I did find a fix, there’s no guarantee that Google won’t change anything again. Therefore, I’ve decided that it is not worth fixing and to take down both apps from the App Store.

It sucks, but I think it’s the right thing to do. gMessage and BigPhone were always fun side projects for me. I used both apps everyday for myself. Luckily there are alternatives in the App Store that still work.

It has been over two years since I released the first version of BigPhone. Thanks to those of you who supported me along the way, and sorry it had to end. It was really fun to see these apps get some press and see how useful they were for people. I learned a lot, and maybe I’ll be ambitious enough to roll a better Google Voice type of service in the future. Until then, follow @enriquez on Twitter to see what I’m working on these days.

Peace and pizza grease,

Mike


awakeFromNib not called

If you’re wondering why your awakeFromNib method is not getting called, check out #4 in the docs on The Object Loading Process. Basically, awakeFromNib is not called on placeholder objects such as File’s Owner and First Responder in iOS.


UIAlertView and UIActionSheet with Blocks and Target/Action Invocations

The delegate methods for UIAlertView and UIActionSheet in my app were getting out of control, so I had to refactor. I came up with subclasses that added a block and target-action API. Instead of having a long delegate method to handle all the button actions, you can now specify the action in a block or a separate method.

Check out MEAlertView and MEActionSheet


Namespaced controller and url generation gotcha in Rails

I ran into a gotcha while working on a Rails app that was written a few years ago, before the idea of REST came about.

What is the path generated from the following?

<%= link_to "Clicky", :controller => "posts" %>

Normally, you would expect /posts, but that’s not always the case. It depends upon the context of where this is being called. If you’re inside a namespaced controller such as Admin::CommentsController, then the generated url is /admin/posts.

It turns out that Rails assumes that if you’re within the context of a namespace that you want to stay in that namespace. You can read more about it in the documentation for url_for. It’s a bit of a WTF moment when you specify a controller and you end up with something else.

Here are 2 ways to get around this behavior.

Workaround #1: Add a leading slash

The leading slash forces the url generation to ignore the defaults.

<%= link_to "Clicky", :controller => "/posts" %>

Workaround #2: Override url_for

In the app I was working on, changing every generated url wasn’t doable given time constraints. I came up with a little hack to override url_for in the controller to always add the leading slash.

# app/controllers/admin/comments_controller.rb

protected
def url_for(options = {})
  if options.is_a?(Hash) && options.has_key?(:controller)
    options[:controller] = "/#{options[:controller]}"
  end
  super(options)
end

I haven’t investigated any side effects to this, so be warned and run your tests.


Don't forget about respond_to? when implementing method_missing

method_missing can be used to do some really cool things in Ruby, but it can also cause some headaches when done improperly. One cause for headache is when method_missing comes with a broken or missing respond_to? implementation.

Example Proxy class

Consider the following example of a proxy class that uses method_missing, but doesn’t implement respond_to?.

class Proxy
  def initialize(subject)
    @subject = subject
  end
  
  def method_missing(method)
    @subject.send(method)
  end
end

proxy = Proxy.new(Time)
proxy.respond_to?(:now) # => false
proxy.now # => Fri Feb 05 00:34:53 -0500 2010

Our proxy object is a dirty liar. When we ask if it responds to now it returns false, but when we actually call now it responds successfully.

Here’s a better implementation for Proxy:

class Proxy
  def initialize(subject)
    @subject = subject
  end

  def method_missing(method)
    if @subject.respond_to?(method)
      @subject.send(method)
    else
      super(method)
    end
  end

  def respond_to?(method, include_private = false)
    super || @subject.respond_to?(method, include_private)
  end
end

proxy = Proxy.new(Time)
proxy.respond_to?(:now) # => true
proxy.now # => Fri Feb 05 00:34:53 -0500 2010

That’s better. We added an implementation for respond_to? and some calls to super. Keep in mind that we’re overriding existing methods, and we want to add behavior to them unobtrusively. You can learn some techniques for DRYing and testing method_missing and respond_to? at Technical Pickles.

Let’s examine a bug with respond_to? in a Rails plugin you’re probably using…

will_paginate and respond_to?

Here is a Post model that contains a class method called paginate_by_something.

# will_paginate is installed
class Post < ActiveRecord::Base
  def self.paginate_by_something
    # "something" is not an attribute
  end
end

Post.respond_to?(:paginate_by_something) # => false

What!? We explicitly define a class level method, but when we interrogate it with respond_to? it returns false.

The problem is with will_paginate’s respond_to?. Below is a snippet of code from will_paginate that gets mixed into your models.

def respond_to?(method, include_priv = false) #:nodoc:
  case method.to_sym
  when :paginate, :paginate_by_sql
    true
  else
    super(method.to_s.sub(/^paginate/, 'find'), include_priv)
  end
end

The first thing will_paginate does is return true for its obvious methods: paginate and paginate_by_sql. Then the interesting part of this code is the call to super. It turns a method like paginate_by_author into find_by_author, which respond_to? would return true for, if it is an ActiveRecord dynamic finder. Going back to the paginate_by_something example in our Post model, we can see that respond_to? returns false because find_by_something is NOT a dynamic finder (when “something” is not an attribute).

The fix to will_paginate is fairly simple, and I’ve already submitted a patch. Props to Ryan Briones for pairing with me while debugging the problem on a project at Chase.

On a side note, if you have a particular RSpec test that fails when you run the whole test suite, but pass when ran individually; Check your mocks on methods that don’t implement respond_to? correctly. RSpec uses respond_to? internally when using mocks, and RSpec expects it to work!