스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
String Catalog 소개
Xcode 15에서 모든 문자열을 한 곳에서 관리하며 앱을 쉽게 현지화하는 방법을 알아보세요. String Catalog를 사용해 프로젝트에서 문자열을 추출, 편집, 내보내기, 빌드하는 방법을 보여드립니다. 원할 때면 언제든 마이그레이션할 파일을 선택해 기존 프로젝트에서 String Catalog를 채택하는 방법도 알려드립니다.
챕터
- 0:00 - Introduction
- 1:29 - Demo
- 4:13 - Extract
- 13:19 - Edit
- 22:48 - Export
- 27:52 - Build
- 28:44 - Migrate
- 31:03 - Wrap-up
리소스
관련 비디오
WWDC23
-
다운로드
♪ ♪
안녕하세요 WWDC에 오신 것을 환영합니다 저는 마리나입니다 잠시 뒤에 맷도 함께할 겁니다 Apple 현지화 팀에서 오늘 여러분에게 String Catalog를 소개합니다 Apple은 접근성과 포용성에 큰 가치를 둡니다 앱 현지화는 전 세계의 더 많은 사람에게 콘텐츠를 전달하는 방법이죠 현재 Apple의 운영 체제는 40개 이상의 언어로 출시되며 그 수도 계속 늘고 있습니다 모든 사람이 모국어로 제품을 사용할 수 있도록 말이죠 현지화 팀은 Xcode 도구를 통해 현지화를 가능한 한 쉽게 만들고자 합니다 오늘 발표를 통해 콘텐츠 현지화 관리의 개선점과 새 워크플로를 제시하려 합니다 이전까지는 앱을 현지화하려면 strings와 stringsdict 파일을 관리해야 했죠 이를 위해 모든 문자열을 코드와 수동으로 동기화하느라 종종 현지화 콘텐츠를 빠트리는 일이 생겨 현지화되지 않은 문자열이 그대로 노출되기도 했을 겁니다 수년간 이런 과정을 겪어야 했지만 오늘 여러분에게 Xcode 15의 String Catalog를 소개합니다 시간이 지나면 이 새 형식이 Xcode에서 strings와 stringsdict 파일을 대체할 겁니다 String Catalog로 모든 문자열을 한 곳에서 쉽게 관리할 수 있고 출시 전 모든 콘텐츠가 현지화되었는지 확인할 수 있죠 함께 살펴봅시다 이 코드에서는 SwiftUI 컨트롤을 사용해 뷰를 빌드하고 콘텐츠를 채우고 있습니다 이게 바로 String Catalog입니다 방금 Swift 코드에서 봤던 모든 문자열이 자동으로 Xcode로 추출되었습니다 제가 일일이 추가할 필요가 없었죠 브라질에 있는 제 친구가 이 앱을 사용할 수 있도록 포르투갈어로 번역했습니다
최근에 뒷마당을 방문한 새의 수를 알려주는 이 뷰를 함께 살펴보죠 여기에서 뒷마당을 방문한 새의 숫자를 보여줍니다 이 숫자를 나타낼 변수를 추가해 보겠습니다 프리뷰에는 이렇게 표시됩니다 이제 새의 숫자가 표시되네요 프로젝트를 빌드하고 Catalog로 돌아갑니다
참 쉽죠? 새 문자열이 추가되었습니다 번역 진행률도 내려갔네요 String Catalog에는 강력한 편집 기능도 탑재되어 복잡한 작업도 쉽게 수행할 수 있습니다 예시를 보죠 이 문자열에는 tap이라는 단어가 있군요 다중 플랫폼 앱이라 Mac 기기에 맞는 적절한 용어를 사용해야 합니다 우선 영어 문자열로 돌아갑니다 Tap to learn more! 문자열을 찾습니다 여기 있군요 우클릭합니다 Vary by device를 선택하고 Mac을 선택해 텍스트를 적절히 수정합니다
다 됐습니다 다시 뷰로 돌아가서 실행 대상을 Mac으로 변경하면
프리뷰 기능으로 확인해 볼 수 있습니다 참 쉽죠?
String Catalog로 많은 걸 할 수 있습니다 좀 더 자세히 살펴보며 사용법을 알아봅시다 문자열을 추출하는 곳부터 String Catalog와 상호 작용하는 Xcode의 기본 편집기도 살펴보고 현지화 내보내기 프로세스를 검토할 겁니다 그런 다음 String Catalog를 빌드하는 방법과 기존 프로젝트에 이를 도입하는 방법을 살펴보겠습니다 먼저, 맷과 함께 현지화 가능한 문자열과 그 출처를 알아보시죠 고마워요, 마리나 현지화 가능한 문자열은 런타임에 사용자에게 표시되는 텍스트 문자열이므로 앱이 지원하는 모든 언어로 번역이 필요합니다 현지화 가능한 문자열은 네 가지로 구성됩니다 Key는 문자열의 고유 식별자로 보통 문자열 그 자체에 해당합니다 이 값은 런타임에 표시할 적절한 값을 조회하는 데 사용됩니다 Value는 필요에 따라 명시적으로 지정할 수 있지만 그렇지 않으면 기본 현지화 키로 돌아갑니다 Xcode 14.3에는 프로젝트 에디터로 프로젝트 기본 현지화를 변경하는 기능이 도입되었습니다 소스 코드의 문자열이 영어가 아닐 때 유용하죠 다음으로 문자열 주석은 사용자 인터페이스에서 문자열의 위치와 사용에 관한 맥락을 번역가에게 제공합니다 번역가가 모호한 부분을 번역하는 걸 도우려면 문자열에 주석을 다는 게 좋습니다 끝으로, 현지화 가능한 문자열은 번역이 저장될 파일에 해당하는 문자열 테이블에 속합니다 기본값으로 코드의 문자열은 Localizable 테이블에 배치되죠 다른 방법으로 정리하고 싶다면 사용자화도 가능합니다 문자열 테이블을 더 자세히 살펴봅시다 .strings 파일을 사용하는 기존 애플리케이션은 단일 문자열 테이블에는 지원하는 언어의 lproj 폴더 내에 .strings 및 .stringsdict 파일이 포함되어 있습니다 여기에 나타나는 모든 파일이 Localizable 문자열 테이블을 구성합니다 반면 String Catalog는 전체 문자열 테이블 단일 파일로 구성합니다 테이블 내에 현지화 가능한 문자열의 번역은 물론 추가 메타데이터도 포함되죠 문자열을 여러 문자열 테이블로 구성하고 싶다면 다중 String Catalog를 생성할 수 있습니다 각 Catalog에는 그 테이블에 속하는 문자열 키와 앱이 지원하는 모든 언어의 번역이 포함됩니다 키는 포함된 테이블 내에서는 고유해야 하지만 다른 테이블 내에서도 고유해야 할 필요는 없습니다 예를 들어 Welcome to WWDC! 문자열은 두 파일에 다 존재하는데요 앱 내 다른 맥락에서도 표시될 수 있기 때문이죠 마리나가 앞서 언급했듯이 Xcode 15은 자동으로 String Catalog를 채우고 최선을 다해 프로젝트 내의 현지화 가능한 문자열과 동기화하죠 그럼 Xcode는 현지화 가능한 문자열을 어디서 찾을까요? 현지화 가능한 문자열의 위치는 다양합니다 Xcode는 소스 코드와 Interface Builder 파일 Info.plist에서도 문자열을 찾아 String Catalog에 추가합니다 앱 현지화 경험이 많다면 많은 부분이 익숙할 겁니다 몇 가지만 자세히 살펴봅시다 SwiftUI부터 보죠 SwiftUI는 현지화를 원활하게 해 줍니다 뷰에서 문자열 리터럴을 지정할 때마다 해당 스트링을 자동으로 현지화 가능한 것으로 간주하죠 현지화가 가능하다고 간주된 문자열은 Localizable.xcstrings라는 이름의 String Catalog로 추출됩니다 LocalizedStringKey를 허용하는 모든 매개변수에 작동하게 됩니다 SwiftUI 문자열은 텍스트 뷰로 주석을 지정하고 테이블 이름을 사용자 지정하거나 문자열을 조회할 수 있습니다 클라이언트가 현지화하려는 문자열들을 사용하는 사용자 뷰를 정의할 수도 있습니다 여기선 LocalizedStringResource를 문자열 유형으로 사용합니다 Xcode는 호출 사이트에서 문자열 리터럴이 LocalizedStringResource의 인스턴스화에 사용됨을 확인하면 현지화 가능한 문자열임을 인식합니다 LocalizedStringResource는 현지화 가능한 문자열의 표현과 전달에 권장되는 유형입니다 문자열 리터럴을 사용한 초기화를 지원하면서도 주석과 테이블 이름은 물론 문자열 키와 다른 기본값을 제공할 수도 있습니다 이제 Swift 코드를 전반적으로 살펴봅시다 모델 코드를 함께 보시죠 일부는 나중에 설명하겠습니다 String과 AttributedString에 localized: 이니셜라이저를 사용해 실행 중에 사용자에게 표시될 문자열을 지정하고 있습니다 또한 Foundation을 임포트한 모든 곳에서 LocalizedStringResource를 직접 사용할 수도 있습니다 String Catalog는 Swift 컴파일러의 강력한 기술로 현지화 가능한 Swift 문자열을 추출합니다 따라서 빌드 설정에서 Use Compiler to Extract Swift Strings를 활성화해야 합니다 String Catalog로 Swift 코드 이외의 문자열도 추출할 수 있습니다 NSLocalizedString을 사용하는 Objective-C 코드 예제입니다 NSLocalizedString 매크로 내의 모든 문자열 리터럴은 자동으로 현지화 가능한 것으로 간주되며 이를 감지할 수 있는 유사한 매크로를 직접 정의할 수도 있습니다 동일한 개념을 C 코드에서도 CFCopyLocalizedString을 통해 사용할 수 있습니다 C 또는 Objective-C에서 직접 만든 현지화 문자열 매크로를 쓰려면 Localized String Macro Names 빌드 설정을 사용합니다 소스 코드에서의 사용법을 살펴봤으니 이제 Interface Builder에서 현지화 가능한 문자열을 살펴보죠 지정된 문자열은 자동으로 현지화 가능하다고 간주됩니다 인스펙터를 사용해 이런 문자열에 주석을 지정하여 해당 스트링이 표시될 위치 콘텍스트를 번역가에게 제공합니다 String Catalog를 Storyboard 또는 xib와 페어링하면 Interface Builder에서 현지화 가능한 모든 문자열이 Catalog에 표시됩니다 소스 코드와 마찬가지로 Xcode는 프로젝트가 빌드될 때마다 Catalog를 업데이트합니다 이 프로세스는 Info.plist 파일에서도 유사하게 작동합니다 InfoPlist.xcstrings 파일을 프로젝트에 추가하고 원하는 대상에 추가하기만 하면 됩니다 빌드할 때마다 Xcode는 현지화 가능한 Info.plist 키 세트를 Catalog에 추가하며 필요에 따라 수동으로 더 추가할 수 있습니다 마지막으로, 올해 Xcode는 앱 단축어로 쓰일 만한 구문을 현지화하는 방식을 크게 개선하였습니다 자세한 내용은 올해 발표에 포함된 '앱 단축어로 주목받기'를 참고하세요 Xcode에서 현지화 가능한 문자열을 찾을 수 있는 곳들을 살펴보았으니 이제 이런 문자열이 String Catalog로 어떻게 이동하는지 좀 더 알아봅시다 빌드할 때마다 Xcode는 현재 스키마와 플랫폼에서 현지화 가능한 문자열을 찾습니다 소스 코드 문자열은 현지화 가능한 문자열의 소스 역할을 하는 반면 String Catalog의 소스 문자열은 동기화가 유지됩니다 코드에서 새 문자열이 발견되면 Xcode는 String Catalog에 문자열을 추가합니다 이 시점에서 문자열은 번역할 준비가 완료됩니다 앞서 설명했듯이 현지화 가능한 문자열의 코드에 기본 소스값이 지정될 수 있죠 그런 경우에 Catalog는 코드의 새 값으로 업데이트됩니다 Xcode는 코드에서 문자열을 제거해도 검색할 수 있습니다 문자열이 아직 번역되지 않았다면 Xcode가 문자열을 제거해 주지만 문자열에 번역을 제공한 다음에 문자열을 지웠다면 Xcode는 이를 그대로 두고 STALE이라고 표시합니다 이는 해당 문자열을 이제 코드에서 찾을 수 없음을 나타냅니다 언제든 필요 없다고 판단된다면 문자열과 번역을 지울 수 있습니다 또는 인스펙터를 사용하여 Xcode를 설정해 특정 문자열을 수동으로 관리할 수도 있습니다 수동 관리 문자열은 빌드 후 현지화를 동기화할 때 Xcode가 업데이트하거나 제거하지 않습니다 코드에서 동적으로 구성된 코드나 데이터베이스에서 유래한 문자열에 유용한 기능입니다 모든 문자열을 String Catalog로 추출했으니 이제 String Catalog Editor로 번역을 쉽게 관리하는 방법을 알아봅시다 String Catalog는 앱을 현지화할 때 상태와 번역 진행 상황을 추적하기 위한 수준 높은 기능을 지원합니다 코드에서 문자열을 더 이상 찾을 수 없을 때 STALE로 표시한다고 알려드렸는데요 그 외에도 알아두셔야 할 현지화 상태가 세 가지 더 있습니다 NEW는 문자열이 아직 선택한 언어로 번역되지 않았음을 나타냅니다 코드에 새 문자열을 추가하면 이 상태가 표시됩니다 NEEDS REVIEW는 값이 변경될 수도 있는 문자열이므로 번역가의 주의가 필요하다는 의미입니다 현재 값을 사용하고 싶다면 콘텍스트 메뉴에서 Mark as Reviewed를 선택합니다 검토할 문자열을 표시할 수도 있습니다 이 기능은 번역 오류에 대한 버그 리포트를 받을 때 유용합니다 마지막으로, 선택한 언어로 번역이 완료된 문자열에는 녹색 체크 표시가 나타납니다 추가 작업이 필요하지 않음을 의미하죠 개발자의 또 다른 현지화 고충은 바로 복수화입니다 예를 들어, 아까 마리나가 Backyard Birds에 추가한 문자열은 최근에 왔다 간 새의 수를 표시합니다 영어에서는 문법에 따라 대상의 단수, 복수에 맞게 문자열을 변경해야 합니다 하지만 우크라이나어 같은 언어는 고려해야 할 경우의 수가 훨씬 많습니다 이 문제를 해결하려면 대상의 숫자에 따라 문자열을 변경할 방법이 필요합니다 기존에는 많은 언어에서 이 문제를 해결하기 위해 stringsdict 파일이 필요했습니다 이런 plist 형식은 제대로 사용하기가 어렵고 문자열 복수화 같은 간단한 작업에도 상당한 어려움을 초래할 수 있습니다 이제 String Catalog Editor에서 문자열 변형 워크플로를 기본 지원합니다 문자열에서 콘텍스트 메뉴를 열면 문자열 변형 옵션이 표시됩니다 현지화 기본값에서 문자열 변형을 지정하면 번역도 자동으로 변경됩니다 두 개의 변수로 복수 변형을 사용해야 하는 더 복잡한 예시를 살펴봅시다 런타임에서 몇 가지 다른 시나리오가 발생할 겁니다 하나의 뒷마당에 한 마리의 새가 있거나 여러 새가 하나의 뒷마당에 있거나 여러 새가 여러 뒷마당에 있거나 여러 뒷마당에 한 마리의 새만 있을 수도 있습니다 각각의 경우를 문법에 맞게 쓰려면 숫자 주변의 문자열을 조금씩 다르게 번역해야 합니다 String Catalog Editor로 이 작업도 쉽게 할 수 있습니다 이때 치환이 필요합니다 여기서는 문자열의 두 인수를 모두 복수형으로 변형했습니다 앞에 @ 기호가 붙은 치환에 복수형 딕셔너리와 그 값을 저장합니다 본 예시에서는 새의 숫자 서식을 지정하는 bird 치환과 뒷마당의 숫자 서식을 지정하는 yards 치환을 사용합니다 런타임 시 여기에 표시된 최상위 문자열이 사용되며 참조된 각 치환에서 적절한 복수형으로 치환됩니다 이 예시에서는 어떤 경우의 문자열이든 생성하여 각 치환에 대응하는 복수형을 효과적으로 치환할 수 있습니다
치환은 일반적으로 문자열에 전달된 인수에 대응하며 종종 문자열 보간을 사용합니다 인스펙터에서 Xcode는 숫자에 사용할 인수의 위치와 전달되는 유형의 C 스타일 서식 지정자에 대한 정보를 표시합니다 여기 표시된 yards 치환은 소스 코드에서 사용된 두 번째 문자열 보간이므로 인수 2에 해당합니다 backyards.count의 값을 그 다음에 사용해 치환 내에서 어떤 복수형을 사용할지 결정하게 됩니다 이런 식으로 String Catalog는 간단한 UI로 변형 문자열을 다루며 복잡한 사례에도 사용할 수 있습니다 이제 다시 마리나와 함께 기술을 실제로 적용해 봅시다 고마워요, 맷 Backyard Birds로 돌아와 String Catalog Editor로 원하는 문자열을 쉽게 찾아봅시다 필터를 사용해 learn이 포함된 모든 문자열을 찾거나 상태로 정렬해 가장 중요한 상태를 맨 위에 표시할 수 있습니다 맷이 지적했듯이 코드에는 없지만 앱에 표시되는 문자열이 있을 수 있습니다 예를 들어, 앱 구독자에게는 클라우드에서 특별한 종류의 새가 앱에 표시되기도 하죠 이 경우, 더하기 버튼으로 수동 문자열을 정의하고 키를 지정한 뒤 주석을 답니다
수동 관리 문자열은 Xcode가 업데이트 또는 제거하지 않습니다 Xcode가 코드에서 문자열 추출을 시작하게 하려면 인스펙터를 열고
문자열을 자동으로 관리하도록 설정합니다 Xcode로 현지화 진행 상황도 쉽게 추적 가능합니다 각 문자열 옆에는 배지가 표시됩니다 번역 상태를 나타내는 배지죠 코드에서 문자열을 추가하거나 수동으로 추가하면 NEW가 표시됩니다 아직 번역되지 않았다는 의미죠 소스 문자열이 변경되면 검토가 필요하다고 표시됩니다 앞서 이 문자열을 영어로 변경했으므로 기존 번역이 검토가 필요하다고 표시된 거죠 변경이 필요 없다면 문자열을 우클릭하여 Mark as reviewed를 선택합니다 제가 포르투갈어를 하니까 번역 업데이트가 필요하다는 게 눈에 보이네요
변경하고 나면 이쪽 사이드바에서 현지화 비율이 올라갑니다 한 언어의 현지화가 완료되고 나면 이곳 사이드바에 녹색 체크 표시가 나타납니다 Xcode에서 현지화 진행 상황을 확인하는 첫 번째 방법이며 이를 통해 App Store에 앱을 제출하기 전에 현지화가 완료되었는지 확인할 수 있습니다 우크라이나어로도 앱을 현지화하고 싶다면 String Catalog Editor에서 더하기 버튼을 눌러 목록에서 새 언어를 고르면 됩니다
아직 번역되지 않은 우크라이나어 Catalog가 생성되었습니다
이건 아까 추가한 문자열입니다 복수형으로 변형해야 할 것 같군요 영어로 돌아가 봅시다
문자열을 우클릭하고 Vary by plural을 선택합니다 영어에서는 문법에 따라 복수와 단수를 구분해야 하니 수정해 봅시다
포르투갈어도 복수형 규칙이 영어와 같습니다 반면, 우크라이나어는 다른 복수형 규칙이 추가되어 있습니다 우크라이나어 번역가가 처리 방법을 잘 알고 있을 겁니다
뷰로 돌아가 보죠 각각의 뒷마당에 새의 수를 나타내는 다른 레이블을 추가하려고 합니다 한번 추가해 봅시다
빌드하고
Catalog로 돌아갑니다
Catalog에도 추가되었습니다 문자열을 복수형으로 변형하고 싶은데 여러 인수가 포함되어 있군요 이번에는 문자열을 우클릭해 Vary by plural을 선택하고 변형하고 싶은 인수를 선택합니다 둘 다 해 보죠
이제 런타임 시 복수형이 되도록 치환을 설정해야 합니다 인수와 일치해야 하는 단어를 옮겨 봅시다 birds를 각각 birds 치환으로 넣고 backyards를 각각 yards 치환에 넣어 줍니다
가독성을 위해 변수가 해당하는 인수를 알기 쉽게 치환의 이름을 바꿔 보겠습니다
이제 더 이해하기 쉽네요 이제 맷이 우크라이나어로 번역하기 위해 문자열을 내보내는 방법을 보여줄 겁니다 고마워요, 마리나 이미 보셨다시피 Xcode를 사용하면 String Catalog에서 직접 번역하고 편집할 수 있지만 종종 앱의 문자열을 Xcode 외부에서 번역가와 협력해 현지화해야 할 때가 있습니다 이를 위해 Xcode는 Export Localizations 옵션을 제공합니다 이 기능으로 언어마다 Localization Catalog를 생성하여 번역을 위해 내보낼 수 있습니다 Xcode 10에서 처음으로 도입된 Localization Catalog는 프로젝트나 워크스페이스 내의 현지화 가능한 모든 콘텐츠를 담는 패키지 형식입니다 본 영상에서는 현지화 가능한 문자열과 그 번역이 포함된 내부 XLIFF 파일 위주로 살펴보죠 XLIFF는 현지화를 저장하고 전송하는 업계 표준 형식입니다 XLIFF 파일로 직접 작업하는 경우 String Catalog를 사용한 프로젝트의 변형 문자열이 어떻게 표시되는지 궁금할 겁니다 .stringsdict 파일에서 정의된 XLIFF 파일의 복수 문자열 표현 예시입니다 여기에서 번역 단위 식별자는 stringsdict plist 형식의 경로 역할을 합니다 반면 String Catalog에서 변형 문자열을 가져오는 경우 이렇게 표시됩니다 문자열 키와 구분 기호 시퀀스 그리고 점으로 구분된 설정 문자열이 포함됩니다 이 설정 문자열은 단순히 복수 지정자나 장치 지정자일 수도 있고 다중 조건을 지정하거나 치환 내부의 복수형 경로를 지정할 수도 있습니다 이런 키는 자동화 도구도 쉽게 읽을 수 있으며 사람도 한눈에 쉽게 읽고 이해할 수 있도록 설계되었습니다 번역 도구는 XLIFF의 번역 단위를 원하는 변형 구조로 대체하여 사전에 변형이 지정되지 않았던 문자열도 변형할 수 있습니다 변형이 지정되지 않은 문자열 예시를 보죠 포르투갈어로 더 짧은 문자열을 제시하려고 합니다 Apple Watch에 쓰일 문자열이죠 XLIFF에서 이 번역 단위를 device.applewatch와 device.other 변형으로 대체하면 다음에 가져오기를 할 때 이 언어로 표시할 변형 구조를 바꿀 수 있습니다
현지화를 내보낼 때 기본 설정으로 XLIFF가 String Catalog 형식을 사용하게 하려면 Localization Prefers String Catalogs를 Yes로 설정합니다 번역가가 번역된 Localization Catalog를 제출하면 이를 다시 프로젝트로 가져올 수 있습니다 출처가 String Catalog인 문자열이라면 가져온 파일에 지정된 번역이 해당 String Catalog에 자동으로 추가됩니다 Backyard Birds에서 직접 해 봅시다 포르투갈어 앱을 위한 번역 작업은 이미 잘 마쳤지만 우크라이나어 번역가가 콘텐츠를 현지화할 수 있도록 Localization Catalog를 준비해야 합니다 먼저 Product 메뉴를 클릭해 Export Localizations를 선택하고 내보낼 언어를 선택합니다 이번 예시에서는 우크라이나어를 선택하고 내보내기를 클릭합니다
번역가가 번역본을 제출하면 다시 앱으로 가져올 수 있습니다 와, 왔네요 번역문이 준비되었으니 앱으로 다시 돌아갑시다 Product 메뉴를 클릭하고 이번에는 Import Localizations를 선택해 우크라이나어 Localization Catalog를 고릅니다
어떻게 되었는지 살펴봅시다
완벽하네요 우크라이나어 번역이 완료됐어요 앱이 두 언어로 전부 현지화되었습니다 포르투갈어도 살펴봅시다 Scheme Selector를 누르고 Edit Scheme을 선택합니다 Options에서 앱의 시스템 언어를 포르투갈어로 변경합니다
이제 앱을 실행합니다
멋지네요 작업한 문자열이 잘 나옵니다
이제 번역이 완료됐으니 맷에게 넘겨드리죠 앱의 콘텐츠가 전부 번역되었으니 빌드 단계를 간략히 살펴봅시다 String Catalog는 Xcode 프로젝트 간 상호 작용을 위해 맞춤 설계되었습니다 내부 구성은 JSON 파일이므로 소스 제어에서도 쉽게 변경할 수 있어야 합니다 빌드 시에는 .strings 및 .stringsdict 파일로 컴파일되죠 운영 체제에서 수년 동안 지원해 왔던 파일 형식이기 때문에 최소 배포 대상을 업데이트할 필요 없이 String Catalog를 바로 사용할 수 있습니다 게다가 최종 빌드에 코드에서 추출한 소스 문자열이 포함되지 않는다는 점도 알고 있어야 합니다 덕분에 런타임에 표시되는 문자열에 영향을 주지 않고도 디스크 공간이 절약되죠 이런 장점들을 모두 살펴봤으니 마리나가 기존 프로젝트에서 String Catalog를 시작하는 방법을 보여 줄 겁니다 Xcode를 쓰면 기존 프로젝트에서 String Catalog로 쉽게 마이그레이션할 수 있습니다 원할 때면 언제든 가능하죠 마음먹으면 언제든 마이그레이션할 문자열 파일과 대상을 선택할 수 있습니다 작년에 현지화한 기존 앱 FoodTruck입니다 strings와 stringsdict 파일이 있네요 String Catalog는 레거시 형식과 공존할 수 있어 현지화 가능한 테이블을 언제든 마이그레이션할 수 있습니다 바로 해 봅시다 파일을 우클릭하여 Migrate to String Catalog를 선택합니다 Xcode에는 마이그레이션 가능한 모든 파일을 나열하는 마이그레이션 어시스턴트가 내장되어 있습니다 FoodTruck의 현지화 가능한 테이블이 표시되네요 지금 바로 마이그레이션해 봅시다
잘됐네요! 마이그레이션 후에는 Xcode가 문자열 추출을 위해 프로젝트를 빌드합니다 빌드 후 Catalog를 살펴봅시다 strings 파일의 문자열과 stringsdict 파일의 복수형까지 전부 마이그레이션된 걸 확인할 수 있습니다 아랍어 번역은 완료되었지만 프랑스어 번역의 진행률은 100%가 아니네요 String Catalog는 현지화되지 않은 문자열을 이렇듯 쉽게 찾아 줍니다 FoodTruck에는 FoodTruckKit라는 Swift 패키지도 있습니다 현지화하기 전 파일이죠 String Catalog를 사용하면 새 패키지나 프로젝트의 현지화를 정말 쉽게 시작할 수 있습니다 우선 패키지 매니패스트에 기본 현지화를 추가합니다 그리고 Swift Tools의 버전이 5.9가 맞는지 확인합니다
기본 테이블 이름이 Localizable인 새 String Catalog를 패키지에 추가합니다
프로젝트를 빌드하고 나면 패키지의 문자열이 모두 나타납니다 새 프로젝트와 패키지의 현지화도 이렇게 쉽게 할 수 있습니다 String Catalog는 Xcode 현지화의 새 Foundation이며 프로젝트의 번역 관리 프로세스를 간소화합니다 지금 바로 시작해 기존 문자열을 마이그레이션하세요 앱 현지화 경험이 없는 분들도 사용법을 쉽게 배우실 수 있을 겁니다 '오늘 함께해 주셔서 감사합니다' 시청해 주셔서 감사하고요 새 관찰 즐겁게 하세요 ♪ ♪
-
-
4:30 - Localizable string
String(localized: "Welcome to WWDC!")
-
4:42 - Localizable string with default value
String(localized: "WWDC_NOTIFICATION_TITLE", defaultValue: "Welcome to WWDC!")
-
5:05 - Localizable string with comment
String(localized: "Welcome to WWDC!", comment: "Notification banner title")
-
5:22 - Localizable string with table and comment
String(localized: "Welcome to WWDC!", table: "WWDCNotifications", comment: "Notification banner title")
-
7:36 - Localizable strings in SwiftUI
// Localizable strings in SwiftUI struct ContentView: View { var body: some View { VStack { Label("Thanks for shopping with us!", systemImage: "bag") .font(.title) HStack { Button("Clear Cart") { } Button("Checkout") { } } } } }
-
8:01 - Localizable strings in SwiftUI with LocalizedStringKey
// Localizable strings in SwiftUI struct ContentView: View { var body: some View { VStack { // init(_ titleKey: LocalizedStringKey, systemImage name: String) Label("Thanks for shopping with us!", systemImage: "bag") .font(.title) HStack { Button("Clear Cart") { } Button("Checkout") { } } } } }
-
8:08 - Localizable strings in SwiftUI text view
// Localizable strings in SwiftUI struct ContentView: View { var body: some View { VStack { Label { Text("Thanks for shopping with us!", comment: "Label above checkout button") } icon: { Image(systemName: "bag") } .font(.title) HStack { Button("Clear Cart") { } Button("Checkout") { } } } } }
-
8:16 - Localizable strings in SwiftUI custom view
// Localizable strings in SwiftUI struct CardView: View { let title: LocalizedStringResource let subtitle: LocalizedStringResource var body: some View { ZStack { RoundedRectangle(cornerRadius: 10.0) VStack { Text(title) Text(subtitle) } .padding() } } } CardView(title: "Recent Purchases", subtitle: "Items you’ve ordered in the past week.")
-
9:03 - Localizable strings in Swift displayed at runtime
// Localizable strings in Swift import Foundation func stringsToPresent() -> (String, AttributedString) { let deferredString = LocalizedStringResource("Title") … return ( String(localized: deferredString), AttributedString(localized: "**Attributed** _Subtitle_") ) }
-
9:44 - Localizable strings in Objective-C
// Localizable strings in Objective-C #import <Foundation/Foundation.h> - (NSString *)stringForDisplay { return NSLocalizedString(@"Recent Purchases", @"Button Title"); } #define MyLocalizedString(key, comment) \ [myBundle localizedStringForKey:key value:nil table:nil]
-
10:04 - Localizable strings in C
// Localizable strings in C #include <CoreFoundation/CoreFoundation.h> CFStringRef stringForDisplay(void) { return CFCopyLocalizedString(CFSTR("Recent Purchases"), CFSTR("Button Title")); } #define MyLocalizedString(key, comment) \ CFBundleCopyLocalizedString(myBundle, key, NULL, NULL)
-
11:23 - App Shortcut phrases
// App Shortcut phrases struct FoodTruckShortcuts: AppShortcutsProvider { static var appShortcuts: [AppShortcut] { AppShortcut( intent: ShowTopDonutsIntent(), phrases: [ "\(.applicationName) Trends for \(\.$timeframe)", "Show trending donuts for \(\.$timeframe) in \(.applicationName)", "Give me trends for \(\.$timeframe) in \(.applicationName)" ] ) } }
-
23:53 - Stringsdict in XLIFF
// Stringsdict in XLIFF <trans-unit id="/%lld Recent Visitors:dict/NSStringLocalizedFormatKey:dict/:string"> <source>%#@recentVisitors@</source> <target>%#@recentVisitors@</target> </trans-unit> <trans-unit id="/%lld Recent Visitors:dict/recentVisitors:dict/one:dict/:string"> <source>%lld Recent Visitor</source> <target>%lld Visitante Recente</target> </trans-unit> <trans-unit id="/%lld Recent Visitors:dict/recentVisitors:dict/other:dict/:string"> <source>%lld Recent Visitors</source> <target>%lld Visitantes Recentes</target> </trans-unit>
-
24:08 - String Catalog in XLIFF
// String Catalog in XLIFF <trans-unit id="%lld Recent Visitors|==|plural.one"> <source>%lld Recent Visitor</source> <target>%lld Visitante Recente</target> </trans-unit> <trans-unit id="%lld Recent Visitors|==|plural.other"> <source>%lld Recent Visitors</source> <target>%lld Visitantes Recentes</target> </trans-unit>
-
24:58 - String Catalog variations in XLIFF
// Overriding variation in XLIFF <trans-unit id="Bird Food Shop|==|device.applewatch"> <source>Bird Food Shop</source> <target>Loja de Comida</target> </trans-unit> <trans-unit id="Bird Food Shop|==|device.other"> <source>Bird Food Shop</source> <target>Loja de Comida de Passarinho</target> </trans-unit>
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.