A rails plugin to use the .plist format to return binary plists
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
MIT-LICENSE
README
init.rb

README

Plistifier
==========

This plugin is for Rails 2 and will not work in Rails 3. If you need this functionality for
Rails 3 check out https://github.com/MSchmidt/CFPropertyList-rails instead.

Adds the possibility to talk to a rails app via (Binary) Property Lists
http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man5/plist.5.html

It is designed to work like the JSON format. On the iPhone it is easier to
use, much faster; because Plists are smaller; and it doesn't need any third
party libraries for parsing like JSON, or difficult SAX-style parsing like
XML.

It adds the ActiveRecord#to_plist, Array#to_plist and Hash#to_plist methods
similar to ActiveRecord#to_json. The :only, :except, :methods, and :include
options are supported on ActiveRecord and Array with ActiveRecord items.


Install
=======

sudo gem install --remote CFPropertyList
script/plugin install git://github.com/jeena/plistifier.git

If you should get the error "Unknown class NilClass! Try using :convert_unknown_to_string
if you want to use unknown object types!" you need to upgrade to rake-0.8.7.


Example
=======

Getting data from rails
-----------------------

In your PostController use for example:

	def index
	  @posts = Post.all

	  respond_to do |format|
	    format.html # index.html.erb
	    format.xml  { render :xml => @posts }
	    format.plist { render :plist => @posts, :only => [:id, :title] }
	  end
	end

	def show
	  @post = Post.find(params[:id])

	  respond_to do |format|
	    format.html # show.html.erb
	    format.xml  { render :xml => @post }
			format.plist { render :plist => @post }
	  end
	end
	
	def show
	  @post = Post.find(params[:id])

	  respond_to do |format|
			format.plist { render :plist => @post, :plist_filename => "a-testfile.plist" }
	  end
	end
	
On the iPhone use for example:

	NSURL *url = [NSURL URLWithString:@"http://example.com/posts.plist"];
	NSArray *posts = [[NSArray alloc] initWithContentsOfURL:url];
	NSLog(@"Title: %@", [[posts objectAtIndex:0] objectForKey:@"title"]);
	
	
Sending data to rails
---------------------

It is possible to send a plist back into rails. On the iPhone you have to do for example:

	NSDictionary *aPost = [[NSDictionary alloc] initWithObjectsAndKeys:
					@"A title", @"title",
					@"Some text for body", @"body", nil];
	NSDictionary *aDict = [[NSDictionary alloc] initWithObjectsAndKeys:aPost, @"post", nil];
	NSData *data = [NSPropertyListSerialization dataFromPropertyList:aDict
				format:NSPropertyListBinaryFormat_v1_0
				errorDescription:nil];

	NSURL *url = [NSURL URLWithString:@"http://example.com/posts.plist"];
	NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
	[request setHTTPMethod:@"POST"];
	[request setValue:@"application/plist" forHTTPHeaderField:@"Content-Type"];
	[request setHTTPBody:data];

	NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
	[connection release];
	[request release];
	[data release];
	[aDict release];
	[aPost release];

And on the rails side:

	def create
	  @post = Post.new(params[:post])

	  respond_to do |format|
	    if @post.save
	      flash[:notice] = 'Post was successfully created.'
	      format.html { redirect_to(@post) }
	      format.xml  { render :xml => @post, :status => :created, :location => @post }
	      format.plist  { render :plist => @post, :status => :created, :location => @post }
	    else
	      format.html { render :action => "new" }
	      format.xml  { render :xml => @post.errors, :status => :unprocessable_entity }
				format.plist { render :plist => @post.errors, :status => :unprocessable_entity }
	    end
	  end
	end

So you see the params variable is the property list you just send from your iPhone.


Known problems
==============

There is one problem though, If you want to do something like this it will crash:

	@post = Post.all
	myplist = { :foo => "bar", :post => @post }.to_plist

You have to convert the ActionRecord @post to a hash which CFPropertyList
understands and can convert for example like:

	myplist = { :foo => "bar", :post => @post.to_hash }.to_plist

ActionRecord#to_hash is a method the plugin adds.	


Thanks
======

This plugin uses Christian Kruses CFPropertyList http://github.com/ckruse/CFPropertyList
to generate Plists.

This plugin started as a copy of http://github.com/chuyeow/jsonifier/ I just changed it to
support and added the CFPropertyList stuff.

Thanks Alexandre Bournier from http://pixyapps.com for his great ideas on how to improve
the functionality and the help with testing.


Copyright (c) 2010 Jeena Paradies, released under the MIT license