LoginSignup
11
9

More than 5 years have passed since last update.

Swift4でAlamofire4を使ってMultipartで画像をサーバへアップロードする

Last updated at Posted at 2018-01-17

Swift4でAlamofire4を使い、画像をテキストのフォームデータと混ぜたマルチパートでサーバへアップロードしたときのメモ書き。

HttpRequestSample.swift
import Alamofire

public class HttpRequestSample {

    // 画像付きのマルチパートでアップロード
    public func uploadMultipartFromData(parameters: [[String: Any]]) {
        let url = "https://example.com/api/hoge"
        let urlRequest = URL(string: url)!
        let headers: HTTPHeaders = [
            "Authorization": "Bearer QWxhZGRpbjpvcGVuIHNlc2FtZQ==",
            "Accept": "application/json"
        ];

        Alamofire.upload(
            multipartFormData: { (multipartFormData) in
                for element in parameters {
                    self.appendMultipartFormData(multipartFormData: multipartFormData, element: element)
                }
            },
            to: urlRequest,
            headers: headers,
            encodingCompletion: { encodingResult in
                // file をエンコードした後のコールバック
                switch encodingResult {
                case .success(let upload, _, _):
                    self.uploaldMultipartProcess(upload: upload, completeNotificationName: .uploadRequestComplete);
                case .failure(let encodingError):
                    print(encodingError)
                }
            }
        )
    }

    // マルチパートのフォームデータをmultipartFormDataに追加
    func appendMultipartFormData(multipartFormData: MultipartFormData, element: [String: Any]) {
        switch element["value"] {
        case let image as UIImage:
            var imageData: Data
            var mimeType: String
            if element["extension"] as! String == "jpg" {
                print(element["extension"] as! String)
                imageData = UIImageJPEGRepresentation(image, 1.0)!
                mimeType = "jpeg"
            } else {
                imageData = UIImagePNGRepresentation(image)!
                mimeType = "png"
            }
            multipartFormData.append(
                imageData,
                withName: element["key"] as! String,
                fileName: element["name"] as! String,
                mimeType: mimeType
            )
        default:
            let value = element["value"] as! String
            multipartFormData.append((value.data(using: .utf8))!, withName: element["key"] as! String)
            break
        }
    }

    // 画像エンコード完了後のアップロード処理
    func uploaldMultipartProcess(upload: UploadRequest, completeNotificationName: NSNotification.Name) {
        upload
            .uploadProgress(closure: { (progress) in
                print("Upload Progress: \(progress.fractionCompleted)")
            })
            .validate(statusCode: 200..<300)
            .validate(contentType: ["application/json"])
            .responseJSON { (response: DataResponse<Any>) in
                let statusCode = response.response?.statusCode
                print("Success: \(response.result.isSuccess)")
                print("Status code: \(String(describing: statusCode))")
        }
    }

    // 画像アップロード用のパラメータを生成
    public func generateUploadParameters(img: UIImage, fileExtension: String) -> [[String: Any]] {
        let parameters: [[String: Any]] = [
            ["key": "name", "value": "hoge"],
            ["key": "file", "value": img, "extension": fileExtension],
        ]
        return parameters
    }

}
呼び出し側
let parameters = HttpRequestSample.generateUploadParameters(img: image, fileExtension: "jpg")
let httpRequest = HttpRequest()
httpRequest.uploadMultipartFromData(
    parameters: parameters,
    requestPath: "media",
    completeNotificationName: .uploadRequestComplete
)
11
9
4

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
11
9