Xcode .xcstrings 카탈로그

Lingo.dev CLI를 사용한 Xcode .xcstrings 파일의 AI 번역

Xcode .xcstrings 카탈로그란 무엇인가요?

Xcode .xcstrings 카탈로그는 Xcode 15에서 도입된 Apple의 현대적인 현지화 형식입니다. 이는 모든 현지화를 단일 JSON 파일에 저장하며, 복수형, 기기 변형 및 번역 메타데이터를 지원합니다.

예시:

{
  "sourceLanguage" : "en",
  "strings" : {
    "item_count" : {
      "comment" : "Number of items displayed in the list - supports pluralization",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "variations" : {
            "plural" : {
              "one" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "1 item"
                }
              },
              "other" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "%d items"
                }
              },
              "zero" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "No items"
                }
              }
            }
          }
        }
      }
    },
    "welcome_message" : {
      "comment" : "Welcome message shown on the app's home screen",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Hello, world!"
          }
        }
      }
    }
  }
}

Lingo.dev CLI란 무엇인가요?

Lingo.dev CLI는 AI를 사용하여 앱과 콘텐츠를 번역하기 위한 무료 오픈소스 CLI입니다. 기존 파이프라인과 통합하면서 전통적인 번역 관리 소프트웨어를 대체하도록 설계되었습니다.

자세한 내용은 개요를 참조하세요.

이 가이드에 대하여

이 가이드는 Lingo.dev CLI를 사용하여 Xcode .xcstrings 파일을 번역하는 방법을 설명합니다.

다음 내용을 배우게 됩니다:

  • 처음부터 프로젝트 생성하기
  • 번역 파이프라인 구성하기
  • AI로 번역 생성하기

사전 요구사항

Lingo.dev CLI를 사용하려면 Node.js v18+ 이상이 설치되어 있어야 합니다:

❯ node -v
v22.17.0

1단계. 프로젝트 설정

프로젝트 디렉토리에 i18n.json 파일을 생성하세요:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

이 파일은 번역 파이프라인의 동작을 정의하며, 어떤 언어 간에 번역할지와 파일 시스템에서 현지화 가능한 콘텐츠가 어디에 있는지를 포함합니다.

사용 가능한 속성에 대해 자세히 알아보려면 i18n.json을 참조하세요.

2단계. 소스 로케일 구성

소스 로케일은 콘텐츠가 원래 작성된 언어와 지역입니다. 소스 로케일을 구성하려면 i18n.json 파일에서 locale.source 속성을 설정하세요:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

소스 로케일은 BCP 47 언어 태그로 제공되어야 합니다.

Lingo.dev CLI가 지원하는 로케일 코드의 전체 목록은 지원되는 로케일 코드를 참조하세요.

3단계. 대상 로케일 구성

대상 로케일은 콘텐츠를 번역하고자 하는 언어와 지역입니다. 대상 로케일을 구성하려면 i18n.json 파일에서 locale.targets 속성을 설정하세요:

{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {}
}

4단계. 소스 콘텐츠 생성

아직 생성하지 않았다면, 번역할 콘텐츠가 포함된 .xcstrings 파일을 생성하세요.

참고: 번역 과정에서 소스 콘텐츠 파일은 번역된 콘텐츠(소스 콘텐츠 외에도)를 포함하도록 덮어쓰여집니다.

