Authlogic and the iPhone

So, I’ve based a couple of apps on a combination of authlogic and the iPhone Objective Resource package, and when I mentioned this on the relevant lists I got a bunch of people asking me questions, so I thought I’d post about what I did generally.

There are a couple of steps, most of which are geared towards having authlogic not produce redirects and instead produce http status codes that are interpretable to the applications. Here’s an example of what I mean from my ApplicationController on an app

  def require_user
    unless current_user
      store_location
      flash[:notice] = "You must be logged in to access this page"
      respond_to do |format|
        format.html { redirect_to new_user_session_url }
        format.xml  { render :text => "you must be logged in to access this page.", :status => :unauthorized }
      end
 
      return false
    end
  end

In the default implementation of this filter, it always returns a redirect. ObjectiveResource can follow the redirect (if you have a recent enough version), but it doesn’t really do it a lot of good. This way, you get a status code that you can use.

Since Authlogic focuses on RESTful creation of things, a lot of operations map naturally. To create an account on the Rails app, create a User object, and to test whether the user can log in, create a user session. My application stores credentials between iPhone App invocations, so it creates a UserSession at startup if you have stored credentials.

- (void)applicationDidFinishLaunching:(UIApplication *)application {
//
// ... blah blah blah all sorts of stuff removed.
//
 
	UserPrefsManager* prefs = [UserPrefsManager sharedInstance];
 
	if ([prefs isLoggedIn]) {
		UserSession * us = [[[UserSession alloc] init] autorelease];
 
		us.login = [prefs username];
		us.password = [prefs password];
 
		NSError * err = nil;
 
		if(![us createRemoteWithResponse:&err])
		{
//
//  ... my actual detection stuff removed and just the default left ...
//
			[AlertHelper showAlertWithError:err];
			[prefs clearLogin];
		}
	}
	[ObjectiveResourceConfig setUser:[prefs username]];
	[ObjectiveResourceConfig setPassword:[prefs password]];
//
// ... and proceed on with your app's normal course of things ...
//	
    [window addSubview:tabBarController.view];
}

You see here that i’m creating an UserSession here and testing to see if it works and setting the ObjectiveResourceConfig properties if it does. I have some logic where if there isn’t saved credentials you will get a dialog asking you to login or create an account (or whatever) later on, which is the point of [prefs clearLogin];. This is matched by a change to the create method of the UserSessionController:

      respond_to do | format |
        format.html do
          flash[:notice] = "Login successful!"
          redirect_back_or_default account_url
        end
        format.xml do
          render :xml => @user_session, :status => :created
        end
      end

(For brevity, I’ve just shown the successful branch)

This should be enough to get people going — all the other changes you have to make can be figured out from these two statements, and when I have some spare time I’m going to create a version of the demo application that works with ObjectiveResource. The only other suggestion I have is to use the withResponse: versions of everything and code defensively, and note that in some versions of ObjectiveResource getting an error from your application will cause the application to throw. In the meantime, feel free to ask me any questions

Tags: , , , , , ,