MYMONDAY.ai
서비스스튜디오도구데이터·포맷73CSS 생성기19색상·이미지10인코딩·보안10웹·SEO11개발·데브옵스10파일·내보내기18계산기6가이드

CSV Swift 구조체 생성기

CSV를 붙여 넣으면 한 행에 대응하는 Codable Swift 구조체와 typealias가 나와 JSONDecoder로 바로 쓸 수 있습니다.

  • 브라우저에서 처리
  • 가입 없음
  • 무료

도구 작업 공간

예제

옵션

끄면 열 이름이 column_1, column_2 …가 되고 JSON은 배열이 됩니다.

비어 있거나 구분자만 있는 줄을 버려서 뒤 레코드가 밀리지 않게 합니다.

채워진 셀이 모두 맞을 때만 열이 숫자·불리언이 됩니다. 01234나 20자리 ID는 텍스트로 남습니다. 끄면 모든 셀이 적은 그대로 텍스트입니다.

대소문자 구분 없이 쉼표로 구분합니다. 빈 셀은 항상 null입니다.

CSV 입력

6줄181byte구분자: 쉼표 (자동 감지)

결과

⌘/Ctrl + Enter로 복사
결과 · CsvRow.swift
import Foundation

typealias CsvRow = [CsvRowItem]

struct CsvRowItem: Codable {
    let id: Int
    let customer: String
    let total: Double
    let paid: Bool
    let note: String?
    let shipped: String?
}
행3
열6
타입1
크기212byte

파일을 읽은 결과

변환기가 보는 앞쪽 레코드와 열마다 정해진 타입입니다.

줄id숫자customer텍스트total숫자paid불리언note텍스트shipped텍스트
21001Ada Lovelace87.90trueGift wrap, please2026-03-14
31002Grace Hopper19falseNA2026-03-15
41003Linus1200.5trueLine one line two·

이 CSV Swift 생성기는 CSV나 TSV의 헤더와 값을 읽어 import Foundation 아래에 한 행에 대한 Codable 구조체와 행 배열에 대한 typealias를 씁니다. iOS·macOS 앱에서 스프레드시트를 모델링할 때 번거로운 부분, 즉 Swift 명명 규칙에 맞는 속성 이름 정하기, class 같은 키워드 피하기, 모든 속성을 헤더와 이어 주는 CodingKeys 열거형 작성을 덜어 줍니다.

타입은 모든 행을 보고 정합니다. 감지를 켜면 숫자 열은 Int나 Double, true·false 열은 Bool, 빈 셀이나 null 단어가 있는 열은 String? 같은 옵셔널이 됩니다. first name, user-id 같은 헤더는 firstName, userId가 되고, 이름이 하나라도 바뀌면 CodingKeys가 모든 속성을 나열하므로 구조체가 그대로 컴파일됩니다.

CSV는 브라우저 안에서 처리되며 서버로 전송되지 않습니다. 한도는 입력 20 MiB, 데이터 행 50,000개, 열 200개이고, 다운로드 파일 이름은 CsvRow.swift처럼 루트 타입 이름을 따릅니다.

사용 방법

  1. CSV 불러오기

    행을 붙여 넣거나 .csv, .tsv 파일을 엽니다. 헤더 행이 속성 이름과 코딩 키가 됩니다.

  2. 루트 이름 설정

    루트 타입 이름의 기본값 CsvRow는 typealias CsvRow = [CsvRowItem]과 struct CsvRowItem을 만듭니다. Products처럼 복수형을 쓰면 typealias Products = [Product]가 됩니다.

  3. 감지 여부 선택

    "숫자·불리언·null 감지"를 켜면 열이 Int, Double, Bool, String이 되고, 빈 셀이나 null 단어가 있는 열은 옵셔널이 됩니다. 끄면 모든 속성이 옵셔널이 아닌 String입니다.

  4. let과 var 선택

    디코딩한 행을 그 자리에서 고쳐야 한다면 "let 대신 var 사용"을 켭니다. 기본값에서는 모든 속성이 불변 let입니다.

  5. Xcode로 복사

    "파일을 읽은 결과"에서 열마다 타입을 확인한 뒤 코드를 복사하거나 .swift 파일로 내려받습니다. CSV를 JSON으로 변환한 다음 JSONDecoder().decode(CsvRow.self, from: data)로 디코딩합니다.