5단계. 버킷 생성

  1. i18n.json 파일에서 buckets 객체에 "xcode-xcstrings" 객체를 추가하세요:

    {
      "$schema": "https://lingo.dev/schema/i18n.json",
      "version": "1.10",
      "locale": {
        "source": "en",
        "targets": ["es"]
      },
      "buckets": {
        "xcode-xcstrings": {}
      }
    }
    
  2. "xcode-xcstrings" 객체에서 하나 이상의 include 패턴 배열을 정의하세요:

    {
      "$schema": "https://lingo.dev/schema/i18n.json",
      "version": "1.10",
      "locale": {
        "source": "en",
        "targets": ["es"]
      },
      "buckets": {
        "xcode-xcstrings": {
          "include": ["./example.xcstrings"]
        }
      }
    }
    

    이러한 패턴은 번역할 파일을 정의하며 다음과 같이 할 수 있습니다:

    • 특정 파일 경로 지정(예: "some/dir/file.xcstrings")
    • 와일드카드 자리 표시자로 별표 사용(예: "some/dir/*.xcstrings")

    재귀적 글로브 패턴(예: **/*.xcstrings)은 지원되지 않습니다.

6단계. LLM 구성하기

Lingo.dev CLI는 대규모 언어 모델(LLM)을 사용하여 AI로 콘텐츠를 번역합니다. 이러한 모델 중 하나를 사용하려면 지원되는 제공업체의 API 키가 필요합니다.

가능한 빨리 시작하려면 Lingo.dev Engine을 사용하는 것이 좋습니다 — 매월 10,000 토큰의 무료 사용량을 제공하는 자체 호스팅 플랫폼입니다:

  1. Lingo.dev 계정에 가입하세요.

  2. 다음 명령어를 실행하세요:

    npx lingo.dev@latest login
    

    이렇게 하면 기본 브라우저가 열리고 인증을 요청합니다.

  3. 안내에 따라 진행하세요.

7단계. 번역 생성하기

i18n.json 파일이 포함된 디렉토리에서 다음 명령어를 실행하세요:

npx lingo.dev@latest run

이 명령어는 다음을 수행합니다:

  1. i18n.json 파일을 읽습니다.
  2. 번역이 필요한 파일을 찾습니다.
  3. 파일에서 번역 가능한 콘텐츠를 추출합니다.
  4. 구성된 LLM을 사용하여 추출된 콘텐츠를 번역합니다.
  5. 번역된 콘텐츠를 파일 시스템에 다시 작성합니다.

번역이 처음 생성될 때 i18n.lock 파일이 생성됩니다. 이 파일은 어떤 콘텐츠가 번역되었는지 추적하여 이후 실행 시 불필요한 재번역을 방지합니다.

예시

example.xcstrings (번역 전)

{
  "sourceLanguage" : "en",
  "strings" : {
    "welcome_message" : {
      "comment" : "Welcome message shown on the app's home screen",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Hello, world!"
          }
        }
      }
    },
    "item_count" : {
      "comment" : "Number of items - supports pluralization",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "variations" : {
            "plural" : {
              "zero" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "No items"
                }
              },
              "one" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "1 item"
                }
              },
              "other" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "%d items"
                }
              }
            }
          }
        }
      }
    }
  }
}

example.xcstrings (번역 후)

{
  "sourceLanguage" : "en",
  "strings" : {
    "welcome_message" : {
      "comment" : "Welcome message shown on the app's home screen",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "Hello, world!"
          }
        },
        "es" : {
          "stringUnit" : {
            "state" : "translated",
            "value" : "¡Hola, mundo!"
          }
        }
      }
    },
    "item_count" : {
      "comment" : "Number of items - supports pluralization",
      "extractionState" : "manual",
      "localizations" : {
        "en" : {
          "variations" : {
            "plural" : {
              "zero" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "No items"
                }
              },
              "one" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "1 item"
                }
              },
              "other" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "%d items"
                }
              }
            }
          }
        },
        "es" : {
          "variations" : {
            "plural" : {
              "zero" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "Sin elementos"
                }
              },
              "one" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "1 elemento"
                }
              },
              "other" : {
                "stringUnit" : {
                  "state" : "translated",
                  "value" : "%d elementos"
                }
              }
            }
          }
        }
      }
    }
  }
}

i18n.json

{
  "version": "1.10",
  "locale": {
    "source": "en",
    "targets": ["es"]
  },
  "buckets": {
    "xcode-xcstrings": {
      "include": ["./example.xcstrings"]
    }
  },
  "$schema": "https://lingo.dev/schema/i18n.json"
}

i18n.lock

version: 1
checksums:
  d3330df55a54ce785f378e7388282a96:
    welcome_message: 57da71b2c89eaddcbca81b3c3766deed
    item_count/zero: 955c31a42e9ff663a49e69e944c8c537
    item_count/one: 154c8eed472b867c8d5af66d162abd2c
    item_count/other: ecb3f18dc6a5e7b3e1d9afe7ef62cf07
  614e9d20c639fed18ee30b9f9637c83d:
    item_count/one: d25ee41f72a2ea94ebc6debc85b9e573
    item_count/other: ecb3f18dc6a5e7b3e1d9afe7ef62cf07
    item_count/zero: 955c31a42e9ff663a49e69e944c8c537
    welcome_message: 0468579ef2fbc83c9d520c2f2f1c5059