CakePHPでSwiftからのPOST,GETリクエストを受け取る

iOSアプリを作るにあたりAPIが必要になったので普段使っているCakePHPで実装してみました。
ググってもCakePHPで実装している例が少なかったのでやろうと思っている方の参考になれば幸いです。
前提として、CakePHPがローカルで動いている（apache,データベースの設定ができている）ことを必要とします。

まずはPOSTから、CakePHPで受け取ったものをそのままjsonでswiftに返すプログラムを実装します。
ここでは、CakePHPのホスト名をlocalhostとします。

まずはPOSTから。
##POST

SwiftでのPOSTのコードから。

```lang:ViewController.swift
func post(){
     //create url request
        //set URL
        let urlstr = "http://localhost/post/posttest"
        var request = NSMutableURLRequest(URL: NSURL(string: urlstr)!)

        //set method
        request.HTTPMethod = "POST"
        
        //set the params
        var params: [String: AnyObject] = [
            "Post": [
                "a": 1,
                "b": 20,
                "c": "hoge"
            ]
        ]

        request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: nil)
        
        //use NSURLSessionDataTask
        var task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler:{ data, response, error in

            //if succeed post
            if(error == nil){
                var result = NSString(data:data, encoding: NSUTF8StringEncoding)!
　　　　　　　　　　//結果を出力
                println(result)
            }else{
                println(error)
                
            }
            
        } )
        task.resume()
}
```


次にCakePHP側でモデルPost.phpとコントローラーPostController.phpを作成します。
localhost/コントローラー名/アクション（function）名
でそのコントローラのアクションにPOST/GETできます。

Post.phpはDBとの連携のために必要なだけなので最低限の記述で大丈夫です。

```lang:Post.php
<?php
class Post extends AppModel{
}
```

```lang:PostController.php

<?php
class PostController extends AppController{

   public function posttest(){

     if(!empty($this->request->data)){

      //キーがPOST内容になっているので
      foreach($this->request->data as $key => $value){
        $Data = $key;
      }
      //PHPで使える配列に。
      $Data = json_decode($Data,true);
      
      //再度json形式にして返す
      $this->set('data',$Data);
      $this->viewClass = 'Json';
      $this->set('_serialize',array('data'));
  
     }

   }
}
```
POSTは$this->request->dataで取得できますが、配列のキーにPOST内容が入っていたのでキーを取り出す処理を入れて、その内容をjson_decodeすればなんとか連想配列に出来ました。
以上を実行してSwiftのconsoleに以下が出ればOKです。

```
{
    "data": {
        "Post": {
            "b": 20,
            "a": 1,
            "c": "hoge"
        }
    }
}
```

次はGETです。
##GET
Swiftから。

```lang:ViewController.swift
func get(){
        //set url and request
        let url = "http://localhost/post/gettest"
        var request = NSMutableURLRequest(URL: NSURL(string:url)!)
        request.HTTPMethod = "GET"

            var task = NSURLSession.sharedSession().dataTaskWithRequest(request, completionHandler:{data, response, error in

                if(error == nil){
                    var result = NSString(data:data,encoding:NSUTF8StringEncoding)!
                //結果を出力    
                println(result)
                    
                }else{
                    println(error)
                }
            })
        task.resume()
}
```
パラメーターはlocalhost/post/gettest?id=1のように渡せて、CakePHPでは$this->params["url"]["id"];で受け取れます。

CakePHP側です。上記のPOST処理での最終的に配列を吐く処理のみです。
先ほどのPostController.phpに新しく関数を追加します。

```lang:PostController.php
public function gettest(){
      //GETさせる配列を設定
      $data = array(
             'a'=>1,
             'b'=>array(
                      array('id'=>1,'name'=>'c'),
                      array('id'=>2,'name'=>'d'),
                       )
              );
      //json形式でviewに吐く
      $this->set(compact('data'));
      $this->viewClass = 'Json';
      $this->set('_serialize', array('data'));
}
```
Swiftのconsoleで以下が出れば成功です。

```
{
    "data": {
        "a": 1,
        "b": [
            {
                "id": 1,
                "name": "c"
            },
            {
                "id": "2",
                "name": "d"
            },
        ]
    }
}

```


##おわりに
CakePHPはデータベースとの連携が楽ちんなのでCakePHPでAPIを作っても便利だと思います。
ミスや改善点があれば教えていただければ幸いです。