작동 원리

적용되는 이름 규칙

각 헤더를 공백, 구두점, 소문자에서 대문자로 바뀌는 지점에서 단어로 나눈 뒤 속성은 카멜 케이스, 타입은 파스칼 케이스로 합칩니다. first name은 firstName, user-id는 userId가 됩니다. 숫자로 시작하게 되는 이름에는 field 접두사가 붙어 1st place는 field1stPlace가 됩니다. Swift는 유니코드 식별자를 허용하므로 이름 같은 한글 헤더는 그대로 속성 이름이 됩니다.

class, default, init, protocol, self 같은 키워드는 속성 이름으로 쓸 수 없어 생성기가 Value를 붙입니다. class는 classValue가 됩니다. type이나 set처럼 Swift가 이름으로 허용하는 단어는 그대로 둡니다.

헤더속성CodingKeys 케이스
ididcase id
first namefirstNamecase firstName = "first name"
user-iduserIdcase userId = "user-id"
classclassValuecase classValue = "class"
selfselfValuecase selfValue = "self"
1st placefield1stPlacecase field1stPlace = "1st place"
typetypecase type

타입과 옵셔널

감지 단계에서 열마다 종류가 하나로 정해지고, 생성기는 그다음 모든 행을 합칩니다. 정수만 있으면 Int, 소수가 하나라도 있으면 정수도 디코딩하는 Double입니다. true, false 열은 Bool, 나머지는 String입니다. 빈 셀이나 null 단어가 하나라도 있는 열은 Double?, String? 같은 옵셔널이 되며, JSONDecoder는 JSON null을 nil로 바꿉니다.

모든 행에서 비어 있는 열은 데이터로 타입을 정할 수 없습니다. 이런 열은 JSONValue가 되고, 생성기가 문자열·숫자·불리언·객체·배열·null을 디코딩하는 작은 indirect enum JSONValue: Codable을 덧붙입니다.

열의 값Swift 타입
1, 2Int
10, 12.5Double
true, FALSEBool
Ari, (빈 셀)String?
3, N/AInt?
9.5, (빈 셀)Double?
02134, 10001String
(빈 셀), NAJSONValue

CodingKeys는 모든 속성을 포함

속성 이름 중 하나라도 헤더와 다르면 구조체에 모든 저장 속성을 나열한 CodingKeys 열거형이 붙습니다. 이름이 바뀐 속성은 헤더를 원시값으로, 그대로인 속성은 일반 케이스로 씁니다. 열거형이 있으면 Swift는 저장 속성마다 케이스를 요구하는데, 출력이 이를 모두 갖추므로 고치지 않고 컴파일됩니다. 바뀐 이름이 없으면 열거형을 생략하고 Swift가 키를 직접 합성합니다.

    enum CodingKeys: String, CodingKey {
        case id
        case firstName = "first name"
        case classValue = "class"
        case note
    }

실제 예시

기본 설정
입력
id,name,active
1,Ari,true
2,Bea,false
출력
import Foundation

typealias CsvRow = [CsvRowItem]

struct CsvRowItem: Codable {
    let id: Int
    let name: String
    let active: Bool
}

루트 타입 이름 CsvRow입니다. 바뀐 이름이 없어 CodingKeys 열거형도 없습니다.

이름이 바뀐 속성과 예약어
입력
id,first name,class,note
1,Ari,A,hi
2,Bea,B,
출력
import Foundation

typealias Person = [PersonItem]

struct PersonItem: Codable {
    let id: Int
    let firstName: String
    let classValue: String
    let note: String?

    enum CodingKeys: String, CodingKey {
        case id
        case firstName = "first name"
        case classValue = "class"
        case note
    }
}

루트 타입 이름은 Person입니다. CodingKeys가 네 속성을 모두 나열하고, 둘째 행의 빈 note 때문에 note는 옵셔널이 되었습니다.

옵셔널과 var 속성
입력
id,price,note
1,10,
2,12.5,gift
출력
import Foundation

typealias CsvRow = [CsvRowItem]

struct CsvRowItem: Codable {
    var id: Int
    var price: Double
    var note: String?
}

"let 대신 var 사용"을 켠 결과입니다. price에 10과 12.5가 섞여 Double이 되었고, note에는 빈 셀이 있어 String?입니다.

