質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

2回答

1232閲覧

SwiftでAPIKitを使用し画像データをPOSTしたい。

bearcanyon

総合スコア13

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

2クリップ

投稿2017/08/10 08:36

編集2017/08/10 08:41

###前提・実現したいこと
SwiftでAPIKitを使用し画像データをPOSTしたいのです。
サーバーサイドはPHPで書いています。

###発生している問題・エラーメッセージ

画像データがなければparametersに入れてPOSTできるのですが、画像データを入れるとPOSTできなくなります。

###該当のソースコード

swift

1// [POST] /api/users 2 struct PostUser: APIRequest { 3 typealias Response = User 4 5 var authenticate: Bool { return false } 6 var method: HTTPMethod = .post 7 var path: String { return "/api/users" } 8 var imageData: Data? 9 10 var bodyParameters: BodyParameters? { 11 let part = MultipartFormDataBodyParameters.Part(data: imageData!, name: "thumbnail") 12 return MultipartFormDataBodyParameters(parts: [part]) 13 } 14 15 var parameters: Any? { 16 return [ 17 "screen_name": "dasfasfaa", 18 "name": "fsfdsfda", 19 "password": "daffffffffs", 20 "email": "sdflaksfa@gmail.com"] 21 } 22 23 init(imageData: Data) { 24 self.imageData = imageData 25 } 26 27 func response(from object: Any, urlResponse: HTTPURLResponse) throws -> User { 28 return try decodeValue(object) 29 } 30 31 func intercept(object: Any, urlResponse: HTTPURLResponse) throws -> Any { 32 print(urlResponse.statusCode) 33 print(urlResponse) 34 print(object) 35 return object 36 } 37 } 38

###試したことと疑問な事
1,parametersにimageDataも入れてみた。

swift

1 var parameters: Any? { 2 return [ 3 "thumbnail": imageData!, 4 "screen_name": "dasfasfaa", 5 "name": "fsfdsfda", 6 "password": "daffffffffs", 7 "email": "sdflaksfa@gmail.com"] 8 } 9

"thumbnail": imageData!を削除してみるとinterceptメソッド内のobjectの中でthumbnail field is requiredとなりますが、
上記のように"thumbnail": imageData!を追加するとinterceptメソッドも実行されずswitch文の.failureに入りAPIKit.SessionTaskError error 1となります。

2,imageDataがなければPOSTできるのか試してみた。
(サーバー側の仕様でthumnailがrequiredなので成功はしていませんがinterceptメソッドの中のobjectではthumbnail field is requiredになります。)

3,そもそもPHP側ではfileで受け取ると仕様書に書いてありますが、Data型にして送るのはあっているのか。
ターミナルで

curl -XPOST -H "Accept: application/json" -F thumbnail=@/Users/名前/Desktop/test.png -F screen_name=hoge -F name=fuga -F password=hogefuga -F email=hogehgoe@gmail.com https://任意のURL

するとPOSTは成功します。

4,APIKitではAcceptのデフォルト値はapplication/jsonなのか。
現在は特に指定などはしていません。

###知りたいこと
APIKitで画像データをPOSTするときのAPIの記述のサンプルなど知りたいです。
どうかよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

// [POST] /api/users struct PostUser: APIRequest { typealias Response = User var authenticate: Bool { return false } var method: HTTPMethod = .post var path: String { return "/api/users" } var imageData: Data? var screenName: String? var name: String? var password: String? var email: String? var bodyParameters: BodyParameters? { var params = [ try! MultipartFormDataBodyParameters.Part(value: screenName!, name: "screen_name"), try! MultipartFormDataBodyParameters.Part(value: name!, name: "name"), try! MultipartFormDataBodyParameters.Part(value: password!, name: "password"), try! MultipartFormDataBodyParameters.Part(value: email!, name: "email") ] if let imageData = imageData { params.append(MultipartFormDataBodyParameters.Part(data: imageData, name: "thumbnail", mimeType: "image/jpeg", fileName: "thumbnail")) return MultipartFormDataBodyParameters(parts: params) } else { return MultipartFormDataBodyParameters(parts: params) } } init(imageData: Data?, screenName: String?, name: String?, password: String?, email: String?) { self.imageData = imageData self.screenName = screenName self.name = name self.password = password self.email = email } func response(from object: Any, urlResponse: HTTPURLResponse) throws -> User { return try decodeValue(object, rootKeyPath: "user") } func intercept(object: Any, urlResponse: HTTPURLResponse) throws -> Any { return object } }

現状このようなコードで正常に動いています。

投稿2017/09/06 21:55

bearcanyon

総合スコア13

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

APIKitを使って試してないので不確かですが、
multipart/form-data と application/x-www-form-urlencoded 、
あるいは application/json を同時に使うことはできないので
var parameters ... を抜きにして、
かわりに bodyParameters の return に parametersの配列を追加してみてはいかがでしょうか。

swift

1let part = MultipartFormDataBodyParameters.Part(data: imageData!, name: "thumbnail") 2return MultipartFormDataBodyParameters(parts: [part])

swift

1let part = MultipartFormDataBodyParameters.Part(data: imageData!, name: "thumbnail") 2let part2 = MultipartFormDataBodyParameters.Part(value: "hoge", name: "screen_name") 3//... 4return MultipartFormDataBodyParameters(parts: [part, part2, part3, ...])

parametersについては、APIKit自身のソース中に
The convenience property for queryParameters and bodyParameters
という記述があることから、一緒に使うものではなさそうです。

swift

1// https://github.com/ishkawa/APIKit/blob/master/Sources/APIKit/Request.swift:77 2 3 public var bodyParameters: BodyParameters? { 4 guard let parameters = parameters, !method.prefersQueryParameters else { 5 return nil 6 } 7 8 return JSONBodyParameters(JSONObject: parameters) 9}

82行目で上書きされるようです。

投稿2017/08/23 14:04

TakeoSaki

総合スコア97

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

bearcanyon

2017/09/06 21:53

回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問