トップ «前の日記(2012-04-28) 最新 次の日記(2012-04-30)» 編集

Cocoa練習帳

iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど

2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|

2012-04-29 [iOS][Web]iPhoneアプリケーションとサーバ間の通信(その2)

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 MURAKAMI17";
    [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は、次回に取り上げる予定だ。

_ ソースコード

GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/REST - GitHub

_ 関連情報

Ruby on Rails
プロジェクトページ。
CHAPTER 5 Representational State Transfer (REST)
Fieldingの論文。
iOSプログラミング逆引きリファレンス108 ~知りたいことがすぐわかるiPhoneプログラミングテクニック~
全面的に、この書籍を参考にしています。助かります!
URL Loading System Programming Guide
Developerサイトの情報。

トップ «前の日記(2012-04-28) 最新 次の日記(2012-04-30)» 編集