Yams 패키지의 YAMLDecoder 등으로 YAML 파일을 읽는 스위프트 앱이나 명령줄 도구는 Codable 타입으로 디코딩하는데, 긴 설정에 맞는 struct를 손으로 쓰는 일은 지루합니다. 이 변환기는 자바스크립트 yaml 라이브러리(YAML 1.2 코어 스키마)로 YAML을 읽고 앵커와 병합 키를 펼친 뒤, 매핑마다 let 속성이 있는 struct 하나를 쓰고, 키 이름을 바꿔야 하면 CodingKeys 열거형도 만듭니다.
먼저 같은 위치의 값을 하나로 합칩니다. 매핑 목록은 모든 항목의 속성을 합친 항목 struct 하나가 되고, 일부 항목에 없는 키는 옵셔널 속성이 되며, 정수와 소수가 섞인 숫자 목록은 [Double]이 됩니다. 옵션으로 루트 타입 이름(기본 Payload, 파일 이름은 Payload.swift)과 속성을 let 대신 var로 쓸지 정합니다.
예제 세 가지(API 응답, 앵커와 병합 키, 엣지 케이스) 중에서 고르거나 내 YAML을 붙여 넣으면 Swift 코드가 입력과 함께 갱신됩니다. 모든 작업은 업로드 없이 브라우저 탭 안에서 일어나고, 입력은 20MiB까지 가능합니다.
사용 방법
YAML 붙여 넣기 또는 예제 고르기
YAML을 붙여 넣거나
.yaml파일을 편집기에 끌어다 놓고, 아니면 예제 칩으로 시작하세요. 루트로는 매핑과 목록을 쓸 수 있으며, 스칼라 하나는 struct 이름을 붙일 곳이 없어 오류가 표시됩니다.루트 타입 이름 정하기
루트 타입 이름 칸에 이름을 씁니다. PascalCase로 바뀌어 중첩 struct의 접두어가 되고(
PayloadServer), 내려받는 파일 이름도Payload.swift처럼 이를 따릅니다.let 또는 var 고르기
let 대신 var 사용 스위치를 켜면 모든 속성이
var가 되어 값을 바꾸는 모델에 알맞습니다. 기본은 바뀌지 않는let속성입니다.문서와 병합 키 고르기
파일에 문서가 여러 개면 자동 모드가 목록으로 만들고, 항상 배열은 문서 하나도 같은 방식으로 감싸며, 첫 문서만은 나머지를 버립니다. 병합 키(<<) 펼치기는 물려받은 키를 struct의 속성으로 복사합니다.
struct 확인 후 복사
루트 struct가 먼저 나오고 중첩 struct가 만난 순서대로 이어집니다. 옵셔널,
JSONValue속성,CodingKeys케이스를 확인한 뒤 코드를 복사하거나.swift파일로 내려받습니다.
작동 원리
YAML 값과 Swift 타입
타입은 파싱된 값에서 정해집니다. YAML 1.2에서는 true와 false만 불리언이라 debug: no는 String입니다. 날짜는 문자열이고, 모든 정수는 Int, 모든 소수는 Double입니다. 목록은 원소 타입의 [T]이고, 매핑은 경로를 따라 이름 붙은 struct가 됩니다.
다른 값과 함께 나오는 null은 속성을 옵셔널(String?)로 만들고, 일부 매핑에 없는 키도 마찬가지입니다. 늘 null뿐이거나 [1, two]처럼 서로 다른 타입이 섞인 위치는 생성되는 JSONValue 열거형을 쓰며, 이 열거형은 Codable 구현과 함께 파일 끝에 붙습니다. JSONValue에는 이미 .null 케이스가 있어서 키 자체가 없을 수 있을 때만 옵셔널로 감쌉니다.
| YAML | Swift | 비고 |
|---|---|---|
| name: api | String | |
| port: 8080 | Int | 32비트를 넘는 정수도 Int |
| cpu: 0.5 | Double | |
| debug: no | String | 불리언은 YAML 1.1에서만 |
| enabled: true | Bool | |
| when: 2026-10-01 | String | 코어 스키마에는 타임스탬프 타입이 없음 |
| region: ~ (단독) | JSONValue | 문자열과 함께 나오면 String? |
| tags: [web, edge] | [String] | |
| mixed: [1, two] | [JSONValue] | 열거형이 파일 끝에 붙음 |
| server: {host: a} | struct PayloadServer | 경로에서 이름을 만듦 |
| id: 9007199254740993 | String | 2^53을 넘으면 정확한 텍스트로 유지하고 알림 표시 |
CodingKeys와 이름
키는 lowerCamelCase 속성 이름이 됩니다. max-conn이 maxConn이 되는 식으로 struct의 키 하나라도 이름이 바뀌면 그 struct에 모든 속성을 나열한 CodingKeys 열거형이 생깁니다. Swift가 일부만 나열한 목록을 거부하기 때문입니다. 이름이 바뀐 케이스에는 원래 문자열이 붙고 그대로인 것은 단순 케이스라서, 디코딩과 인코딩이 계속 YAML 키를 씁니다.
default나 class 같은 Swift 키워드 이름에는 Value가 붙고, ASCII 글자가 없는 키는 field가 되며, 겹치는 이름에는 숫자 접미사가 붙습니다. 루트 목록은 typealias Payload = [PayloadItem]이 되고 빈 매핑은 빈 struct가 됩니다.
숫자 1.0, 병합 키, 문서
생성기는 YAML 표기가 아니라 평범한 숫자를 받으므로 ratio: 1.0 하나만 있으면 숫자 1이고 Int입니다. 같은 위치 어딘가에 [1.0, 2.5]처럼 소수가 있으면 Double이 됩니다. Double 속성은 정수 3도 디코딩하지만 Int 속성은 1.5를 디코딩하지 못하므로, 샘플에 소수가 빠진 경우는 고칠 만합니다.
병합 키는 기본으로 펼쳐지므로 앵커에서 물려받는 매핑은 물려받은 속성을 모두 갖습니다. 스위치를 끄면 <<에서 만든 속성이 중첩 struct와 함께 나타납니다. 여러 문서는 목록이 되어 typealias가 생기고, 모든 문서에 없는 키는 옵셔널 속성이 됩니다.
실제 예시
server:
host: a
port: 8080
debug: noimport Foundation
struct Payload: Codable {
let server: PayloadServer
}
struct PayloadServer: Codable {
let host: String
let port: Int
let debug: String
}이름이 바뀐 키가 없어서 CodingKeys 열거형이 쓰이지 않습니다. debug: no는 YAML 1.2에서 String입니다.
max-conn: 5
name: ximport Foundation
struct Payload: Codable {
let maxConn: Int
let name: String
enum CodingKeys: String, CodingKey {
case maxConn = "max-conn"
case name
}
}열거형이 생기면 Swift는 모든 저장 속성이 CodingKeys에 있어야 하므로, 이름이 바뀌지 않은 name도 함께 나열됩니다.
- k: a
- k: b
extra: 1.5
when: 2026-03-14import Foundation
typealias Payload = [PayloadItem]
struct PayloadItem: Codable {
let k: String
let extra: Double?
let when: String?
}루트 목록은 typealias와 항목 struct 하나가 됩니다. extra와 when은 한 항목에만 있어 둘 다 옵셔널이고, 날짜는 String입니다.
a: [1, two]import Foundation
struct Payload: Codable {
let a: [JSONValue]
}
indirect enum JSONValue: Codable {
case string(String)
case number(Double)
case bool(Bool)
case object([String: JSONValue])
case array([JSONValue])
case null
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if container.decodeNil() { self = .null; return }
if let value = try? container.decode(Bool.self) { self = .bool(value); return }
if let value = try? container.decode(Double.self) { self = .number(value); return }
if let value = try? container.decode(String.self) { self = .string(value); return }
if let value = try? container.decode([String: JSONValue].self) { self = .object(value); return }
if let value = try? container.decode([JSONValue].self) { self = .array(value); return }
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Unsupported JSON value")
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .string(let value): try container.encode(value)
case .number(let value): try container.encode(value)
case .bool(let value): try container.encode(value)
case .object(let value): try container.encode(value)
case .array(let value): try container.encode(value)
case .null: try container.encodeNil()
}
}
}숫자와 문자열이 섞인 목록은 하나의 Swift 타입으로 나타낼 수 없어서, 디코딩된 어떤 값이든 담을 수 있는 JSONValue 열거형을 덧붙입니다.
id: 7
ratio: 1.0
name: ximport Foundation
struct Payload: Codable {
var id: Int
var ratio: Int
var name: String
}let 대신 var 사용을 켜면 모든 속성이 var입니다. ratio는 생성기가 YAML 표기 1.0이 아니라 숫자 1을 보기 때문에 Int입니다.
자주 하는 실수
1.0 하나는 Int 속성이 됨
생성기가 보는 것은 숫자 1이라서
ratio: 1.0은Int가 되고, 나중에 실제 1.5를 디코딩하면 타입 불일치로 실패합니다. 샘플에 소수 값을 넣거나 타입을 직접Double로 고치세요.없는 키는 기본값이 아니라 옵셔널
일부 매핑에 없는 키는
T?가 됩니다. Swift가 합성하는 디코더는 없는 키를 nil로 처리하지만, 코드에서는 여전히 언래핑해야 합니다.선택 여부는 여러 매핑을 보고 추정
같은 위치의 일부 매핑에 키가 없거나 null일 때만 옵셔널 속성이 됩니다. 샘플 레코드가 하나면 모든 키가 필수이므로 여러 개를 붙여 넣으세요.
JSONValue는 코드 블록을 추가함
섞이거나 null뿐인 값은
JSONValue열거형을 끌어옵니다. 데이터가 실제로는 일정하다면 샘플이나 YAML을 고쳐 속성이 구체적인 타입을 갖게 하면 열거형이 사라집니다.YAML 로더도 같은 규칙이어야 함
여기서
yes는String이고0123은 숫자 123입니다. YAML 1.1 로더는 이를true와 8진수 83으로 읽어 이 타입들로 디코딩되지 않으므로, 로더를 확인하거나 값을 따옴표로 감싸세요.날짜는 문자열
YAML 날짜는
String속성입니다.Date가 필요하면 코드에서ISO8601DateFormatter나 날짜 디코딩 전략으로 변환하세요.
자주 묻는 질문
최상위가 목록인 YAML도 되나요?
네. 루트 목록은 typealias Payload = [PayloadItem]과 항목 struct가 됩니다. 문서가 여러 개인 파일도 자동 모드에서는 이런 목록이 됩니다.
yes가 왜 String인가요?
YAML 1.2 코어 스키마의 불리언은 true와 false뿐이라서 yes, no, on, off는 평범한 텍스트입니다. struct에는 Bool이 아니라 String 속성으로 들어갑니다.
키 하나만 바뀌어도 모든 속성이 CodingKeys에 들어가는 이유가 뭔가요?
Swift는 CodingKeys 열거형에 struct의 모든 저장 속성이 있어야 합니다. 그래서 키 하나가 다른 Swift 이름을 필요로 하면 생성기가 모두 나열합니다.
null과 선택 키는 어떻게 타입이 정해지나요?
다른 값과 함께 나오는 null이나 일부 매핑에 없는 키는 T?가 됩니다. 늘 null뿐인 위치는 이미 .null 케이스가 있는 JSONValue가 됩니다.
병합 키도 펼치나요?
기본값은 펼침이라 <<: *anchor로 물려받은 키가 struct의 속성이 됩니다. 병합 키 펼치기를 끄면 <<에서 만든 속성이 대신 나옵니다.
var 속성으로 만들 수 있나요?
네. let 대신 var 사용을 켜면 모든 속성이 var로 선언됩니다.
YAML이 업로드되나요?
아니요. 파싱과 코드 생성은 브라우저 탭 안에서 실행되며 서버로 전송되지 않습니다. 입력은 20MiB까지입니다.
마지막 업데이트:
