일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- vi
- Android
- php
- jenkins
- CODEIGNITER
- Firebase
- jenkins 업데이트
- 가상머신
- 리눅스
- 가상컴퓨터
- 우분투 젠킨스 업데이트
- 버추얼박스
- 아파치
- Phone Selector
- virtualbox
- 웹서버
- 우분투
- vim
- 인증번호 문자
- 우분투 아파치 ssl
- SMS Retreiver API
- 우분투 젠킨스
- 전화번호 가져오기
- 아파치 https 적용
- ubuntu
- 젠킨스
- 안드로이드
- vimrc
- jenkins war
- phpMyAdmin
- Today
- Total
철스토리
[Android, iOS] 번역 시트 관리하기 (구글 스프레드시트) 본문
개발을 하면서 개발적인 부분 말고 힘들었던 부분들 중에 하나는 "다국어 관리" 였다.
다국어를 처리하는 기존의 방식은 이랬다.
1. 기획자가 기획문서를 작성하면서 문구를 정한다.
2. 안드로이드, 아이폰 개발자 중 먼저 개발하는 부분에 대해 키값과 문구를 구글시트에 등록한다.
3. 기획자가 문구를 정리해서 번역가에게 전송한다. 총 5가지의 언어를 지원한다. - 한국어, 영어, 중국어, 대만어, 일본어 (번역을 외주로 했음)
4. 기획자가 번역이 도착하면 도착한 순서대로 시트에 업데이트 한다.
5. 개발자가 업데이트 된 번역에 대해 개발자가 키값을 찾아 적용한다.
이러한 과정으로 번역을 적용하는건 그렇게 어렵거나 많이 불편하진 않았다.
하지만 문제는 문구가 수정될 때 발생했다.
구글시트에 모든 문구에 대한 번역이 들어가 있다보니 1000라인(1000개의 단어 또는 문장) 이상 되는데
이중에서 문구가 중간중간 수정이 되고, 번역이 수정되면
그것을 찾아서 개발자가 또 적용해야하고....
이런게 반복되면 기획자가 복사붙여넣기 할 때도 실수할 수 있고, 개발자가 복사붙여넣기 할 때도 실수할 수 있는 상황이 발생했다.
그래서 여러가지를 찾아보게되었다.
그중에서 찾게된 방법을 정리해놓고 앞으로 사용해 보려고 한다. 참고한 사이트는 아래의 사이트들이다.
https://tech.wanted.co.kr/android/2018/03/30/android-strings-1.html
https://github.com/aurelhubert/android-ios-drive-export
구글드라이브에 구글시트 생성
시트 작성하기
아래처럼 구글시트에 글을 작성한다.
여기서 중요한 포인트
- Description : 주석부분
- en, fr, ko 등 : values-en, values-ko 등으로 파일이 생성됨
- %1$s, %2$s, %3$d, %4$d : 이건 안드로이에서 필요한 내용인데 아이폰은 자동으로 %@로 매핑되게끔 소스를 짰음.
- 언어추가 : 언어가 추가될때는 Tawiwanese (zh-rtw) 오른쪽으로 계속해서 언어를 추가하면 됨
메뉴 구성하기
도구 - 스크립트 편집기 를 눌러서 스크립트를 작성한다. 아래 그림 참조.
코드.gs
var appName = "AppName";
function onOpen() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [
{
name : "리소스 생성",
functionName : "exportResources"
}
];
sheet.addMenu(appName, entries);
};
// Export resources function
function exportResources() {
// Folders
var appFolder = createOrGetFolder(appName);
var androidFolder = createOrGetFolder("Android", appFolder);
var iOSFolder = createOrGetFolder("iOS", appFolder);
// Data
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getDataRange().getValues();
var i = 2;
while (data[1][i] != null && data[1][i].length > 0) {
//var results = data[1][i].match(/\((\w\w)\)/g);
var results = data[1][i].match(/\(([a-zA-Z-]*)\)/g);
if (results.length > 0) {
var language = results[0].replace("(", "").replace(")", "");
createAndroidResources(language, data, androidFolder, i);
createIOSResources(language, data, iOSFolder, i);
}
i++;
}
}
// Create an XML file for Android
// language: Current language
// data: Spreadsheet data array
// folder: Folder where create the file
// column: Index of the column
function createAndroidResources(language, data, folder, column) {
var folderName = "values";
if (language != "en") {
folderName += "-" + language;
}
var languageFolder = createOrGetFolder(folderName, folder);
var content = "<resources>";
content += "\n\n";
content += "\t<!-- App name -->";
content += '\n\t<string name="app_name">' + appName + '</string>';
for (var i = 3; i < data.length; i++) {
if (data[i][1].length == 0) {
continue;
}
if (data[i][0].length > 0) {
content += "\n\n\t<!-- " + data[i][0] + " -->";
}
var formatted = "";
if (data[i][2].indexOf("%s") > -1 || data[i][2].indexOf("%d") > -1) {
formatted = ' formatted="false"';
}
var escapedContent = data[i][column]
.replace(new RegExp("\'", 'g'), "\\'")
.replace(new RegExp("\\.\\.\\.", 'g'), "…");
content += '\n\t<string name="' + data[i][1] + '"' + formatted + '>' + escapedContent + '</string>';
}
content += "\n\n</resources>";
var file = createOrGetFile("strings.xml", languageFolder);
file.setContent(content);
}
// Create a localizable file for iOS
// language: Current language
// data: Spreadsheet data array
// folder: Folder where create the file
// column: Index of the column
function createIOSResources(language, data, folder, column) {
var content = "// App";
content += "\n";
content += '"APP_NAME" = "' + appName + '";';
for (var i = 3; i < data.length; i++) {
if (data[i][1].length == 0) {
continue;
}
if (data[i][0].length > 0) {
content += "\n\n// " + data[i][0] + "";
}
var value = data[i][column];
value = value.replace(/%[0-9]\$[sdf]/g, "%@");
//value = value.replace(/%s/g, "%@");
value = value.replace(/"/g, '\\"');
value = value.replace(/(?:\r\n|\r|\n)/g, '\\n');
content += '\n"' + data[i][1] + '" = "' + value + '";';
}
var fileName = "Localizable_" + language.toUpperCase() + ".strings";
var file = createOrGetFile(fileName, folder);
file.setContent(content);
}
////////////
// HELPER //
////////////
// Check folder
function createOrGetFolder(name, folder) {
var folders;
if (folder == undefined) {
folders = DriveApp.getFoldersByName(name)
} else {
folders = folder.getFoldersByName(name)
}
var mainFolder;
if (folders.hasNext()) {
mainFolder = folders.next();
} else {
if (folder == undefined) {
mainFolder = DriveApp.createFolder(name);
} else {
mainFolder = folder.createFolder(name);
}
}
return mainFolder;
}
// Check file
function createOrGetFile(name, folder) {
var files;
if (folder == undefined) {
files = DriveApp.getFilesByName(name)
} else {
files = folder.getFilesByName(name)
}
var file;
if (files.hasNext()) {
file = files.next();
} else {
if (folder == undefined) {
file = DriveApp.createFile(name, "");
} else {
file = folder.createFile(name, "");
}
}
return file;
}
위의 소스를 저장한 후에 구글시트로 돌아가면 "AppName"이라는 메뉴가 생성이 되었다.
번역 생성하기
AppName - 리소스 생성을 누른다.
그러면 완료 될 때까지 진행중 메시지가 뜬다.
생성된 파일 확인하기
Android
iOS
끝!!!!!!!!!!!!!!!!
'안드로이드 > 프로그래밍' 카테고리의 다른 글
안드로이드 Phone Selector, SMS Retriever API (0) | 2019.06.03 |
---|---|
웹뷰에서 카메라 촬영 및 갤러리에서 사진 불러오기 기능 (0) | 2018.11.23 |
안드로이드 파일 및 폴더(하위폴더까지) 삭제하는 방법 (0) | 2016.12.28 |
인증서 지문 검색 SHA1 (0) | 2016.10.26 |
TabLayout (0) | 2016.10.16 |