まえがき
iOS開発で少し手こずったので備忘録として,載せておきます.
幾分冗長だなとか多々あると思いますが,長い目でよろしくお願いします.
やりたいこと
iOS開発で画像とテキストをmultipart
で自社サーバへ同時送信
使用ライブラリ
Alamofire
仕様
概要
今回はチャットのようなアプリをイメージしてください.
送信は以下の4通りに分かれます.
画像 | テキスト | 備考 |
---|---|---|
◯ | ◯ | 画像とテキスト同時送信 |
◯ | × | 画像のみ送信 |
× | ◯ | テキストのみ送信 |
× | × | 何も入力されていない |
今回の実装プログラムでは,上3つに対応しております.
一番下は必ずエラー処理として,PopUpみたいなのを出すといいと思われます.
今回は実装してないです.
WebAPIの仕様
画像とテキストを投稿するにあたってサーバへPOSTリクエストを行います.
ここで,POSTリクエストの際に以下のようなbodyが要求されています.
パラメタ | 型 | 備考 |
---|---|---|
user_id | int | 誰が送ったのかが必要なので必須 |
message | string | 投稿本文 |
img_file | string | 画像 |
送信実装
cocoaPodsでAlamofireのインストール
本セクションではライブラリのインストール方法を記述します.
# 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関数を呼び出すと投稿が実行されます.
画像は写真で撮影およびギャラリーからの参照で取得できると思いますが,それは頑張ってください.
画像はData型
です!
これは注意です.
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