SwiftでSpringBootで作られたAPIに文字列を渡す
SwiftでSpringBootで作られたAPIに文字列を渡した時にちょっと詰まったのでそれの忘備録です。
@RequestMapping(value = "", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public SampleBean request(@RequestBody String text) {
SampleBean sampleBean = new SampleBean();
sampleBean.setText(text);
return sampleBean;
}
@Data
public class SampleBean implements Serializable {
private String text;
}
このような Bean を返すエンドポイントを作りました。curl コマンドでエンドポイントを叩くと以下のようなレスポンスが返ってきます。想定通りの挙動です。
curl "http://localhost:8080/sample" \
-X POST \
-H 'Content-Type: application/json' \
-d 'Kabigon' \
| jq
{
"text": "Kabigon"
}
次にこのエンドポイントを Swift から叩きます。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PlaygroundSupport | |
import XCPlayground | |
enum HttpMethod: String { | |
case get = "GET" | |
case post = "POST" | |
} | |
struct APIRequest { | |
static func createUrlRequest<RequestBody: Encodable>(baseUrl: String = "https://swiswiswift.com/", path: String, httpMethod: HttpMethod = .get, requestHeader: [String: String] = ["Content-Type": "application/json"], requestBody: RequestBody) -> URLRequest { | |
let url = URL(string: baseUrl + path)! | |
var request = URLRequest(url: url) | |
request.httpMethod = httpMethod.rawValue | |
request.allHTTPHeaderFields = requestHeader | |
if let httpBody = try? JSONEncoder().encode(requestBody) { | |
request.httpBody = httpBody | |
} | |
return request | |
} | |
} | |
struct SampleBean: Codable { | |
let text: String | |
} | |
let request = APIRequest.createUrlRequest(baseUrl: "http://localhost:8080/" ,path: "sample", httpMethod: .post, requestBody: "Kabigon") | |
let task = URLSession.shared.dataTask(with: request) { data, response, error in | |
guard let data = data, let response = response as? HTTPURLResponse else { | |
return | |
} | |
let sampleBean = try! JSONDecoder().decode(SampleBean.self, from: data) | |
print(sampleBean.text) // -> "Kabigon" | |
} | |
task.resume() |
レスポンスを SampleBean にデコードしてその中の text プロパティを表示すると ダブルクオート付きの文字列が表示されてしまいます。 それはSwift がダブルクオートを含めて Spring 側にデータを送信しているからです。 Swiftが行っているリクエストを curl コマンドに翻訳すると以下になります。
curl "http://localhost:8080/sample" \
-X POST \
-H 'Content-Type: application/json' \
-d '"Kabigon"'
将来的に送りたいプロパティが増えるので、Swiftから String 型ではなく、任意の struct を送信するようにしました。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let request = APIRequest.createUrlRequest(baseUrl: "http://localhost:8080/" ,path: "sample", httpMethod: .post, requestBody: SampleBean(text: "Kabigon")) | |
let task = URLSession.shared.dataTask(with: request) { data, response, error in | |
guard let data = data, let response = response as? HTTPURLResponse else { | |
return | |
} | |
let sampleBean = try! JSONDecoder().decode(SampleBean.self, from: data) | |
print(sampleBean.text) // Kabigon | |
} | |
task.resume() |
curl "http://localhost:8080/sample" \
-X POST \
-H 'Content-Type: application/json' \
-d '{"text":"Kabigon"}'