(string.xml 적용하여 다국어 사용하는 방법 링크)
보통 다국어 협업을 할때 필요한것은 두가지 이다. 하나는 번역해야하는 입장에서의 여러 국가의 번역을 할수있는 엑셀파일 , 하나는 키값이 있고 해당 키값에 있는 여러 국가의 번역본 엑셀파일 , 이 두 가지 조건만 맞으면 일단 다국어 정리가 한결 수월 해 진다. 그리고 협업을 위해서는 다국어 입력하는 파일(번역자전용) 1, 이 내용을 코드로 변환시키는 소스변환기능이 있어야한다. 별도의 엑셀파일을 만들어서 엑셀 함수를 이용하여 각 칸에 맞게 해당 언어의 내용을 입력하면 Android , IOS 다국어 string 파일에 맞게 변환되는 기능이 있어야한다. 이게 없으면 단순 복사 붙여넣기 작업만 하는데 많은 시간을 소요해야한다. 단순하게 정리된 엑셀 파일을 직접 복사 붙여넣기로 작업을 한적이 있는데 1개 국가당 키 값이 800개가 넘는데 국가가 15개 가 되는 작업을 한 적이 있는데, 하나씩 하다가 몇개 꼬이는 경우도있고 빼먹는 경우도 발생하게 된다. 이렇게 되면 어디까지 했는지도 꼬여버리면서 처음부터 다시 복붙 노가다를 해야하는 경험도 한 경험이 있다. 그래서 찾아보던 중 구글드라이브에 엑셀파일을 공유하여 관리자의 번역을 수월하게하고, 구글 스크립트를 사용하여 간단한 코드로 string 코드로 변환까지 시켜줄 수 있다는 방법을 알아냈다. 겨우 알아냈고, 스크립트를 잘 모르지만 프로세스는 JAVA 와 비슷할거라 생각하고, 이것 저것 시도해본 결과 안드로이드와 IOS 의 다국어 string 변환 가능을 구현했다.
나와같이 한참을 헤매고 있을지도 모르는 사람들을 위해 현재 작동이 잘되고 현재도 사용하고 있는 구글 스크립트 소스를 공유 하겠다.
소스를 먼저 공유하고 아래의 소스의 결과물은 어떤것이며, 사용시 주의사항, 적용방법 을 나중에 정리해서 올리겠다.
< 구글 스크립트 코드>
function onOpen(){
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [
{
name : "안드로이드 리소스 생성", // (2) 파일안에서 작동시킬 이벤트 폴더이름
functionName : "createAndroidStringResource"
}
];
var entriesIOS = [
{
name : "아이폰 리소스 생성",
functionName : "createIOSStringResource"
}
];
sheet.addMenu("AndroidString", entries);
sheet.addMenu("IOSString", entriesIOS);
}
var PARENT_FOLDER = DriveApp.getFolderById("1SdMDZhq_oNvCTn_Lf4_Ze9wUIAsgzi8z");
var SHEET_NAME = "AppStrings";
var FILE_NAME = "strings.xml";
var LANGUAGE_SET = [
[1, "values-en"], // 영어
[2, "values-ko"], // 한국어
[3, "values-km"], // 크메르어(캄보디아)
[4, "values-ne"], // 네팔어
[5, "values-tl"], // 타갈로그어(필리핀)
[6, "values-in"], // 인도네시아어
[7, "values-vi"], // 베트남어
[8, "values-bn"], // 방글라데시어
[9, "values-zh"], // 중국어
[10, "values-uz"], // 우즈베키스탄어
[11, "values-si"], // 스리랑카어
[12, "values-th"], // 태국어
[13, "values-mm"], // 미얀마어
[14, "values-ru"], // 러시아어
[15, "values-pk"], // 파키스탄어
];
function createAndroidStringResource() {
var sheet = SpreadsheetApp.getActiveSheet();
if( sheet != null && sheet.getName() == SHEET_NAME ) {
var sheetData = sheet.getSheetValues(1, 1, sheet.getLastRow(), sheet.getLastRow());
writeAndroidResourceFile(sheetData);
return true;
} else {
SpreadsheetApp.getUi().alert("알림", "파일 생성에 실패하였습니다.", SpreadsheetApp.getUi().ButtonSet.OK);
return false;
}
}
function writeAndroidResourceFile(sheetData) {
var folderName = "Android";
var now = new Date();
folderName = folderName+ " [" + now + "]";
var AFolder = PARENT_FOLDER.createFolder(folderName);
for(var i=0; i<LANGUAGE_SET.length; i++) {
var folder = LANGUAGE_SET[i][1];
var xml = AndroidconvertDataToXmlString(sheetData, LANGUAGE_SET[i][0]);
if( xml != null ) {
AFolder.createFolder(folder).createFile(FILE_NAME, xml);
}
}
}
function AndroidconvertDataToXmlString(sheetData, columnIndex) {
var result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<resources>\r\n";
for(var i=1; i<sheetData.length; i++) {
var row = sheetData[i];
var key = row[0];
var value = row[columnIndex];
if( value == null || value == '' ) {
value = "";
}
if(value.indexOf('&')) {
value = value.replace("&","&"); // 안드로이드 허용가능 문자로 변경
}
var pos = value.indexOf('%');
var pos2 = value.indexOf('@');
var resultpos = pos2 - pos;
var count = 0;
if(resultpos>=1){
count = (value.match(/@/g) || []).length;
value = value.replace(/@/g,"s"); // 안드로이드 유동값과 섞어사용하는 Strings.xml 사용가능하도록 값 변환하기
}
// /대상의값/ , g : 발생할 모든 패턴에 대한 전역 검색 , i: 대소문자 구분안함
// ex)var A 라는 문자열 안에 대소문자 구분없이 a 와 같은 문자의 갯수는 몇개인가
// ex_)count = value.match(/a/gi)||[]).length; 이렇게 하면 count 에 갯수가 뽑힌다.
// value.replace(/@/gi,"s"); 이렇게 해야 replaceAll 의 효과가 난다.
// 안드로이드 변수와 섞어사용하는 Strings.xml 사용가능하도록 값 변환하기 (@% 는 아이폰 개발자
//편의를 위해 번역본은 저렇게 받고, 안드로이드에서 변환 처리를 넣어주었음.
if( key == null || key == '' ) {
result += "\r\n";
} else if( key.indexOf("<!--") > -1 ) {
result += " " + key + "\r\n";
} else {
if(count>=2){
// 위의 유동값을 적용할때 1개 이상의 유동값이 포함되면 클래스에서 적용시 앞,뒤 구분을 지으라는 에러가 생긴다.
//(단순하게 첫번째 쓰고 두번째 쓰고의 문제가 아니다)
// 그래서 이때 아래와 같이 formatted를 넣어주면 위의 문제는 해결된다.
result += " " + "<string name=\"" + key +" formatted=\"false\""+"\">"+"\""+ value + "\"" +"</string>\r\n";
}else{
result += " " + "<string name=\"" + key + "\">"+"\""+ value + "\"" +"</string>\r\n";
}
}
}
result += "</resources>"
return result;
}
var FILE_NAMEIOS = "Localizable.strings";
var LANGUAGE_SETIOS = [
[1, "ko.lproj"], // 한국어
[2, "en.lproj"], // 영어
[3, "km.lproj"], // 크메르어(캄보디아)
[4, "ne-NP.lproj"], // 네팔어
[5, "fil-PH.lproj"], // 타갈로그어(필리핀)
[6, "id-ID.lproj"], // 인도네시아어
[7, "vi.lproj"], // 베트남어
[8, "bn-BD.lproj"], // 방글라데시어
[9, "zh-Hans.lproj"], // 중국어
[10, "uz-UZ.lproj"], // 우즈베키스탄어
[11, "si-LK.lproj"], // 스리랑카어
[12, "th-TH.lproj"], // 태국어
[13, "my-MM.lproj"], // 미얀마어
[14, "ru.lproj"], // 러시아어
[15, "ur-PK.lproj"], // 파키스탄어
];
function createIOSStringResource() {
var sheet = SpreadsheetApp.getActiveSheet();
if( sheet != null && sheet.getName() == SHEET_NAME ) {
var sheetData = sheet.getSheetValues(1, 1, sheet.getLastRow(), sheet.getLastRow());
writeIOSResourceFile(sheetData);
return true;
} else {
SpreadsheetApp.getUi().alert("알림", "파일 생성에 실패하였습니다.", SpreadsheetApp.getUi().ButtonSet.OK);
return false;
}
}
function writeIOSResourceFile(sheetData) {
var folderName = "IOS";
var now = new Date();
folderName = folderName+ " [" + now + "]";
var IFolder = PARENT_FOLDER.createFolder(folderName);
for(var i=0; i<LANGUAGE_SETIOS.length; i++) {
var folder = LANGUAGE_SETIOS[i][1];
var strings = IOSconvertDataToStrings(sheetData, LANGUAGE_SETIOS[i][0]);
if( strings != null ) {
IFolder.createFolder(folder).createFile(FILE_NAMEIOS, strings);
}
}
}
function IOSconvertDataToStrings(sheetData, columnIndex) {
var result = "";
for(var i=1; i<sheetData.length; i++) {
var row = sheetData[i];
var key = row[0];
var value = row[columnIndex];
if( value == null || value == '' ) {
value = "";
}
if(value.indexOf("\"")) {
}
if( key == null || key == '' ) {
result += "\r\n";
}
}
return result;
}
구현하는것에 중점을 둔것이라, 커스터마이징이 많이 필요함.
- 끝 -
'Android Study' 카테고리의 다른 글
Android notification 헤드업 Tip(channel 사용 버전만) (0) | 2019.11.12 |
---|---|
안드로이드의 디자인 적용 원리 (0) | 2019.05.09 |
안드로이드 string.xml 을 사용 할 때 동적값 적용하기 (0) | 2019.04.25 |
안드로이드 string.xml 기본 사용법 및 다국어 적용방법 (0) | 2019.04.25 |
안드로이드 앱 삭제는 확실하게!! (0) | 2019.04.02 |