숫자로 시작하거나 기호가 든 헤더
입력
1st place,user-id,class,Name
1,2.5,x,true
출력
import Foundation

typealias Rank = [RankItem]

struct RankItem: Codable {
    let field1stPlace: Int
    let userId: Double
    let classValue: String
    let name: Bool

    enum CodingKeys: String, CodingKey {
        case field1stPlace = "1st place"
        case userId = "user-id"
        case classValue = "class"
        case name = "Name"
    }
}

루트 타입 이름은 Rank입니다. 모든 속성이 헤더와 달라 모든 케이스에 원래 텍스트가 붙었습니다.

감지를 끈 경우
입력
id,price
1,10
2,12.5
출력
import Foundation

typealias CsvRow = [CsvRowItem]

struct CsvRowItem: Codable {
    let id: String
    let price: String
}

모든 속성이 옵셔널이 아닌 String이라, JSON 값이 문자열이기만 하면 어떤 열 내용도 디코딩됩니다.

자주 하는 실수

  • CSV는 JSON이 아님

    JSONDecoder로 쓰는 Codable은 CSV가 아니라 JSON을 읽습니다. 파일을 먼저 JSON으로 변환해 디코딩하거나, CSV를 직접 또는 라이브러리로 파싱해 구조체를 채우세요. 구조체는 모델이지 파서가 아닙니다.

  • 옵셔널은 샘플만 보고 정함

    샘플에 빈 셀이 없는 열은 옵셔널이 아니므로, 나중 파일에서 그 필드가 null이면 DecodingError.valueNotFound로 디코딩이 실패합니다. 실제 데이터에서 빠질 수 있는 속성에는 직접 ?를 붙이세요.

  • 모든 행에서 비어 있는 열

    이런 열은 JSONValue가 되고 30줄 남짓한 보조 열거형이 덧붙습니다. 샘플에 그 열의 실제 값을 넣거나, JSONValue를 기대하는 타입으로 바꾸고 열거형을 지우세요.

  • 같은 이름으로 합쳐지는 헤더

    user id와 user_id는 둘 다 카멜 케이스로 userId가 되므로 둘째는 userId2가 됩니다. CodingKeys는 각각을 올바른 헤더에 이어 주지만, 속성 이름은 의미 있게 바꾸세요.

  • 식별자가 숫자로 읽힘

    1001처럼 숫자만 있는 ID는 Int가 됩니다. 앞자리 0이 있는 ID는 이미 String으로 남지만, 나중에 0이 붙을 수 있는 코드라면 타입을 고치거나 감지를 끄세요.

자주 묻는 질문

구조체를 만드나요, 클래스를 만드나요?

Codable을 따르는 구조체이며, 속성은 기본적으로 let이고 "let 대신 var 사용"을 켜면 var입니다. 참조 의미론이 필요하면 클래스로 직접 바꾸세요.

Swift 키워드는 어떻게 처리되나요?

class나 self처럼 키워드와 같은 헤더에는 Value가 붙고, 원래 이름은 CodingKeys의 원시값으로 남습니다.

빠진 CodingKeys 케이스를 직접 추가해야 하나요?

아니요. 속성 이름이 하나라도 바뀌면 열거형이 바뀌지 않은 이름까지 모든 속성을 나열하므로 구조체가 고치지 않고 Codable을 따릅니다.

빈 셀이 옵셔널이 되나요?

감지를 켜면 그렇습니다. 빈 셀이나 NA 같은 null 단어가 하나라도 있는 열은 String?, Int?, Double?, Bool?이 됩니다. 감지를 끄면 모든 속성이 옵셔널이 아닌 String입니다.

Swift에서 CSV를 바로 읽을 수 있나요?

아니요. 생성된 모델은 한 행을 설명합니다. Swift CSV 라이브러리나 직접 만든 리더로 CSV 텍스트를 파싱해 구조체를 채우거나, 파일을 먼저 JSON으로 변환하세요.

파일이 업로드되나요?

아니요. 헤더, 샘플 값, 생성된 구조체는 브라우저 안에서 처리되며 서버로 전송되지 않습니다. Swift 코드는 페이지에서 Xcode로 직접 복사해 가져갑니다.

마지막 업데이트: