LoginSignup
6
2

More than 5 years have passed since last update.

swiftで画像とテキストをmultipart同時送信

Last updated at Posted at 2018-10-09

まえがき

iOS開発で少し手こずったので備忘録として,載せておきます.
幾分冗長だなとか多々あると思いますが,長い目でよろしくお願いします.:star2:

やりたいこと

iOS開発で画像とテキストをmultipartで自社サーバへ同時送信

使用ライブラリ

Alamofire

仕様

概要

今回はチャットのようなアプリをイメージしてください.
送信は以下の4通りに分かれます.

画像 テキスト 備考
画像とテキスト同時送信
× 画像のみ送信
× テキストのみ送信
× × 何も入力されていない

今回の実装プログラムでは,上3つに対応しております.
一番下は必ずエラー処理として,PopUpみたいなのを出すといいと思われます.
今回は実装してないです.:frowning2:

WebAPIの仕様

画像とテキストを投稿するにあたってサーバへPOSTリクエストを行います.
ここで,POSTリクエストの際に以下のようなbodyが要求されています.

パラメタ 備考
user_id int 誰が送ったのかが必要なので必須
message string 投稿本文
img_file string 画像

送信実装

cocoaPodsでAlamofireのインストール

本セクションではライブラリのインストール方法を記述します.

Podfile
# Uncomment the next line to define a global platform for your project
platform :ios, '9.0'

target 'chatApp' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for ChatApp
  pod 'Alamofire', '~> 4.2.0'

  target 'ChatAppTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'ChatAppUITests' do
    inherit! :search_paths
    # Pods for testing
  end
end

送信

本セクションでは実際にコードを使ってmultipart送信を行います.
postEntry関数を呼び出すと投稿が実行されます.
画像は写真で撮影およびギャラリーからの参照で取得できると思いますが,それは頑張ってください.:v:
画像はData型です!
これは注意です.

UIViewController.swift
import Alamofire
...

    // 投稿を送信するAPIの実装
    // 第一引数: ユーザID int 型
    // 第二引数: 投稿本文 string 型
    // 第三引数: 投稿画像 Data? 型 
    // 第四引数: 投稿画像の拡張子: String? 型
    func postEntry(userId: Int, body: String?, image: Data?, imageExtension: String?) {

        Alamofire.upload(multipartFormData: { (multipartFormData) in
            if image == nil && body == nil { // どっちも何も入っていない時returnで終了
               return
            }

            // multipartFormDataというオブジェクトにappendすると送信するデータを追加していきます
            // まず,idを追加
            multipartFormData.append("\(userId)".data(using: .utf8)!,
                                                 withName: "user_id",
                                                 mimeType: "text/plain")
            // 次,画像を追加
            // 画像を送らない時は image が nil となっている
            if image != nil {
                multipartFormData.append(image!, withName: "img_file",
                                                 fileName: "img_file." + self.mImageExtension!,
                                                 mimeType: "image/" + imageExtension!)
            }
            // 最後に投稿するテキスト本文を追加
            // 投稿がnilの時は本文に何も入っていない
            if body != nil {
                multipartFormData.append(body.data(using: .utf8)!,
                                              withName: "body",
                                              mimeType: "text/plain")
            }

        }, to: "https://自社サーバのドメイン/ディレクトリhoge/ディレクトリfuga") { (encodingResult) in
            switch encodingResult {
            case .success(let upload, _, _): // 成功
                upload.responseJSON { response in
                    if !response.result.isSuccess {
                        print("# ERROR")
                    } else {
                        // TODO: ここに成功した時に任意の処理をかく
                    }
                }
            case .failure(let error): // 失敗
                print(error)
            }
        }
    }

...

終わりに

ちょっと改造してテストはしてないですが,こちらで多分通ると思います.
質問や改善要求などどしどしためらいもなく,うぇるかむです.
読んでいただきありがとうございました.

Androidの場合 -> https://qiita.com/hisakioomae/items/9588e41ead50bd62f186

6
2
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
6
2