NSURLSessionを使ってバイナリの画像ファイルをPSOTする


Alamofireなどのサードパーティ製ライブラリを使用せずにPOSTリクエストを送信してみます。

###1.POSTする画像を生成

```swift
let sampleImage = UIImage(named: "sample")

let imageData:NSData = NSData(data:UIImageJPEGRepresentation(sampleImage, 1.0))
        
```
UIImageのインスタンスをNSDataに変換しています。
UIImageJPEGRepresentationをUIImagePNGRepresentationに変更することでPNG形式で変換することも可能です。

###2.NSURLRequestを生成

```swift
let url = NSURL(string: "URL_STRING")
var urlRequest : NSMutableURLRequest = NSMutableURLRequest()

if let u = url{
            urlRequest.URL = u
            urlRequest.HTTPMethod = "POST"
            urlRequest.timeoutInterval = 30.0
        }
        
```

URL_STRINGにはPOST先のURLを記載して下さい。

###3.BODYを作成

```swift
let uniqueId = NSProcessInfo.processInfo().globallyUniqueString
var body: NSMutableData = NSMutableData()
var postData :String = String()
var boundary:String = "---------------------------\(uniqueId)"

urlRequest.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") //(1)
        
postData += "--\(boundary)\r\n"

postData += "Content-Disposition: form-data; name=\"image\"; filename=\"sample.jpg\"\r\n" //(2)
postData += "Content-Type: image/jpeg\r\n\r\n"
        body.appendData(postData.dataUsingEncoding(NSUTF8StringEncoding)!)
body.appendData(imageData)
        
postData = String()
postData += "\r\n"
postData += "\r\n--\(boundary)--\r\n"

body.appendData(postData.dataUsingEncoding(NSUTF8StringEncoding)!) //(3)
        
urlRequest.HTTPBody = NSData(data:body)

```

(1)
まず、HTTPヘッダーの情報を登録しています。
Content-Typeヘッダにmultipart/form-dataを指定する、という意味の記述です。
ファイルアップロードの際はこのようにマルチパートのデータとして送信しなければなりません。

このマルチパートのデータはboundaryという境界となる行でデータが区切られます。
boundary=の部分で、どのような文字列をboundary（境界文字列）とするか、を指定しています。この文字列は自由に決められますが、境界文字列が本体部分に含まれるようなものではいけません。

境界の指定は、境界文字列の最初に--を連結して--(境界文字列）とします。

(2)
Content-Dispositionヘッダのname=の部分でサーバー側でパラメータ処理をする際の名前を指定できます。今回の例において、PHPで受け取るとすると$_POST['image']で受け取れる値です。
filename=の部分には転送するファイルの名前を指定します。
そして、次の行でContent-Typeを指定し、これらの文字列をNSData型に変換してbodyにappendしています。
次にNSData型に変換した画像のデータもappendします。

(3)
終了部分を示す境界には、境界文字列の最後にも--を連結することになっています。

###4.リクエストを送信してレスポンスを受け取る

```swift
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
        
let task: NSURLSessionDataTask = session.dataTaskWithRequest(urlRequest, completionHandler: { data, request, error in
            println(NSString(data: data, encoding: NSUTF8StringEncoding)!)
            println(request)
        })
task.resume()

```

まず、 NSURLSessionConfigurationを作成しています。
通常はdefaultSessionConfigurationで構いませんが、アプリケーションがバックグラウンドにいる時、アプリケーションが終了しているときでも通信を継続させたい場合はbackgroundSessionConfigurationWithIdentifier:を用います。
（但しNSURLSessionDownloadTask、NSURLSessionUploadTaskの時のみであり、今回はバックグラウンド転送はできない）

次に、NSURLSessionを作成しています。
先ほど作成したNSURLSessionConfigurationのインスンタンスを渡して初期化します。今回は関係ありませんが、バックグラウンド処理をさせたいときはデリゲートメソッドの実装先を指定しないといけません。

最後に、NSURLSessionDataTaskを作成して、resume()でタスクを実行しています。
NSURLSessionDataTaskはデータの送受信処理を行うもので、他にもファイルをダウンロード、アップロードするためのNSURLSessionDownloadTask、NSURLSessionUploadTaskが存在しています。

そして、処理が完了したら引数として渡したクロージャが呼び出されます。
返ってきたデータはNSData型ですので、任意の形式に変換する必要があります。
JSONに変換したいときは、NSJSONSerializationを用いるか、サードパーティ製ライブラリのSwiftyJSONなどを使うと良いです。