Alamofireなどのサードパーティ製ライブラリを使用せずにPOSTリクエストを送信してみます。
1.POSTする画像を生成
let sampleImage = UIImage(named: "sample")
let imageData:NSData = NSData(data:UIImageJPEGRepresentation(sampleImage, 1.0))
UIImageのインスタンスをNSDataに変換しています。
UIImageJPEGRepresentationをUIImagePNGRepresentationに変更することでPNG形式で変換することも可能です。
2.NSURLRequestを生成
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を作成
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.リクエストを送信してレスポンスを受け取る
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などを使うと良いです。