
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash:streamGenerateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H 'Content-Type: application/json' \
--no-buffer \
-X POST \
-d '{
"contents": [
{
"parts": [
{
"text": "Explain how AI works in detail"
}
]
}
]
}'
오후 2:30
위 Gemini API 응답에 맞는 Swift Codable 구조체를 설계해드릴게요.
swift
import Foundation
// MARK: - Request
struct GeminiRequest: Codable {
let contents: [Content]
}
// MARK: - Response
struct GeminiResponse: Codable {
let candidates: [Candidate]
let usageMetadata: UsageMetadata?
let modelVersion: String?
}
struct Candidate: Codable {
let content: Content
let finishReason: String?
let avgLogprobs: Double?
}
// MARK: - Shared
struct Content: Codable {
let parts: [Part]
let role: String?
}
struct Part: Codable {
let text: String
}
// MARK: - Usage
struct UsageMetadata: Codable {
let promptTokenCount: Int?
let candidatesTokenCount: Int?
let totalTokenCount: Int?
let promptTokensDetails: [TokenDetail]?
let candidatesTokensDetails: [TokenDetail]?
}
struct TokenDetail: Codable {
let modality: String?
let tokenCount: Int?
}
편의 extension도 함께:
swift
extension GeminiResponse {
var firstText: String? {
candidates.first?.content.parts.first?.text
}
}
사용 예시:
swift
let decoded = try JSONDecoder().decode(GeminiResponse.self, from: data)
print(decoded.firstText ?? "No response")
설계 포인트:
- Content는 Request/Response에서 공통으로 재사용
- role은 요청 시엔 보통 생략되므로 Optional
- usageMetadata, modelVersion 등 optional 필드는 ? 처리
- Swift의 camelCase 네이밍을 유지하면서 JSON 키와 자동 매핑 (JSONDecoder 기본 camelCase 전략 활용)
snake_case JSON 키가 있다면 decoder.keyDecodingStrategy = .convertFromSnakeCase 설정만 추가하면 됩니다.



MovieLJY 6.zip
0.39MB