Postman製APIをSwiftで叩く時の備忘録
はじめに
Postmanで作成されたAPIをSwiftで呼び出し、返されたデータをデコードする方法について解説します。この記事では、URLRequestの作成とAPIキーの付与、JSONのデコードなど、APIとの連携に必要な基本的な手順を備忘録として残しました。
環境
- Xcode16.0 Beta2
- Swift5.10
- iOS18.0
- 標準ライブラリのみ
実装
APIのURLとAPIKeyを確認、URLRequestを作成
APIのアクセス先URLを確認します。認証が必要なAPIの場合はAPIKeyをリクエストのヘッダにつける必要があります。
以下のようにURLRequest
を作成します。
let baseURL: URL = URL(string: ...)
let apiKey = "..."
let request: URLRequest = {
var request = URLRequest(url: baseURL)
request.httpMethod = "GET"
// APIリクエストの認証に必要なカスタムヘッダを添える
request.setValue(apiKey, forHTTPHeaderField: "X-API-Key")
// ついでにキャッシュポリシーも設定しておく
request.cachePolicy = .returnCacheDataElseLoad
return request
}
APIを叩いてデータを取得する
URLRequest
が作成できたら、今回はURLSession
でAPIを叩きます。👊
let (data, _) = try await URLSession.shared.data(for: request)
let newsItems = try JSONDecoder().decode(ResponseModel.self, from: data)
APIを叩くとData
が手に入ります。
それをSwift側の世界で使えるようにするためにJSONDecoder()
にDecodable
に準拠した型を指定してデコードします。
APIから渡ってくるデータの内容によってResponseModel
の型の内容が決まります。
ResponseModel
の型がAPI制作者や既にプロジェクトに存在している場合はそれらを参考にすれば良いですが、自分で0から作る必要が出てくる場合、Terminal等から直接APIを叩くことでも確認することができます。
curl -v -H "X-API-Key: your-api-key" https://your.base.url
認証が必要なAPIの場合は-Hオプションとその後にカスタムヘッダを""
で囲んで付与します。その後ろにURLをつけて実行します。
curl
コマンドを叩き、成功したら返ってきたデータをClaudeに解釈させ、JSONDecoder()
でデコードできるstructを作成してもらいました。以下はその一例です。
Claudeにプロンプトを投げてレスポンスモデルを生成してもらう
"hoge": [
{
"id": 1,
"title": "あいうえお",
"image_url": "https://picsum.photos/200/200",
"priority": 2
},
{
"id": 2,
"title": "かきくけこ",
"image_url": "https://picsum.photos/200/200",
"priority": 1
}
]
Postmanを叩くとこのbodyが返ってきます。このデータをSwiftで扱えるようにJSONDecodeしたい。レスポンスモデルを出力してください。
出力されたレスポンスモデル
struct HogeResponse: Codable {
let hoge: [HogeItem]
}
// 各Hoge項目を表す構造体
struct HogeItem: Codable {
let id: Int
let title: String
let imageURL: URL
let priority: Int
enum CodingKeys: String, CodingKey {
case id
case title
case imageURL = "image_url"
case priority
}
}
全体のコード
struct HogeResponse: Codable {
let hoge: [HogeItem]
}
// 各Hoge項目を表す構造体
struct HogeItem: Codable {
let id: Int
let title: String
let imageURL: URL
let priority: Int
enum CodingKeys: String, CodingKey {
case id
case title
case imageURL = "image_url"
case priority
}
}
class HogeService {
enum Const {
static let baseURL = URL(string: "...")
static let apiKey = "..."
}
func fetch() async throws -> [HogeItem] {
var request = URLRequest(url: Const.baseURL)
request.httpMethod = "GET"
request.setValue(Const.apiKey, forHTTPHeaderField: "X-API-Key")
request.cachePolicy = .returnCacheDataElseLoad
let (data, _) = try await URLSession.shared.data(for: request)
let hogeItems = try JSONDecoder().decode(HogeResponse.self, from: data)
return hogeItems.hoge
}
}
最後に
基本的な部分のみ書きましたが、改善できる箇所はたくさんあると思います。Alamofire
等のライブラリを導入したり、APIキーをplistで秘匿したり、Swift-Testing
をキャッチアップしてテストを書くなど!
関連
Discussion