LoginSignup
24
22

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-05-19

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などを使うと良いです。

24
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
22