iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
Ruby on Railsは初めてなので、ログ取りにうってつけな状況だ。Railsアプリケーションを配置するディレクトリを用意する。ディレクトリの場所には制約はないようなので、Documentsディレクトリ配下にrailsというディレクトリを作成して、そこにworkbookというアプリケーション環境を生成する。
$ rails new workbook
create
create README.rdoc
....
Enter your password to install the bundled RubyGems to your system: ←パスワード入力
....
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
workbookアプリケーションのディレクトリ配下に移動して、雛形scaffoldを使って、コードを生成する。
$cd workbook/
$ rails generate scaffold person name:string age:integer
....
Could not find coffee-script-source-1.3.1 in any of the sources
Run `bundle install` to install missing gems.
自分の場合はエラーとなったので、素直にコメントの操作を実行して、成功するまで、コード生成を繰り返した。
$ bundle install
$ rails generate scaffold person name:string age:integer
Could not find sass-rails-3.2.5 in any of the sources
Run `bundle install` to install missing gems.
....
$ bundle install
$ rails generate scaffold person name:string age:integer
....
invoke scss
create app/assets/stylesheets/scaffolds.css.scss
$ rake db:migrate
== CreatePeople: migrating ===================================================
-- create_table(:people)
-> 0.0009s
== CreatePeople: migrated (0.0010s) ==========================================
初心者の自分では、理由は分からないが、『iOSプログラミング逆引きリファレンス108』で説明されているとおり、設定を変更する。
$ cd app/controllers
$ vi application_controller.rb
....
$ cat application_controller.rb
class ApplicationController < ActionController::Base
#protect_from_forgery
end
protect_from_forgeryをコメント・アウトする。
ところが、著者の場合、これでは上手くいかなかった。今の環境では、この手順だとHTMLとJSONのみの対応で、RESTはXMLということになると思うが、これに対応していない。また、驚いたのはpersonというモデルを作成したが、コントローラ名はこれの複数形のpeopleとなっていた。
RESTに対応される為、people_controller.rbで、JSONの記述をコピーして、JSONの部分をXMLに変更する。
具体的にいうと、例えば、
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @people }
end
となっている部分に、RESTに対応させるため、XMLのコードを追加する。
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @people } ←追加する。
format.json { render :json => @people }
end
Ruby on Railsやscaffoldが素晴らしいのだと思うが、JSONの記述を真似るだけで対応できた。全てを確認した訳ではないが。
これで、準備OK。サーバ側のアプリケーションを起動する。
$ rails server
=> Booting WEBrick
=> Rails 3.2.3 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2012-04-29 07:53:27] INFO WEBrick 1.3.1
[2012-04-29 07:53:27] INFO ruby 1.8.7 (2010-01-10) [universal-darwin11.0]
[2012-04-29 07:53:27] INFO WEBrick::HTTPServer#start: pid=1652 port=3000
余談だが、今回の試験で、サーバ側のDBを更新するが、初期状態に戻したくなると思うが、著者は以下の手順で対応した。
$ cd ~/Documents/rails/workbook/db
$ sqlite3 ./development.sqlite3
sqlite> delete from people; ←全データを削除
sqlite> select * from people; ←削除された事を確認。
sqlite> update sqlite_sequence set seq=0 where name='people'; ←カウンタをリセット。
sqlite> vacuum;
sqlite> .exit
iPhoneアプリケーション側のコードは、『iOSプログラミング逆引きリファレンス108』そのままなので、詳しくは説明しない。
- (IBAction)sendPost:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://localhost:3000/people.xml"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
NSString *content = @"Yukio MURAKAMI 17 ";
[request setHTTPBody:[content dataUsingEncoding:NSUTF8StringEncoding]];
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (!error) {
NSString *s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSString *t = [[NSString alloc] initWithFormat:@"status code: %d\ndata: %@", [response statusCode], s];
self.textView.text = t;
NSLog(@"%@", self.textView.text);
}
else {
NSString *s = [[NSString alloc] initWithFormat:@"error: %@", error];
self.textView.text = s;
NSLog(@"%@", self.textView.text);
}
}
RESTで気になるといえば、上記の場合、値を渡す際に、XML文字列をコードを埋め込む事だ。せっかくならCocoaの辞書型が使えたらと思うが、その場合は、JSONということになるようだ。JSONは、次回に取り上げる予定だ。