150 lines
4.5 KiB
Text
150 lines
4.5 KiB
Text
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
|